summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2014-05-18 20:08:38 -0700
committerGarrett D'Amore <garrett@damore.org>2014-07-11 20:35:28 -0700
commit2d08521bd15501c8370ba2153b9cca4f094979d0 (patch)
treecd843bc37fe795bc7bbdd04b5b13b0310a2d6be1
parent961519c5bffd5ec670890fc3596d6c4ff1cefea0 (diff)
downloadillumos-joyent-2d08521bd15501c8370ba2153b9cca4f094979d0.tar.gz
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Approved by: Dan McDonald <danmcd@omniti.com>
-rw-r--r--usr/src/cmd/localedef/messages.c3
-rw-r--r--usr/src/cmd/localedef/monetary.c3
-rw-r--r--usr/src/cmd/localedef/numeric.c3
-rw-r--r--usr/src/cmd/localedef/time.c3
-rw-r--r--usr/src/cmd/mdb/common/kmdb/mapfile_skel14
-rw-r--r--usr/src/cmd/mdb/common/libstand/ctype.c135
-rw-r--r--usr/src/cmd/sgs/rtld/common/external.c50
-rw-r--r--usr/src/head/Makefile5
-rw-r--r--usr/src/head/ctype.h44
-rw-r--r--usr/src/head/iso/ctype_c99.h86
-rw-r--r--usr/src/head/iso/ctype_iso.h125
-rw-r--r--usr/src/head/iso/stdlib_iso.h12
-rw-r--r--usr/src/head/iso/wctype_c99.h79
-rw-r--r--usr/src/head/iso/wctype_iso.h16
-rw-r--r--usr/src/head/langinfo.h19
-rw-r--r--usr/src/head/locale.h49
-rw-r--r--usr/src/head/monetary.h18
-rw-r--r--usr/src/head/string.h45
-rw-r--r--usr/src/head/strings.h17
-rw-r--r--usr/src/head/time.h18
-rw-r--r--usr/src/head/wchar.h34
-rw-r--r--usr/src/head/wctype.h88
-rw-r--r--usr/src/head/xlocale.h113
-rw-r--r--usr/src/lib/libc/amd64/Makefile13
-rw-r--r--usr/src/lib/libc/i386/Makefile.com13
-rw-r--r--usr/src/lib/libc/port/i18n/isdigit.c148
-rw-r--r--usr/src/lib/libc/port/i18n/wscasecmp.c55
-rw-r--r--usr/src/lib/libc/port/locale/_ctype.h3
-rw-r--r--usr/src/lib/libc/port/locale/big5.c42
-rw-r--r--usr/src/lib/libc/port/locale/btowc.c13
-rw-r--r--usr/src/lib/libc/port/locale/collate.c218
-rw-r--r--usr/src/lib/libc/port/locale/collate.h35
-rw-r--r--usr/src/lib/libc/port/locale/collcmp.c11
-rw-r--r--usr/src/lib/libc/port/locale/euc.c187
-rw-r--r--usr/src/lib/libc/port/locale/fgetwc.c48
-rw-r--r--usr/src/lib/libc/port/locale/fnmatch.c58
-rw-r--r--usr/src/lib/libc/port/locale/fputwc.c3
-rw-r--r--usr/src/lib/libc/port/locale/gb18030.c45
-rw-r--r--usr/src/lib/libc/port/locale/gb2312.c43
-rw-r--r--usr/src/lib/libc/port/locale/gbk.c42
-rw-r--r--usr/src/lib/libc/port/locale/isdigit.c91
-rw-r--r--usr/src/lib/libc/port/locale/iswctype.c229
-rw-r--r--usr/src/lib/libc/port/locale/lctype.h66
-rw-r--r--usr/src/lib/libc/port/locale/ldpart.c23
-rw-r--r--usr/src/lib/libc/port/locale/ldpart.h3
-rw-r--r--usr/src/lib/libc/port/locale/lmessages.c56
-rw-r--r--usr/src/lib/libc/port/locale/lmessages.h6
-rw-r--r--usr/src/lib/libc/port/locale/lmonetary.c153
-rw-r--r--usr/src/lib/libc/port/locale/lmonetary.h5
-rw-r--r--usr/src/lib/libc/port/locale/lnumeric.c69
-rw-r--r--usr/src/lib/libc/port/locale/lnumeric.h6
-rw-r--r--usr/src/lib/libc/port/locale/localeconv.c47
-rw-r--r--usr/src/lib/libc/port/locale/localeimpl.c537
-rw-r--r--usr/src/lib/libc/port/locale/localeimpl.h107
-rw-r--r--usr/src/lib/libc/port/locale/mblen.c18
-rw-r--r--usr/src/lib/libc/port/locale/mblocal.h47
-rw-r--r--usr/src/lib/libc/port/locale/mbrlen.c14
-rw-r--r--usr/src/lib/libc/port/locale/mbrtowc.c16
-rw-r--r--usr/src/lib/libc/port/locale/mbsinit.c48
-rw-r--r--usr/src/lib/libc/port/locale/mbsnrtowcs.c23
-rw-r--r--usr/src/lib/libc/port/locale/mbsrtowcs.c18
-rw-r--r--usr/src/lib/libc/port/locale/mbstowcs.c15
-rw-r--r--usr/src/lib/libc/port/locale/mbtowc.c18
-rw-r--r--usr/src/lib/libc/port/locale/mskanji.c43
-rw-r--r--usr/src/lib/libc/port/locale/nextwctype.c32
-rw-r--r--usr/src/lib/libc/port/locale/nl_langinfo.c101
-rw-r--r--usr/src/lib/libc/port/locale/none.c72
-rw-r--r--usr/src/lib/libc/port/locale/regcomp.c15
-rw-r--r--usr/src/lib/libc/port/locale/rune.c73
-rw-r--r--usr/src/lib/libc/port/locale/runetype.c7
-rw-r--r--usr/src/lib/libc/port/locale/runetype.h6
-rw-r--r--usr/src/lib/libc/port/locale/setlocale.c336
-rw-r--r--usr/src/lib/libc/port/locale/setlocale.h4
-rw-r--r--usr/src/lib/libc/port/locale/setrunelocale.c274
-rw-r--r--usr/src/lib/libc/port/locale/strcasecmp.c (renamed from usr/src/lib/libc/port/i18n/strcasecmp.c)21
-rw-r--r--usr/src/lib/libc/port/locale/strcasestr.c (renamed from usr/src/lib/libc/port/i18n/strcasestr.c)14
-rw-r--r--usr/src/lib/libc/port/locale/strcoll.c25
-rw-r--r--usr/src/lib/libc/port/locale/strfmon.c199
-rw-r--r--usr/src/lib/libc/port/locale/strftime.c45
-rw-r--r--usr/src/lib/libc/port/locale/strncasecmp.c (renamed from usr/src/lib/libc/port/i18n/strncasecmp.c)20
-rw-r--r--usr/src/lib/libc/port/locale/strptime.c67
-rw-r--r--usr/src/lib/libc/port/locale/strxfrm.c17
-rw-r--r--usr/src/lib/libc/port/locale/table.c9
-rw-r--r--usr/src/lib/libc/port/locale/timelocal.c48
-rw-r--r--usr/src/lib/libc/port/locale/timelocal.h5
-rw-r--r--usr/src/lib/libc/port/locale/tolower.c22
-rw-r--r--usr/src/lib/libc/port/locale/towlower.c47
-rw-r--r--usr/src/lib/libc/port/locale/utf8.c34
-rw-r--r--usr/src/lib/libc/port/locale/wcrtomb.c16
-rw-r--r--usr/src/lib/libc/port/locale/wcscasecmp.c (renamed from usr/src/lib/libc/port/i18n/wsncasecmp.c)47
-rw-r--r--usr/src/lib/libc/port/locale/wcscoll.c36
-rw-r--r--usr/src/lib/libc/port/locale/wcsnrtombs.c26
-rw-r--r--usr/src/lib/libc/port/locale/wcsrtombs.c16
-rw-r--r--usr/src/lib/libc/port/locale/wcstombs.c14
-rw-r--r--usr/src/lib/libc/port/locale/wcswidth.c13
-rw-r--r--usr/src/lib/libc/port/locale/wcsxfrm.c17
-rw-r--r--usr/src/lib/libc/port/locale/wctob.c13
-rw-r--r--usr/src/lib/libc/port/locale/wctomb.c17
-rw-r--r--usr/src/lib/libc/port/locale/wctrans.c29
-rw-r--r--usr/src/lib/libc/port/locale/wctype.c17
-rw-r--r--usr/src/lib/libc/port/locale/wcwidth.c15
-rw-r--r--usr/src/lib/libc/port/mapfile-vers84
-rw-r--r--usr/src/lib/libc/sparc/Makefile.com13
-rw-r--r--usr/src/lib/libc/sparcv9/Makefile.com13
-rw-r--r--usr/src/lib/libumem/common/stub_stand.c16
-rw-r--r--usr/src/man/man3c/Makefile191
-rw-r--r--usr/src/man/man3c/btowc.3c50
-rw-r--r--usr/src/man/man3c/ctype.3c172
-rw-r--r--usr/src/man/man3c/fgetwc.3c159
-rw-r--r--usr/src/man/man3c/getwc.3c45
-rw-r--r--usr/src/man/man3c/getwchar.3c25
-rw-r--r--usr/src/man/man3c/iswalpha.3c164
-rw-r--r--usr/src/man/man3c/iswctype.3c124
-rw-r--r--usr/src/man/man3c/mblen.3c61
-rw-r--r--usr/src/man/man3c/mbrlen.3c77
-rw-r--r--usr/src/man/man3c/mbrtowc.3c242
-rw-r--r--usr/src/man/man3c/mbsinit.3c48
-rw-r--r--usr/src/man/man3c/mbsrtowcs.3c101
-rw-r--r--usr/src/man/man3c/mbtowc.3c55
-rw-r--r--usr/src/man/man3c/newlocale.3c191
-rw-r--r--usr/src/man/man3c/nl_langinfo.3c47
-rw-r--r--usr/src/man/man3c/strcoll.3c46
-rw-r--r--usr/src/man/man3c/strfmon.3c164
-rw-r--r--usr/src/man/man3c/strftime.3c78
-rw-r--r--usr/src/man/man3c/string.3c122
-rw-r--r--usr/src/man/man3c/strptime.3c47
-rw-r--r--usr/src/man/man3c/strxfrm.3c51
-rw-r--r--usr/src/man/man3c/tolower.3c27
-rw-r--r--usr/src/man/man3c/toupper.3c28
-rw-r--r--usr/src/man/man3c/towlower.3c75
-rw-r--r--usr/src/man/man3c/towupper.3c75
-rw-r--r--usr/src/man/man3c/uselocale.3c95
-rw-r--r--usr/src/man/man3c/wcrtomb.3c62
-rw-r--r--usr/src/man/man3c/wcscoll.3c65
-rw-r--r--usr/src/man/man3c/wcsrtombs.3c68
-rw-r--r--usr/src/man/man3c/wcswidth.3c26
-rw-r--r--usr/src/man/man3c/wctob.3c47
-rw-r--r--usr/src/man/man3c/wctomb.3c40
-rw-r--r--usr/src/man/man3c/wctrans.3c140
-rw-r--r--usr/src/man/man3c/wctype.3c54
-rw-r--r--usr/src/man/man3c/wcwidth.3c39
-rw-r--r--usr/src/man/man3head/Makefile8
-rw-r--r--usr/src/man/man3head/locale.h.3head72
-rw-r--r--usr/src/man/man3head/xlocale.h.3head59
-rw-r--r--usr/src/man/man3lib/libc.3lib145
-rw-r--r--usr/src/man/man5/environ.525
-rw-r--r--usr/src/pkg/manifests/system-header.mf7
-rw-r--r--usr/src/pkg/manifests/system-library.man3c.inc80
-rw-r--r--usr/src/pkg/manifests/system-test-libctest.mf37
-rw-r--r--usr/src/test/Makefile2
-rw-r--r--usr/src/test/libc-tests/Makefile21
-rw-r--r--usr/src/test/libc-tests/cmd/Makefile38
-rw-r--r--usr/src/test/libc-tests/cmd/libctest.ksh63
-rw-r--r--usr/src/test/libc-tests/doc/Makefile36
-rw-r--r--usr/src/test/libc-tests/doc/README70
-rw-r--r--usr/src/test/libc-tests/runfiles/Makefile40
-rw-r--r--usr/src/test/libc-tests/runfiles/default.run25
-rw-r--r--usr/src/test/libc-tests/tests/Makefile19
-rw-r--r--usr/src/test/libc-tests/tests/newlocale/Makefile57
-rw-r--r--usr/src/test/libc-tests/tests/newlocale/newlocale_test.c195
-rw-r--r--usr/src/uts/common/sys/feature_tests.h47
161 files changed, 6408 insertions, 3248 deletions
diff --git a/usr/src/cmd/localedef/messages.c b/usr/src/cmd/localedef/messages.c
index 18f8ef0bd7..3c7cc0201c 100644
--- a/usr/src/cmd/localedef/messages.c
+++ b/usr/src/cmd/localedef/messages.c
@@ -10,6 +10,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
@@ -28,7 +29,7 @@
#include "parser.tab.h"
#include "lmessages.h"
-static struct lc_messages_T msgs;
+static struct lc_messages msgs;
void
init_messages(void)
diff --git a/usr/src/cmd/localedef/monetary.c b/usr/src/cmd/localedef/monetary.c
index c6f4780c2a..126ae6bf3f 100644
--- a/usr/src/cmd/localedef/monetary.c
+++ b/usr/src/cmd/localedef/monetary.c
@@ -10,6 +10,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
@@ -27,7 +28,7 @@
#include "parser.tab.h"
#include "lmonetary.h"
-static struct lc_monetary_T mon;
+static struct lc_monetary mon;
void
init_monetary(void)
diff --git a/usr/src/cmd/localedef/numeric.c b/usr/src/cmd/localedef/numeric.c
index 2a0892bb63..b6935bd21c 100644
--- a/usr/src/cmd/localedef/numeric.c
+++ b/usr/src/cmd/localedef/numeric.c
@@ -10,6 +10,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
@@ -27,7 +28,7 @@
#include "parser.tab.h"
#include "lnumeric.h"
-static struct lc_numeric_T numeric;
+static struct lc_numeric numeric;
void
init_numeric(void)
diff --git a/usr/src/cmd/localedef/time.c b/usr/src/cmd/localedef/time.c
index d4cb9d65cd..8347f0ecb7 100644
--- a/usr/src/cmd/localedef/time.c
+++ b/usr/src/cmd/localedef/time.c
@@ -10,6 +10,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
@@ -27,7 +28,7 @@
#include "parser.tab.h"
#include "timelocal.h"
-struct lc_time_T tm;
+struct lc_time tm;
void
init_time(void)
diff --git a/usr/src/cmd/mdb/common/kmdb/mapfile_skel b/usr/src/cmd/mdb/common/kmdb/mapfile_skel
index bbf6767bf3..2d55703c7d 100644
--- a/usr/src/cmd/mdb/common/kmdb/mapfile_skel
+++ b/usr/src/cmd/mdb/common/kmdb/mapfile_skel
@@ -21,6 +21,7 @@
/* BEGIN PROLOGUE */
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
/*
@@ -44,10 +45,19 @@ SYMBOL_SCOPE {
* Secret additions to the module API
*/
- /* Implementation detail of the ctype macros */
- __ctype; /* variable */
/* There should be only one - ours */
errno; /* variable */
+ isprint;
+ isalnum;
+ isalpha;
+ isgraph;
+ iscntrl;
+ isdigit;
+ isxdigit;
+ isupper;
+ islower;
+ ispunct;
+ isspace;
mdb_tgt_aread;
mdb_dis_create;
diff --git a/usr/src/cmd/mdb/common/libstand/ctype.c b/usr/src/cmd/mdb/common/libstand/ctype.c
index 4037d0f0db..49200afac0 100644
--- a/usr/src/cmd/mdb/common/libstand/ctype.c
+++ b/usr/src/cmd/mdb/common/libstand/ctype.c
@@ -1,50 +1,97 @@
/*
- * CDDL HEADER START
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
*
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * ASCII versions of ctype character classification functions. This avoids
+ * pulling in the entire locale framework that is in libc.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <ctype.h>
-
-unsigned char __ctype[129] =
-{
- 0, /* EOF */
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _S|_C, _S|_C, _S|_C, _S|_C, _S|_C, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _S|_B, _P, _P, _P, _P, _P, _P, _P,
- _P, _P, _P, _P, _P, _P, _P, _P,
- _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X,
- _N|_X, _N|_X, _P, _P, _P, _P, _P, _P,
- _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _P, _P, _P, _P, _P,
- _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _P, _P, _P, _P, _C,
-};
+int
+isdigit(int c)
+{
+ return ((c >= '0' && c <= '9') ? 1 : 0);
+}
+
+int
+isupper(int c)
+{
+ return ((c >= 'A' && c <= 'Z') ? 1 : 0);
+}
+
+
+int
+islower(int c)
+{
+ return ((c >= 'a' && c <= 'z') ? 1 : 0);
+}
+
+int
+isspace(int c)
+{
+ return (((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') ||
+ (c == '\v') || (c == '\f')) ? 1 : 0);
+}
+
+int
+isxdigit(int c)
+{
+ return ((isdigit(c) || (c >= 'A' && c <= 'F') ||
+ (c >= 'a' && c <= 'f')) ? 1 : 0);
+}
+
+int
+isalpha(int c)
+{
+ return ((isupper(c) || islower(c)) ? 1 : 0);
+}
+
+
+int
+isalnum(int c)
+{
+ return ((isalpha(c) || isdigit(c)) ? 1 : 0);
+}
+
+int
+ispunct(int c)
+{
+ return (((c >= '!') && (c <= '/')) ||
+ ((c >= ':') && (c <= '@')) ||
+ ((c >= '[') && (c <= '`')) ||
+ ((c >= '{') && (c <= '~')));
+}
+
+int
+iscntrl(int c)
+{
+ return ((c < 0x20) || (c == 0x7f));
+}
+
+int
+isprint(int c)
+{
+ /*
+ * Almost the inverse of iscntrl, but be careful that c > 0x7f
+ * returns false for everything.
+ */
+ return ((c >= ' ') && (c <= '~'));
+}
+
+int
+isgraph(int c)
+{
+ /* isgraph is like is print, but excludes <space> */
+ return ((c >= '!') && (c <= '~'));
+}
diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c
index 82766906b5..e2ebd89145 100644
--- a/usr/src/cmd/sgs/rtld/common/external.c
+++ b/usr/src/cmd/sgs/rtld/common/external.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
/*
@@ -668,3 +669,52 @@ write(int fd, const void *buf, size_t size)
extern ssize_t __write(int, const void *, size_t);
return (__write(fd, buf, size));
}
+
+/*
+ * ASCII versions of ctype character classification functions. This avoids
+ * pulling in the entire locale framework that is in libc.
+ */
+
+int
+isdigit(int c)
+{
+ return ((c >= '0' && c <= '9') ? 1 : 0);
+}
+
+int
+isupper(int c)
+{
+ return ((c >= 'A' && c <= 'Z') ? 1 : 0);
+}
+
+int
+islower(int c)
+{
+ return ((c >= 'a' && c <= 'z') ? 1 : 0);
+}
+
+int
+isspace(int c)
+{
+ return (((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') ||
+ (c == '\v') || (c == '\f')) ? 1 : 0);
+}
+
+int
+isxdigit(int c)
+{
+ return ((isdigit(c) || (c >= 'A' && c <= 'F') ||
+ (c >= 'a' && c <= 'f')) ? 1 : 0);
+}
+
+int
+isalpha(int c)
+{
+ return ((isupper(c) || islower(c)) ? 1 : 0);
+}
+
+int
+isalnum(int c)
+{
+ return ((isalpha(c) || isdigit(c)) ? 1 : 0);
+}
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index 21a5dfc1f9..72e2224afc 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -22,6 +22,8 @@
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Garrett D'Amore <garrett@damore.org>
+#
# head/Makefile
#
# include global definitions
@@ -203,12 +205,12 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
wctype.h \
widec.h \
wordexp.h \
+ xlocale.h \
xti.h \
xti_inet.h \
zone.h
ISOHDRS = \
- ctype_c99.h \
ctype_iso.h \
limits_iso.h \
locale_iso.h \
@@ -225,7 +227,6 @@ ISOHDRS = \
time_iso.h \
wchar_c99.h \
wchar_iso.h \
- wctype_c99.h \
wctype_iso.h
ARPAHDRS = \
diff --git a/usr/src/head/ctype.h b/usr/src/head/ctype.h
index 04d2e4552f..23b1e67c7b 100644
--- a/usr/src/head/ctype.h
+++ b/usr/src/head/ctype.h
@@ -27,14 +27,14 @@
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
#ifndef _CTYPE_H
#define _CTYPE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <iso/ctype_iso.h>
-#include <iso/ctype_c99.h>
/*
* Allow global visibility for symbols defined in
@@ -54,6 +54,9 @@ using std::isupper;
using std::isxdigit;
using std::tolower;
using std::toupper;
+#if _cplusplus >= 201103L
+using std::isblank;
+#endif
#endif
#ifdef __cplusplus
@@ -80,25 +83,42 @@ extern int _toupper(int);
defined(_XOPEN_SOURCE)) || defined(__XPG4_CHAR_CLASS__)
#define isascii(c) (!(((int)(c)) & ~0177))
#define toascii(c) (((int)(c)) & 0177)
-#if defined(__XPG4_CHAR_CLASS__) || defined(_XPG4)
-#define _toupper(c) (__trans_upper[(int)(c)])
-#define _tolower(c) (__trans_lower[(int)(c)])
-#else
-#define _toupper(c) ((__ctype + 258)[(int)(c)])
-#define _tolower(c) ((__ctype + 258)[(int)(c)])
-#endif /* defined(__XPG4_CHAR_CLASS__) || defined(_XPG4) */
+#define _toupper(c) (toupper(c))
+#define _tolower(c) (tolower(c))
#endif /* defined(__EXTENSIONS__) || ((!defined(_STRICT_STDC) ... */
#endif /* !defined(__lint) */
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+extern int isalnum_l(int, locale_t);
+extern int isalpha_l(int, locale_t);
+extern int isblank_l(int, locale_t);
+extern int iscntrl_l(int, locale_t);
+extern int isdigit_l(int, locale_t);
+extern int isgraph_l(int, locale_t);
+extern int islower_l(int, locale_t);
+extern int isprint_l(int, locale_t);
+extern int ispunct_l(int, locale_t);
+extern int isspace_l(int, locale_t);
+extern int isupper_l(int, locale_t);
+extern int isxdigit_l(int, locale_t);
+
+#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
+
#else /* defined(__STDC__) */
#if !defined(__lint)
#define isascii(c) (!(((int)(c)) & ~0177))
-#define _toupper(c) ((_ctype + 258)[(int)(c)])
-#define _tolower(c) ((_ctype + 258)[(int)(c)])
+#define _toupper(c) (isascii(c) ? __trans_upper[(int)(c)] : toupper(c))
+#define _tolower(c) (isascii(c) ? __trans_lower[(int)(c)] : tolower(c))
#define toascii(c) (((int)(c)) & 0177)
#endif /* !defined(__lint) */
diff --git a/usr/src/head/iso/ctype_c99.h b/usr/src/head/iso/ctype_c99.h
deleted file mode 100644
index f6edbc2b8c..0000000000
--- a/usr/src/head/iso/ctype_c99.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * An application should not include this header directly. Instead it
- * should be included only through the inclusion of <ctype.h>.
- *
- * The contents of this header is limited to identifiers specified in
- * the C99 standard and in conflict with the C++ implementation of the
- * standard header. The C++ standard may adopt the C99 standard at
- * which point it is expected that the symbols included here will
- * become part of the C++ std namespace.
- */
-
-#ifndef _ISO_CTYPE_C99_H
-#define _ISO_CTYPE_C99_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The following have been added as a result of the ISO/IEC 9899:1999
- * standard. For a strictly conforming C application, visibility is
- * contingent on the value of __STDC_VERSION__ (see sys/feature_tests.h).
- * For non-strictly conforming C applications, there are no restrictions
- * on the C namespace.
- */
-
-#if defined(__STDC__)
-
-#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
- defined(_XPG6) || defined(_STDC_C99) || defined(__EXTENSIONS__)
-extern int isblank(int);
-#endif
-
-#if !defined(__lint)
-
-#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
- defined(_XPG6) || defined(_STDC_C99) || \
- defined(__XPG4_CHAR_CLASS__) || defined(__EXTENSIONS__)
-#define isblank(c) (__ctype_mask[(int)(c)] & _ISBLANK)
-#endif
-
-#endif /* !defined(__lint) */
-
-#else /* defined(__STDC__) */
-
-#if !defined(__lint)
-
-#define isblank(c) ((_ctype + 1)[(int)(c)] & _B)
-
-#endif /* !defined(__lint) */
-
-#endif /* defined(__STDC__) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ISO_CTYPE_C99_H */
diff --git a/usr/src/head/iso/ctype_iso.h b/usr/src/head/iso/ctype_iso.h
index 31aa478288..dc736473fd 100644
--- a/usr/src/head/iso/ctype_iso.h
+++ b/usr/src/head/iso/ctype_iso.h
@@ -27,6 +27,9 @@
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
/*
* An application should not include this header directly. Instead it
@@ -43,8 +46,6 @@
#ifndef _ISO_CTYPE_ISO_H
#define _ISO_CTYPE_ISO_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/feature_tests.h>
#ifdef __cplusplus
@@ -73,11 +74,24 @@ extern "C" {
#define _ISPRINT 0x00008000
#define _ISALNUM (_ISALPHA | _ISDIGIT)
+extern unsigned char __ctype[];
+extern unsigned int *__ctype_mask;
+extern int *__trans_upper;
+extern int *__trans_lower;
#if defined(__STDC__)
-#if __cplusplus < 199711L /* Use inline functions instead for ANSI C++ */
+#if __cplusplus >= 199711L
+namespace std {
+#endif
+/*
+ * These used to be macros, which while more efficient, precludes operation
+ * with thread specific locales. The old macros will still work, but new
+ * code compiles to use functions. This is specifically permitted by the
+ * various standards. Only _tolower and _toupper were required to be
+ * delivered in macro form.
+ */
extern int isalnum(int);
extern int isalpha(int);
extern int iscntrl(int);
@@ -89,11 +103,8 @@ extern int ispunct(int);
extern int isspace(int);
extern int isupper(int);
extern int isxdigit(int);
-
-#endif /* __cplusplus < 199711L */
-
-#if __cplusplus >= 199711L
-namespace std {
+#if defined(_XPG6) || defined(_STDC_C99) || !defined(_STRICT_SYMBOLS)
+extern int isblank(int);
#endif
extern int tolower(int);
@@ -103,96 +114,22 @@ extern int toupper(int);
} /* end of namespace std */
#endif
-extern unsigned char __ctype[];
-extern unsigned int *__ctype_mask;
-extern int *__trans_upper;
-extern int *__trans_lower;
-
-#if !defined(__lint)
-
-#if __cplusplus >= 199711L
-namespace std {
-
-#if defined(__XPG4_CHAR_CLASS__) || defined(_XPG4)
-
-inline int isalpha(int c) { return (__ctype_mask[c] & _ISALPHA); }
-inline int isupper(int c) { return (__ctype_mask[c] & _ISUPPER); }
-inline int islower(int c) { return (__ctype_mask[c] & _ISLOWER); }
-inline int isdigit(int c) { return (__ctype_mask[c] & _ISDIGIT); }
-inline int isxdigit(int c) { return (__ctype_mask[c] & _ISXDIGIT); }
-inline int isalnum(int c) { return (__ctype_mask[c] & _ISALNUM); }
-inline int isspace(int c) { return (__ctype_mask[c] & _ISSPACE); }
-inline int ispunct(int c) { return (__ctype_mask[c] & _ISPUNCT); }
-inline int isprint(int c) { return (__ctype_mask[c] & _ISPRINT); }
-inline int isgraph(int c) { return (__ctype_mask[c] & _ISGRAPH); }
-inline int iscntrl(int c) { return (__ctype_mask[c] & _ISCNTRL); }
-#else
-inline int isalpha(int c) { return ((__ctype + 1)[c] & (_U | _L)); }
-inline int isupper(int c) { return ((__ctype + 1)[c] & _U); }
-inline int islower(int c) { return ((__ctype + 1)[c] & _L); }
-inline int isdigit(int c) { return ((__ctype + 1)[c] & _N); }
-inline int isxdigit(int c) { return ((__ctype + 1)[c] & _X); }
-inline int isalnum(int c) { return ((__ctype + 1)[c] & (_U | _L | _N)); }
-inline int isspace(int c) { return ((__ctype + 1)[c] & _S); }
-inline int ispunct(int c) { return ((__ctype + 1)[c] & _P); }
-inline int isprint(int c) {
- return ((__ctype + 1)[c] & (_P | _U | _L | _N | _B)); }
-inline int isgraph(int c) { return ((__ctype + 1)[c] & (_P | _U | _L | _N)); }
-inline int iscntrl(int c) { return ((__ctype + 1)[c] & _C); }
-#endif /* defined(__XPG4_CHAR_CLASS__) || defined(_XPG4) */
-
-} /* end of namespace std */
-
-#else /* __cplusplus >= 199711L */
-
-#if defined(__XPG4_CHAR_CLASS__) || defined(_XPG4)
-#define isalpha(c) (__ctype_mask[(int)(c)] & _ISALPHA)
-#define isupper(c) (__ctype_mask[(int)(c)] & _ISUPPER)
-#define islower(c) (__ctype_mask[(int)(c)] & _ISLOWER)
-#define isdigit(c) (__ctype_mask[(int)(c)] & _ISDIGIT)
-#define isxdigit(c) (__ctype_mask[(int)(c)] & _ISXDIGIT)
-#define isalnum(c) (__ctype_mask[(int)(c)] & _ISALNUM)
-#define isspace(c) (__ctype_mask[(int)(c)] & _ISSPACE)
-#define ispunct(c) (__ctype_mask[(int)(c)] & _ISPUNCT)
-#define isprint(c) (__ctype_mask[(int)(c)] & _ISPRINT)
-#define isgraph(c) (__ctype_mask[(int)(c)] & _ISGRAPH)
-#define iscntrl(c) (__ctype_mask[(int)(c)] & _ISCNTRL)
-#else
-#define isalpha(c) ((__ctype + 1)[(int)(c)] & (_U | _L))
-#define isupper(c) ((__ctype + 1)[(int)(c)] & _U)
-#define islower(c) ((__ctype + 1)[(int)(c)] & _L)
-#define isdigit(c) ((__ctype + 1)[(int)(c)] & _N)
-#define isxdigit(c) ((__ctype + 1)[(int)(c)] & _X)
-#define isalnum(c) ((__ctype + 1)[(int)(c)] & (_U | _L | _N))
-#define isspace(c) ((__ctype + 1)[(int)(c)] & _S)
-#define ispunct(c) ((__ctype + 1)[(int)(c)] & _P)
-#define isprint(c) ((__ctype + 1)[(int)(c)] & (_P | _U | _L | _N | _B))
-#define isgraph(c) ((__ctype + 1)[(int)(c)] & (_P | _U | _L | _N))
-#define iscntrl(c) ((__ctype + 1)[(int)(c)] & _C)
-
-#endif /* defined(__XPG4_CHAR_CLASS__) || defined(_XPG4) */
-
-#endif /* __cplusplus >= 199711L */
-
-#endif /* !defined(__lint) */
-
#else /* defined(__STDC__) */
-extern unsigned char _ctype[];
-
#if !defined(__lint)
-#define isalpha(c) ((_ctype + 1)[(int)(c)] & (_U | _L))
-#define isupper(c) ((_ctype + 1)[(int)(c)] & _U)
-#define islower(c) ((_ctype + 1)[(int)(c)] & _L)
-#define isdigit(c) ((_ctype + 1)[(int)(c)] & _N)
-#define isxdigit(c) ((_ctype + 1)[(int)(c)] & _X)
-#define isalnum(c) ((_ctype + 1)[(int)(c)] & (_U | _L | _N))
-#define isspace(c) ((_ctype + 1)[(int)(c)] & _S)
-#define ispunct(c) ((_ctype + 1)[(int)(c)] & _P)
-#define isprint(c) ((_ctype + 1)[(int)(c)] & (_P | _U | _L | _N | _B))
-#define isgraph(c) ((_ctype + 1)[(int)(c)] & (_P | _U | _L | _N))
-#define iscntrl(c) ((_ctype + 1)[(int)(c)] & _C)
+extern int isalpha();
+extern int isupper();
+extern int islower();
+extern int isdigit();
+extern int isxdigit();
+extern int isalnum();
+extern int isspace();
+extern int ispunct();
+extern int isprint();
+extern int isgraph();
+extern int iscntrl();
+extern int isblank();
#endif /* !defined(__lint) */
diff --git a/usr/src/head/iso/stdlib_iso.h b/usr/src/head/iso/stdlib_iso.h
index 17577a93dd..5b958873c4 100644
--- a/usr/src/head/iso/stdlib_iso.h
+++ b/usr/src/head/iso/stdlib_iso.h
@@ -23,6 +23,9 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
@@ -50,11 +53,12 @@ extern "C" {
#endif
#if defined(__STDC__)
-extern unsigned char __ctype[];
-#define MB_CUR_MAX __ctype[520]
+unsigned char __mb_cur_max(void);
#else
-extern unsigned char _ctype[];
-#define MB_CUR_MAX _ctype[520]
+unsigned char __mb_cur_max();
+#endif
+#ifndef MB_CUR_MAX
+#define MB_CUR_MAX (__mb_cur_max())
#endif
#if __cplusplus >= 199711L
diff --git a/usr/src/head/iso/wctype_c99.h b/usr/src/head/iso/wctype_c99.h
deleted file mode 100644
index 89a47feddb..0000000000
--- a/usr/src/head/iso/wctype_c99.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * An application should not include this header directly. Instead it
- * should be included only through the inclusion of other Sun headers.
- *
- * The contents of this header is limited to identifiers specified in
- * the C99 standard and in conflict with the C++ implementation of the
- * standard header. The C++ standard may adopt the C99 standard at
- * which point it is expected that the symbols included here will
- * become part of the C++ std namespace.
- */
-
-#ifndef _ISO_WCTYPE_C99_H
-#define _ISO_WCTYPE_C99_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The following have been added as a result of the ISO/IEC 9899:1999
- * standard. For a strictly conforming C application, visibility is
- * contingent on the value of __STDC_VERSION__ (see sys/feature_tests.h).
- * For non-strictly conforming C applications, there are no restrictions
- * on the C namespace.
- */
-
-/*
- * Visibility of the iswblank() function is not allowed in the X/Open
- * or POSIX namespace prior to SUSv3. However, since SUSv3 aligns
- * with the C99 standard, visibility is controlled by the version of
- * the C standard as indicated by the value of __STDC_VERSION__ (see
- * sys/feature_tests.h and _STDC_C99) rather than if the X/Open or POSIX
- * feature test macros are used. Conforming SUSv3 applications are
- * required to use c99, therefore, iswblank() will be made visible by
- * default.
- */
-
-#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
- defined(_STDC_C99) || defined(__EXTENSIONS__)
-#ifdef __STDC__
-extern int iswblank(wint_t);
-#else
-extern int iswblank();
-#endif
-#endif /* defined(__EXTENSIONS__)... */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ISO_WCTYPE_C99_H */
diff --git a/usr/src/head/iso/wctype_iso.h b/usr/src/head/iso/wctype_iso.h
index 9d74aeb4d9..450cb6a34a 100644
--- a/usr/src/head/iso/wctype_iso.h
+++ b/usr/src/head/iso/wctype_iso.h
@@ -27,6 +27,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
/*
* An application should not include this header directly. Instead it
@@ -43,8 +46,6 @@
#ifndef _ISO_WCTYPE_ISO_H
#define _ISO_WCTYPE_ISO_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/feature_tests.h>
#ifdef __cplusplus
@@ -94,6 +95,12 @@ extern int iswpunct(wint_t);
extern int iswspace(wint_t);
extern int iswupper(wint_t);
extern int iswxdigit(wint_t);
+
+#if (__cplusplus >= 201103L) || defined(_STDC_C99) || defined(_XPG6) || \
+ !defined(_STRICT_SYMBOLS)
+extern int iswblank(wint_t);
+#endif
+
/* tow* also become functions */
extern wint_t towlower(wint_t);
extern wint_t towupper(wint_t);
@@ -101,7 +108,7 @@ extern wctrans_t wctrans(const char *);
extern wint_t towctrans(wint_t, wctrans_t);
extern int iswctype(wint_t, wctype_t);
extern wctype_t wctype(const char *);
-#else
+#else /* __STDC__ */
extern int iswalnum();
extern int iswalpha();
extern int iswcntrl();
@@ -120,7 +127,10 @@ extern wctrans_t wctrans();
extern wint_t towctrans();
extern int iswctype();
extern wctype_t wctype();
+#if defined(_XPG6) || !defined(_STRICT_SYMBOLS)
+extern int iswblank();
#endif
+#endif /* __STDC__ */
/* bit definition for character class */
diff --git a/usr/src/head/langinfo.h b/usr/src/head/langinfo.h
index 2e73cfbae7..2a61edd983 100644
--- a/usr/src/head/langinfo.h
+++ b/usr/src/head/langinfo.h
@@ -27,12 +27,14 @@
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
#ifndef _LANGINFO_H
#define _LANGINFO_H
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */
-
#include <sys/feature_tests.h>
#include <nl_types.h>
@@ -150,6 +152,19 @@ char *nl_langinfo(nl_item); /* get a string from the database */
char *nl_langinfo(); /* get a string from the database */
#endif
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+#if defined(__STDC__)
+char *nl_langinfo_l(nl_item, locale_t);
+#else
+char *nl_langinfo_l();
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/head/locale.h b/usr/src/head/locale.h
index 7f6f323e2b..3c98df2413 100644
--- a/usr/src/head/locale.h
+++ b/usr/src/head/locale.h
@@ -24,11 +24,20 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ *
+ * Portions of this file developed by Garrett D'Amore are licensed
+ * under the terms of the Common Development and Distribution License (CDDL)
+ * version 1.0 only. The use of subsequent versions of the License are
+ * is specifically prohibited unless those terms are not in conflict with
+ * version 1.0 of the License. You can find this license on-line at
+ * http://www.illumos.org/license/CDDL
+ */
+
#ifndef _LOCALE_H
#define _LOCALE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <iso/locale_iso.h>
#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
@@ -56,6 +65,42 @@ extern "C" {
(((int)(c) >= LC_CTYPE) && ((int)(c) <= _LastCategory) || \
((int)c == LC_ALL))
+
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+
+/*
+ * These were added in POSIX 2008 as part of the newlocale() specification.
+ */
+#define LC_CTYPE_MASK (1 << LC_CTYPE)
+#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
+#define LC_TIME_MASK (1 << LC_TIME)
+#define LC_COLLATE_MASK (1 << LC_COLLATE)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_ALL_MASK (0x3f)
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+#if defined(__STDC__)
+extern locale_t duplocale(locale_t);
+extern void freelocale(locale_t);
+extern locale_t newlocale(int, const char *, locale_t);
+extern locale_t uselocale(locale_t);
+#else /* __STDC__ */
+extern locale_t duplocale();
+extern void freelocale();
+extern locale_t newlocale();
+extern locale_t uselocale();
+#endif /* __STDC__ */
+
+#define LC_GLOBAL_LOCALE (__global_locale())
+extern locale_t __global_locale(void);
+
+#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/head/monetary.h b/usr/src/head/monetary.h
index 6c190a7a44..1ef02ca8da 100644
--- a/usr/src/head/monetary.h
+++ b/usr/src/head/monetary.h
@@ -23,12 +23,13 @@
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
#ifndef _MONETARY_H
#define _MONETARY_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/feature_tests.h>
#include <sys/types.h>
@@ -39,8 +40,21 @@ extern "C" {
#if defined(__STDC__)
extern ssize_t strfmon(char *_RESTRICT_KYWD, size_t,
const char *_RESTRICT_KYWD, ...);
+
+#if defined(_XPG7) || (!defined(_STRICT_STRICT_SYMBOLS))
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+extern ssize_t strfmon_l(char *_RESTRICT_KYWD, size_t, locale_t,
+ const char *_RESTRICT_KYWD, ...);
+#endif
+
#else
extern ssize_t strfmon();
+extern ssize_t strfmon_l();
#endif
#ifdef __cplusplus
diff --git a/usr/src/head/string.h b/usr/src/head/string.h
index f786eb72d8..99c941c5bd 100644
--- a/usr/src/head/string.h
+++ b/usr/src/head/string.h
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -86,20 +87,30 @@ extern void *memccpy(void *_RESTRICT_KYWD, const void *_RESTRICT_KYWD,
int, size_t);
#endif
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
- /* || defined(_XPG7) */
-extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, size_t);
+#if !defined(_STRICT_SYMBOLS) || defined(_XPG7)
+
extern char *stpcpy(char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD);
extern char *stpncpy(char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t);
extern char *strndup(const char *, size_t);
extern size_t strnlen(const char *, size_t);
extern char *strsignal(int);
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
#endif
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
+extern int strcoll_l(const char *, const char *, locale_t);
+extern size_t strxfrm_l(char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+ size_t, locale_t);
+extern int strcasecmp_l(const char *, const char *, locale_t);
+extern int strncasecmp_l(const char *, const char *, size_t, locale_t);
+
+#endif /* defined(_STRICT_SYMBOLS) || defined(_XPG7) */
+
+#if !defined(_STRICT_SYMBOLS)
+
+/* Note that some of these are also declared in strings.h for XPG4_2+ */
extern int uucopy(const void *_RESTRICT_KYWD, void *_RESTRICT_KYWD, size_t);
extern int uucopystr(const void *_RESTRICT_KYWD, void *_RESTRICT_KYWD, size_t);
extern int ffs(int);
@@ -115,6 +126,9 @@ extern size_t strlcpy(char *, const char *, size_t);
extern size_t strlcat(char *, const char *, size_t);
extern char *strsep(char **stringp, const char *delim);
extern char *strchrnul(const char *, int);
+extern char *strcasestr_l(const char *, const char *, locale_t);
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, size_t);
#endif /* defined(__EXTENSIONS__)... */
#if defined(__EXTENSIONS__) || \
@@ -194,11 +208,11 @@ extern char *strtok_r();
extern void *memccpy();
#endif
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
- /* || defined(_XPG7) */
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
extern int strcasecmp();
extern int strncasecmp();
+extern int strcasecmp_l();
+extern int strncasecmp_l();
extern char *stpcpy();
extern char *stpncpy();
extern char *strndup();
@@ -206,8 +220,7 @@ extern size_t strnlen();
extern char *strsignal();
#endif
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
+#if !defined(_STRICT_SYMBOLS)
extern int uucopy();
extern int uucopystr();
extern int ffs();
@@ -217,17 +230,23 @@ extern int fls();
extern int flsl();
extern int flsll();
extern char *strcasestr();
+extern char *strcasestr_l();
extern char *strnstr();
extern size_t strlcpy();
extern size_t strlcat();
extern char *strsep();
extern char *strchrnul();
-#endif /* defined(__EXTENSIONS__) ... */
+#endif /* _STRICT_SYMBOLS */
#if defined(__EXTENSIONS__) || !defined(__XOPEN_OR_POSIX) || defined(_XPG4_2)
extern char *strdup();
#endif
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+extern size_t strcoll_l();
+extern size_t strxfrm_l();
+#endif
+
#endif /* __STDC__ */
#ifdef __cplusplus
diff --git a/usr/src/head/strings.h b/usr/src/head/strings.h
index d4487dae1f..ef466cc4fa 100644
--- a/usr/src/head/strings.h
+++ b/usr/src/head/strings.h
@@ -23,12 +23,13 @@
* Copyright (c) 1995, 1996, by Sun Microsystems, Inc.
* All rights reserved.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
#ifndef _STRINGS_H
#define _STRINGS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/feature_tests.h>
@@ -63,6 +64,14 @@ extern char *rindex(const char *, int);
extern int ffs(int);
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);
+#if defined(_XPG7)
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+extern int strcasecmp_l(const char *, const char *, locale_t);
+extern int strncasecmp_l(const char *, const char *, size_t, locale_t);
+#endif /* defined(_XPG7) */
#endif /* defined(_XPG4_2) && !defined(__EXTENSIONS__) */
#else
@@ -78,6 +87,10 @@ extern char *rindex();
extern int ffs();
extern int strcasecmp();
extern int strncasecmp();
+#if defined(_XPG7)
+extern int strcasecmp_l();
+extern int strncasecmp_l();
+#endif
#endif /* defined(_XPG4_2) && !defined(__EXTENSIONS__) */
#endif /* __STDC__ */
diff --git a/usr/src/head/time.h b/usr/src/head/time.h
index 44f558d9c9..523b080c98 100644
--- a/usr/src/head/time.h
+++ b/usr/src/head/time.h
@@ -28,6 +28,7 @@
*/
/*
* Copyright 2010 Nexenta Systems, Inc. Al rights reserved.
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
#ifndef _TIME_H
@@ -371,6 +372,23 @@ extern char *ctime_r();
#endif /* defined(__EXTENSIONS__) || defined(_REENTRANT)... */
+
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+#if defined(__STDC__)
+extern size_t strftime_l(char *_RESTRICT_KYWD, size_t,
+ const char *_RESTRICT_KYWD, const struct tm *_RESTRICT_KYWD, locale_t);
+#else /* __STDC__ */
+extern size_t strftime_l();
+#endif /* __STDC__ */
+
+#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/head/wchar.h b/usr/src/head/wchar.h
index b80469846a..47fb64342a 100644
--- a/usr/src/head/wchar.h
+++ b/usr/src/head/wchar.h
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -167,17 +168,29 @@ using std::wctype;
#endif
#endif /* !defined(_STRICT_STDC) || defined(_XOPEN_SOURCE)... */
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
- /* || defined(_XPG7) */
-extern wchar_t *wcsdup(const wchar_t *);
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
extern size_t wcsnlen(const wchar_t *, size_t);
extern wchar_t *wcpcpy(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD);
extern wchar_t *wcpncpy(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
size_t);
+extern size_t wcsxfrm_l(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
+ size_t, locale_t);
+extern int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
+extern wchar_t *wcsdup(const wchar_t *);
extern int wcscasecmp(const wchar_t *, const wchar_t *);
+extern int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
extern int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
-#endif
+extern int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
+extern size_t mbsnrtowcs(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
+ size_t, size_t, mbstate_t *_RESTRICT_KYWD);
+
+#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
#else /* __STDC__ */
@@ -202,15 +215,18 @@ extern int wcwidth();
extern wctype_t wctype();
#endif /* !defined(_STRICT_STDC) || defined(_XOPEN_SOURCE)... */
-#if defined(__EXTENSIONS__) || \
- (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX))
- /* || defined(_XPG7) */
-extern wchar_t *wcsdup();
+#if defined(_XGP7) || !defined(_STRICT_SYMBOLS)
extern size_t wcsnlen();
extern wchar_t *wcpcpy();
extern wchar_t *wcpncpy();
+extern size_t wcsxfrm_l();
+extern int wcscoll_l();
+extern wchar_t *wcsdup();
extern int wcscasecmp();
+extern int wcscasecmp_l();
extern int wcsncasecmp();
+extern int wcsncasecmp_l();
+extern size_t mbsnrtowcs();
#endif
#endif /* __STDC__ */
diff --git a/usr/src/head/wctype.h b/usr/src/head/wctype.h
index ae69a8e1f8..0d48b967c4 100644
--- a/usr/src/head/wctype.h
+++ b/usr/src/head/wctype.h
@@ -24,6 +24,7 @@
/* definitions for international functions */
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,11 +32,9 @@
#ifndef _WCTYPE_H
#define _WCTYPE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
+#include <sys/feature_tests.h>
#include <iso/wctype_iso.h>
-#if !defined(__XOPEN_OR_POSIX) && !defined(_STRICT_STDC) || \
- defined(__EXTENSIONS__)
+#ifndef _STRICT_SYMBOLS
#include <ctype.h>
#include <wchar.h>
#endif
@@ -64,22 +63,17 @@ using std::wctrans;
using std::towctrans;
using std::iswctype;
using std::wctype;
+#if __cplusplus >= 201103L
+using std::iswblank;
+#endif
#endif
-
-/*
- * This header needs to be included here because it relies on the global
- * visibility of wint_t in the C++ environment.
- */
-
-#include <iso/wctype_c99.h>
#ifdef __cplusplus
extern "C" {
#endif
/* do not allow any of the following in a strictly conforming application */
-#if !defined(__XOPEN_OR_POSIX) && !defined(_STRICT_STDC) || \
- defined(__EXTENSIONS__)
+#ifndef _STRICT_SYMBOLS
/*
* data structure for supplementary code set
@@ -111,24 +105,32 @@ extern wint_t __nextwctype(wint_t, wctype_t);
/* isw*, except iswascii(), are not macros any more. They become functions */
#ifdef __STDC__
-extern unsigned _iswctype(wchar_t, int);
-extern wchar_t _trwctype(wchar_t, int);
/* is* also become functions */
extern int isphonogram(wint_t);
extern int isideogram(wint_t);
extern int isenglish(wint_t);
extern int isnumber(wint_t);
extern int isspecial(wint_t);
-#else
+/* From BSD/MacOS */
+extern int iswideogram(wint_t);
+extern int iswphonogram(wint_t);
+extern int iswnumber(wint_t);
+extern int iswhexnumber(wint_t);
+extern int iswspecial(wint_t);
+
+#else /* __STDC__ */
-extern unsigned _iswctype();
-extern wchar_t _trwctype();
/* is* also become functions */
extern int isphonogram();
extern int isideogram();
extern int isenglish();
extern int isnumber();
extern int isspecial();
+/* From BSD/MacOS */
+extern int iswideogram();
+extern int iswphonogram();
+extern int iswnumber();
+extern int iswspecial();
#endif
#define iscodeset0(c) isascii(c)
@@ -136,7 +138,55 @@ extern int isspecial();
#define iscodeset2(c) (((c) & WCHAR_CSMASK) == WCHAR_CS2)
#define iscodeset3(c) (((c) & WCHAR_CSMASK) == WCHAR_CS3)
-#endif /* !defined(__XOPEN_OR_POSIX)... */
+#endif /* !defined(_STRICT_SYMBOLS)... */
+
+
+/* XPG7 extended locale support */
+#if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+#if defined(__STDC__)
+extern wint_t towlower_l(wint_t, locale_t);
+extern wint_t towupper_l(wint_t, locale_t);
+extern wint_t towctrans_l(wint_t, wctrans_t, locale_t);
+extern int iswctype_l(wint_t, wctype_t, locale_t);
+extern int iswalnum_l(wint_t, locale_t);
+extern int iswalpha_l(wint_t, locale_t);
+extern int iswcntrl_l(wint_t, locale_t);
+extern int iswdigit_l(wint_t, locale_t);
+extern int iswgraph_l(wint_t, locale_t);
+extern int iswlower_l(wint_t, locale_t);
+extern int iswprint_l(wint_t, locale_t);
+extern int iswpunct_l(wint_t, locale_t);
+extern int iswspace_l(wint_t, locale_t);
+extern int iswupper_l(wint_t, locale_t);
+extern int iswxdigit_l(wint_t, locale_t);
+extern wctrans_t wctrans_l(const char *, locale_t);
+extern wctype_t wctype_l(const char *, locale_t);
+#else /* __STDC__ */
+extern wint_t towlower_l();
+extern wint_t towupper_l();
+extern wint_t towctrans_l();
+extern int iswctype_l();
+extern int iswalnum_l();
+extern int iswalpha_l();
+extern int iswcntrl_l();
+extern int iswdigit_l();
+extern int iswgraph_l();
+extern int iswlower_l();
+extern int iswprint_l();
+extern int iswpunct_l();
+extern int iswspace_l();
+extern int iswupper_l();
+extern int iswxdigit_l();
+extern wctrans_t wctrans_l();
+extern wctype_t wctype_l();
+#endif /* __STDC__ */
+#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
#ifdef __cplusplus
}
diff --git a/usr/src/head/xlocale.h b/usr/src/head/xlocale.h
new file mode 100644
index 0000000000..7393a31a15
--- /dev/null
+++ b/usr/src/head/xlocale.h
@@ -0,0 +1,113 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
+#ifndef _XLOCALE_H
+#define _XLOCALE_H
+
+/*
+ * This file supplies declarations for extended locale routines, as
+ * originally delivered by MacOS X. Many of these things are now
+ * officially part of XPG7. (Note that while the interfaces are the
+ * same as MacOS X, there is no shared implementation.)
+ *
+ * Those declarations that are part of XPG7 are provided for the in the
+ * XPG7-specified location. This file lists just the declarations that
+ * were not part of the standard. These will be useful in their own right,
+ * and will aid porting programs that don't strictly follow the standard.
+ *
+ * Note that it is an error to include this file in a program with strict
+ * symbol visibilty rules (under strict ANSI or POSIX_C_SOURCE rules.)
+ * If this is done, the symbols defined here will indeed be exposed to your
+ * program, but those symbols that are part of the related standards might
+ * not be.
+ */
+
+#include <sys/feature_tests.h>
+#include <wchar.h>
+#include <locale.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _LOCALE_T
+#define _LOCALE_T
+typedef struct locale *locale_t;
+#endif
+
+extern int mbsinit_l(const mbstate_t *, locale_t);
+
+extern size_t mbsrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
+ size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
+
+extern size_t mbsnrtowcs_l(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
+ size_t, size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
+
+extern char *strptime_l(const char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+ struct tm *_RESTRICT_KYWD, locale_t);
+
+extern int wcwidth_l(wchar_t, locale_t);
+
+extern int wcswidth_l(const wchar_t *, size_t, locale_t);
+
+extern int iswspecial_l(wint_t, locale_t);
+extern int iswnumber_l(wint_t, locale_t);
+extern int iswhexnumber_l(wint_t, locale_t);
+extern int iswideogram_l(wint_t, locale_t);
+extern int iswphonogram_l(wint_t, locale_t);
+
+extern wint_t btowc_l(int, locale_t);
+extern int wctob_l(wint_t, locale_t);
+extern size_t mbrtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+ size_t, mbstate_t *_RESTRICT_KYWD, locale_t);
+extern size_t mbstowcs_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
+ size_t, locale_t);
+extern int mblen_l(const char *, size_t, locale_t);
+extern size_t mbrlen_l(const char *_RESTRICT_KYWD, size_t,
+ mbstate_t *_RESTRICT_KYWD, locale_t);
+extern int mbtowc_l(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, size_t,
+ locale_t);
+extern size_t wcsrtombs_l(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
+ size_t len, mbstate_t *_RESTRICT_KYWD, locale_t);
+extern size_t wcrtomb_l(char *_RESTRICT_KYWD, wchar_t,
+ mbstate_t *_RESTRICT_KYWD, locale_t);
+extern size_t wcstombs_l(char *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
+ size_t, locale_t);
+extern int wctomb_l(char *, wchar_t, locale_t);
+
+extern unsigned char __mb_cur_max_l(locale_t);
+#ifndef MB_CUR_MAX_L
+#define MB_CUR_MAX_L(l) (__mb_cur_max_l(l))
+#endif
+
+
+#if defined(_XPG4) && !defined(_FILEDEFED) || __cplusplus >= 199711L
+#define _FILEDEFED
+typedef __FILE FILE;
+#endif
+
+extern wint_t fgetwc_l(FILE *, locale_t);
+extern wint_t getwc_l(FILE *, locale_t);
+
+#ifndef getwchar_l
+#define getwchar_l(l) fgetwc_l(stdin, (l))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XLOCALE_H */
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile
index 873c2ded87..59d9a684e9 100644
--- a/usr/src/lib/libc/amd64/Makefile
+++ b/usr/src/lib/libc/amd64/Makefile
@@ -23,6 +23,7 @@
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
#
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2013 Garrett D'Amore <garrett@damore.org>
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -655,9 +656,6 @@ PORTI18N= \
getwchar.o \
putwchar.o \
putws.o \
- strcasecmp.o \
- strcasestr.o \
- strncasecmp.o \
strtows.o \
wcsnlen.o \
wcsstr.o \
@@ -670,7 +668,6 @@ PORTI18N= \
wmemcpy.o \
wmemmove.o \
wmemset.o \
- wscasecmp.o \
wscat.o \
wschr.o \
wscmp.o \
@@ -678,7 +675,6 @@ PORTI18N= \
wscspn.o \
wsdup.o \
wslen.o \
- wsncasecmp.o \
wsncat.o \
wsncmp.o \
wsncpy.o \
@@ -696,7 +692,6 @@ PORTI18N= \
gettext_gnu.o \
gettext_real.o \
gettext_util.o \
- isdigit.o \
plural_parser.o \
wdresolve.o \
_ctype.o \
@@ -724,12 +719,14 @@ PORTLOCALE= \
gb2312.o \
gbk.o \
getdate.o \
+ isdigit.o \
iswctype.o \
ldpart.o \
lmessages.o \
lnumeric.o \
lmonetary.o \
localeconv.o \
+ localeimpl.o \
mbftowc.o \
mblen.o \
mbrlen.o \
@@ -751,9 +748,12 @@ PORTLOCALE= \
runetype.o \
setlocale.o \
setrunelocale.o \
+ strcasecmp.o \
+ strcasestr.o \
strcoll.o \
strfmon.o \
strftime.o \
+ strncasecmp.o \
strptime.o \
strxfrm.o \
table.o \
@@ -763,6 +763,7 @@ PORTLOCALE= \
ungetwc.o \
utf8.o \
wcrtomb.o \
+ wcscasecmp.o \
wcscoll.o \
wcsftime.o \
wcsnrtombs.o \
diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com
index b21f87a0d6..ca8e9b8970 100644
--- a/usr/src/lib/libc/i386/Makefile.com
+++ b/usr/src/lib/libc/i386/Makefile.com
@@ -22,6 +22,7 @@
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, Joyent, Inc. All rights reserved.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2013 Garrett D'Amore <garrett@damore.org>
#
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -697,9 +698,6 @@ PORTI18N= \
getwchar.o \
putwchar.o \
putws.o \
- strcasecmp.o \
- strcasestr.o \
- strncasecmp.o \
strtows.o \
wcsnlen.o \
wcsstr.o \
@@ -712,7 +710,6 @@ PORTI18N= \
wmemcpy.o \
wmemmove.o \
wmemset.o \
- wscasecmp.o \
wscat.o \
wschr.o \
wscmp.o \
@@ -720,7 +717,6 @@ PORTI18N= \
wscspn.o \
wsdup.o \
wslen.o \
- wsncasecmp.o \
wsncat.o \
wsncmp.o \
wsncpy.o \
@@ -738,7 +734,6 @@ PORTI18N= \
gettext_gnu.o \
gettext_real.o \
gettext_util.o \
- isdigit.o \
plural_parser.o \
wdresolve.o \
_ctype.o \
@@ -766,12 +761,14 @@ PORTLOCALE= \
gb2312.o \
gbk.o \
getdate.o \
+ isdigit.o \
iswctype.o \
ldpart.o \
lmessages.o \
lnumeric.o \
lmonetary.o \
localeconv.o \
+ localeimpl.o \
mbftowc.o \
mblen.o \
mbrlen.o \
@@ -793,9 +790,12 @@ PORTLOCALE= \
runetype.o \
setlocale.o \
setrunelocale.o \
+ strcasecmp.o \
+ strcasestr.o \
strcoll.o \
strfmon.o \
strftime.o \
+ strncasecmp.o \
strptime.o \
strxfrm.o \
table.o \
@@ -805,6 +805,7 @@ PORTLOCALE= \
ungetwc.o \
utf8.o \
wcrtomb.o \
+ wcscasecmp.o \
wcscoll.o \
wcsftime.o \
wcsnrtombs.o \
diff --git a/usr/src/lib/libc/port/i18n/isdigit.c b/usr/src/lib/libc/port/i18n/isdigit.c
deleted file mode 100644
index 69f6f4bbdd..0000000000
--- a/usr/src/lib/libc/port/i18n/isdigit.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source. A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*
- * This file contains the implementation of various functional forms
- * of the ctype tests, specifically the required by ISO C. These are defined
- * in the "C" (POSIX) locale.
- */
-
-#include "lint.h"
-#include <ctype.h>
-
-/*
- * We are supplying functional forms, so make sure to suppress any macros
- * we might have imported.
- */
-
-#ifdef isblank
-#undef isblank
-#endif
-
-int
-isblank(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISBLANK));
-}
-
-#ifdef isupper
-#undef isupper
-#endif
-
-int
-isupper(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISUPPER));
-}
-
-#ifdef islower
-#undef islower
-#endif
-
-int
-islower(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISLOWER));
-}
-
-#ifdef isdigit
-#undef isdigit
-#endif
-
-int
-isdigit(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISDIGIT));
-}
-
-#ifdef isxdigit
-#undef isxdigit
-#endif
-
-int
-isxdigit(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISXDIGIT));
-}
-
-#ifdef isalpha
-#undef isalpha
-#endif
-
-int
-isalpha(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISALPHA));
-}
-
-#ifdef isalnum
-#undef isalnum
-#endif
-
-int
-isalnum(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISALNUM));
-}
-
-#ifdef isspace
-#undef isspace
-#endif
-
-int
-isspace(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISSPACE));
-}
-
-#ifdef iscntrl
-#undef iscntrl
-#endif
-
-int
-iscntrl(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISCNTRL));
-}
-
-#ifdef isgraph
-#undef isgraph
-#endif
-
-int
-isgraph(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISGRAPH));
-}
-
-#ifdef ispunct
-#undef ispunct
-#endif
-
-int
-ispunct(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISPUNCT));
-}
-
-#ifdef isprint
-#undef isprint
-#endif
-
-int
-isprint(int c)
-{
- return (((unsigned)c > 255) ? 0 : (__ctype_mask[c] & _ISPRINT));
-}
diff --git a/usr/src/lib/libc/port/i18n/wscasecmp.c b/usr/src/lib/libc/port/i18n/wscasecmp.c
deleted file mode 100644
index c8855ded41..0000000000
--- a/usr/src/lib/libc/port/i18n/wscasecmp.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * Compare strings ignoring case difference.
- * returns: s1>s2: >0 s1==s2: 0 s1<s2: <0
- * All letters are converted to the lowercase and compared.
- */
-
-#pragma weak _wscasecmp = wscasecmp
-
-#include "lint.h"
-#include <stdlib.h>
-#include <widec.h>
-#include "libc.h"
-
-int
-wcscasecmp(const wchar_t *s1, const wchar_t *s2)
-{
- if (s1 == s2)
- return (0);
-
- while (towlower(*s1) == towlower(*s2++))
- if (*s1++ == 0)
- return (0);
- return (towlower(*s1) - towlower(*(s2 - 1)));
-}
-
-int
-wscasecmp(const wchar_t *s1, const wchar_t *s2)
-{
- return (wcscasecmp(s1, s2));
-}
diff --git a/usr/src/lib/libc/port/locale/_ctype.h b/usr/src/lib/libc/port/locale/_ctype.h
index 34c3a49435..462b19f57c 100644
--- a/usr/src/lib/libc/port/locale/_ctype.h
+++ b/usr/src/lib/libc/port/locale/_ctype.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -79,6 +80,4 @@
#define _CTYPE_SWM 0xe0000000U /* Mask for screen width data */
#define _CTYPE_SWS 30 /* Bits to shift to get width */
-unsigned int ___runetype(int);
-
#endif /* !__CTYPE_H_ */
diff --git a/usr/src/lib/libc/port/locale/big5.c b/usr/src/lib/libc/port/locale/big5.c
index f13df7a6f2..2729ab0289 100644
--- a/usr/src/lib/libc/port/locale/big5.c
+++ b/usr/src/lib/libc/port/locale/big5.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
* Copyright (c) 1993
@@ -35,11 +36,11 @@
#include "lint.h"
#include <sys/types.h>
#include <errno.h>
-#include "runetype.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _BIG5_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -47,22 +48,27 @@ static size_t _BIG5_mbrtowc(wchar_t *_RESTRICT_KYWD,
static int _BIG5_mbsinit(const mbstate_t *);
static size_t _BIG5_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+static size_t _BIG5_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _BIG5_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
typedef struct {
wchar_t ch;
} _BIG5State;
-int
-_BIG5_init(_RuneLocale *rl)
+void
+_BIG5_init(struct lc_ctype *lct)
{
-
- __mbrtowc = _BIG5_mbrtowc;
- __wcrtomb = _BIG5_wcrtomb;
- __mbsinit = _BIG5_mbsinit;
- _CurrentRuneLocale = rl;
- __ctype[520] = 2;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _BIG5_mbrtowc;
+ lct->lc_wcrtomb = _BIG5_wcrtomb;
+ lct->lc_mbsnrtowcs = _BIG5_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _BIG5_wcsnrtombs;
+ lct->lc_mbsinit = _BIG5_mbsinit;
+ lct->lc_max_mblen = 2;
+ lct->lc_is_ascii = 0;
}
static int
@@ -164,3 +170,17 @@ _BIG5_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc, mbstate_t *_RESTRICT_KYWD ps)
*s = wc & 0xff;
return (1);
}
+
+static size_t
+_BIG5_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _BIG5_mbrtowc));
+}
+
+static size_t
+_BIG5_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _BIG5_wcrtomb));
+}
diff --git a/usr/src/lib/libc/port/locale/btowc.c b/usr/src/lib/libc/port/locale/btowc.c
index d835f8da77..9401d9b030 100644
--- a/usr/src/lib/libc/port/locale/btowc.c
+++ b/usr/src/lib/libc/port/locale/btowc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002, 2003 Tim J. Robbins.
* All rights reserved.
@@ -28,10 +29,12 @@
#include "lint.h"
#include <stdio.h>
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
wint_t
-btowc(int c)
+btowc_l(int c, locale_t loc)
{
static const mbstate_t initial = { 0 };
mbstate_t mbs = initial;
@@ -46,7 +49,13 @@ btowc(int c)
* counts.
*/
cc = (char)c;
- if (__mbrtowc(&wc, &cc, 1, &mbs) > 1)
+ if (mbrtowc_l(&wc, &cc, 1, &mbs, loc) > 1)
return (WEOF);
return (wc);
}
+
+wint_t
+btowc(int c)
+{
+ return (btowc_l(c, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/collate.c b/usr/src/lib/libc/port/locale/collate.c
index 9064ca685f..75814a9a9f 100644
--- a/usr/src/lib/libc/port/locale/collate.c
+++ b/usr/src/lib/libc/port/locale/collate.c
@@ -1,5 +1,6 @@
/*
- * Copright 2010 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
* All rights reserved.
@@ -44,7 +45,6 @@
#include "collate.h"
#include "setlocale.h"
-#include "ldpart.h"
/*
* See the comments in usr/src/cmd/localedef/collate.c for further
@@ -53,21 +53,21 @@
* handy (www.opengroup.org).
*/
-static collate_subst_t *subst_table[COLL_WEIGHTS_MAX];
-static collate_char_t *char_pri_table;
-static collate_large_t *large_pri_table;
-static collate_chain_t *chain_pri_table;
-static char *cache = NULL;
-static size_t cachesz;
-static char collate_encoding[ENCODING_LEN + 1];
+/*
+ * POSIX uses empty tables and falls down to strcmp.
+ */
+struct lc_collate lc_collate_posix = {
+ .lc_is_posix = 1,
+};
-/* Exposed externally to other parts of libc. */
-collate_info_t *_collate_info;
-int _collate_load_error = 1;
+struct locdata __posix_collate_locdata = {
+ .l_lname = "C",
+ .l_data = { &lc_collate_posix }
+};
-int
-_collate_load_tables(const char *encoding)
+struct locdata *
+__lc_collate_load(const char *locname)
{
int i, chains, z;
char buf[PATH_MAX];
@@ -76,49 +76,41 @@ _collate_load_tables(const char *encoding)
collate_info_t *info;
struct stat sbuf;
int fd;
-
- /* 'encoding' must be already checked. */
- if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
- _collate_load_error = 1;
- return (_LDP_CACHE);
- }
-
- /*
- * If the locale name is the same as our cache, use the cache.
- */
- if (cache && (strncmp(encoding, collate_encoding, ENCODING_LEN) == 0)) {
- _collate_load_error = 0;
- return (_LDP_CACHE);
- }
+ struct locdata *ldata;
+ struct lc_collate *lcc;
/*
* Slurp the locale file into the cache.
*/
(void) snprintf(buf, sizeof (buf), "%s/%s/LC_COLLATE/LCL_DATA",
- _PathLocale, encoding);
+ _PathLocale, locname);
- if ((fd = open(buf, O_RDONLY)) < 0)
- return (_LDP_ERROR);
+ if ((fd = open(buf, O_RDONLY)) < 0) {
+ errno = EINVAL;
+ return (NULL);
+ }
if (fstat(fd, &sbuf) < 0) {
(void) close(fd);
- return (_LDP_ERROR);
+ errno = EINVAL;
+ return (NULL);
}
if (sbuf.st_size < (COLLATE_STR_LEN + sizeof (info))) {
(void) close(fd);
errno = EINVAL;
- return (_LDP_ERROR);
+ return (NULL);
}
map = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
(void) close(fd);
if ((TMP = map) == NULL) {
- return (_LDP_ERROR);
+ errno = EINVAL;
+ return (NULL);
}
if (strncmp(TMP, COLLATE_VERSION, COLLATE_STR_LEN) != 0) {
(void) munmap(map, sbuf.st_size);
errno = EINVAL;
- return (_LDP_ERROR);
+ return (NULL);
}
TMP += COLLATE_STR_LEN;
@@ -130,72 +122,84 @@ _collate_load_tables(const char *encoding)
((chains = info->chain_count) < 0)) {
(void) munmap(map, sbuf.st_size);
errno = EINVAL;
- return (_LDP_ERROR);
+ return (NULL);
}
i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) +
(sizeof (collate_chain_t) * chains) +
(sizeof (collate_large_t) * info->large_count);
- for (z = 0; z < (info->directive_count); z++) {
+ for (z = 0; z < info->directive_count; z++) {
i += sizeof (collate_subst_t) * info->subst_count[z];
}
if (i != (sbuf.st_size - (TMP - map))) {
(void) munmap(map, sbuf.st_size);
errno = EINVAL;
- return (_LDP_ERROR);
+ return (NULL);
}
- char_pri_table = (void *)TMP;
+
+ if ((ldata = __locdata_alloc(locname, sizeof (*lcc))) == NULL) {
+ (void) munmap(map, sbuf.st_size);
+ return (NULL);
+ }
+ lcc = ldata->l_data[0];
+ ldata->l_map = map;
+ ldata->l_map_len = sbuf.st_size;
+
+ lcc->lc_info = info;
+ lcc->lc_directive_count = info->directive_count;
+ lcc->lc_large_count = info->large_count;
+
+ for (z = 0; z < COLL_WEIGHTS_MAX; z++) {
+ lcc->lc_directive[z] = info->directive[z];
+ lcc->lc_subst_count[z] = info->subst_count[z];
+ lcc->lc_pri_count[z] = info->pri_count[z];
+ lcc->lc_undef_pri[z] = info->undef_pri[z];
+ }
+
+ lcc->lc_char_table = (void *)TMP;
TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1);
- for (z = 0; z < info->directive_count; z++) {
- if (info->subst_count[z] > 0) {
- subst_table[z] = (void *)TMP;
- TMP += info->subst_count[z] * sizeof (collate_subst_t);
+ for (z = 0; z < lcc->lc_directive_count; z++) {
+ int count;
+ if ((count = lcc->lc_subst_count[z]) > 0) {
+ lcc->lc_subst_table[z] = (void *)TMP;
+ TMP += count * sizeof (collate_subst_t);
} else {
- subst_table[z] = NULL;
+ lcc->lc_subst_table[z] = NULL;
}
}
if (chains > 0) {
- chain_pri_table = (void *)TMP;
+ lcc->lc_chain_table = (void *)TMP;
TMP += chains * sizeof (collate_chain_t);
} else
- chain_pri_table = NULL;
- if (info->large_count > 0)
- large_pri_table = (void *)TMP;
+ lcc->lc_chain_table = NULL;
+ lcc->lc_chain_count = chains;
+ if (lcc->lc_large_count > 0)
+ lcc->lc_large_table = (void *)TMP;
else
- large_pri_table = NULL;
-
- (void) strlcpy(collate_encoding, encoding, ENCODING_LEN);
- _collate_info = info;
-
- if (cache)
- (void) munmap(cache, cachesz);
-
- cache = map;
- cachesz = sbuf.st_size;
- _collate_load_error = 0;
+ lcc->lc_large_table = NULL;
- return (_LDP_LOADED);
+ return (ldata);
}
-static int32_t *
-substsearch(const wchar_t key, int pass)
+static const int32_t *
+substsearch(const struct lc_collate *lcc, const wchar_t key, int pass)
{
- collate_subst_t *p;
- int n = _collate_info->subst_count[pass];
+ const collate_subst_t *p;
+ int n = lcc->lc_subst_count[pass];
if (n == 0)
return (NULL);
- if (pass >= _collate_info->directive_count)
+ if (pass >= lcc->lc_directive_count)
return (NULL);
if (!(key & COLLATE_SUBST_PRIORITY))
return (NULL);
- p = subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY);
+ p = lcc->lc_subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY);
assert(p->key == key);
return (p->pri);
}
@@ -206,7 +210,7 @@ substsearch(const wchar_t key, int pass)
*/
static collate_chain_t *
-chainsearch(const wchar_t *key, int *len)
+chainsearch(const struct lc_collate *lcc, const wchar_t *key, int *len)
{
int low;
int high;
@@ -214,12 +218,12 @@ chainsearch(const wchar_t *key, int *len)
collate_chain_t *p;
collate_chain_t *tab;
- if (_collate_info->chain_count == 0)
+ if (lcc->lc_info->chain_count == 0)
return (NULL);
low = 0;
- high = _collate_info->chain_count - 1;
- tab = chain_pri_table;
+ high = lcc->lc_info->chain_count - 1;
+ tab = lcc->lc_chain_table;
while (low <= high) {
next = (low + high) / 2;
@@ -242,15 +246,15 @@ chainsearch(const wchar_t *key, int *len)
}
static collate_large_t *
-largesearch(const wchar_t key)
+largesearch(const struct lc_collate *lcc, const wchar_t key)
{
int low = 0;
- int high = _collate_info->large_count - 1;
+ int high = lcc->lc_info->large_count - 1;
int next, compar;
collate_large_t *p;
- collate_large_t *tab = large_pri_table;
+ collate_large_t *tab = lcc->lc_large_table;
- if (_collate_info->large_count == 0)
+ if (lcc->lc_info->large_count == 0)
return (NULL);
while (low <= high) {
@@ -268,19 +272,19 @@ largesearch(const wchar_t key)
}
void
-_collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
+_collate_lookup(const struct lc_collate *lcc, const wchar_t *t,
+ int *len, int *pri, int which, const int **state)
{
collate_chain_t *p2;
collate_large_t *match;
- collate_info_t *info = _collate_info;
int p, l;
- int *sptr;
+ const int *sptr;
/*
* If this is the "last" pass for the UNDEFINED, then
* we just return the priority itself.
*/
- if (which >= info->directive_count) {
+ if (which >= lcc->lc_directive_count) {
*pri = *t;
*len = 1;
*state = NULL;
@@ -306,7 +310,7 @@ _collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
* Check for composites such as dipthongs that collate as a
* single element (aka chains or collating-elements).
*/
- if (((p2 = chainsearch(t, &l)) != NULL) &&
+ if (((p2 = chainsearch(lcc, t, &l)) != NULL) &&
((p = p2->pri[which]) >= 0)) {
*len = l;
@@ -318,10 +322,10 @@ _collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
* Character is a small (8-bit) character.
* We just look these up directly for speed.
*/
- *pri = char_pri_table[*t].pri[which];
+ *pri = lcc->lc_char_table[*t].pri[which];
- } else if ((info->large_count > 0) &&
- ((match = largesearch(*t)) != NULL)) {
+ } else if ((lcc->lc_info->large_count > 0) &&
+ ((match = largesearch(lcc, *t)) != NULL)) {
/*
* Character was found in the extended table.
@@ -332,11 +336,11 @@ _collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
/*
* Character lacks a specific definition.
*/
- if (info->directive[which] & DIRECTIVE_UNDEFINED) {
+ if (lcc->lc_directive[which] & DIRECTIVE_UNDEFINED) {
/* Mask off sign bit to prevent ordering confusion. */
*pri = (*t & COLLATE_MAX_PRIORITY);
} else {
- *pri = info->undef_pri[which];
+ *pri = lcc->lc_undef_pri[which];
}
/* No substitutions for undefined characters! */
return;
@@ -354,7 +358,7 @@ _collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
* to be substituted be unique for that level. The localedef
* code ensures this for us.
*/
- if ((sptr = substsearch(*pri, which)) != NULL) {
+ if ((sptr = substsearch(lcc, *pri, which)) != NULL) {
if ((*pri = *sptr) != 0) {
sptr++;
*state = *sptr ? sptr : NULL;
@@ -368,7 +372,8 @@ _collate_lookup(const wchar_t *t, int *len, int *pri, int which, int **state)
* NOT NULL terminate. That is left to the caller.
*/
size_t
-_collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room)
+_collate_wxfrm(const struct lc_collate *lcc, const wchar_t *src, wchar_t *xf,
+ size_t room)
{
int pri;
int len;
@@ -376,13 +381,14 @@ _collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room)
wchar_t *tr = NULL;
int direc;
int pass;
- int32_t *state;
+ const int32_t *state;
size_t want = 0;
size_t need = 0;
+ int ndir = lcc->lc_directive_count;
assert(src);
- for (pass = 0; pass <= _collate_info->directive_count; pass++) {
+ for (pass = 0; pass <= ndir; pass++) {
state = NULL;
@@ -396,10 +402,10 @@ _collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room)
}
/* special pass for undefined */
- if (pass == _collate_info->directive_count) {
+ if (pass == ndir) {
direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED;
} else {
- direc = _collate_info->directive[pass];
+ direc = lcc->lc_directive[pass];
}
t = src;
@@ -424,7 +430,8 @@ _collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room)
if (direc & DIRECTIVE_POSITION) {
while (*t || state) {
- _collate_lookup(t, &len, &pri, pass, &state);
+ _collate_lookup(lcc, t, &len, &pri, pass,
+ &state);
t += len;
if (pri <= 0) {
if (pri < 0) {
@@ -442,7 +449,8 @@ _collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room)
}
} else {
while (*t || state) {
- _collate_lookup(t, &len, &pri, pass, &state);
+ _collate_lookup(lcc, t, &len, &pri, pass,
+ &state);
t += len;
if (pri <= 0) {
if (pri < 0) {
@@ -497,10 +505,10 @@ fail:
#define XFRM_SEP ('.') /* chosen to be less than XFRM_OFFSET */
static int
-xfrm(unsigned char *p, int pri, int pass)
+xfrm(locale_t loc, unsigned char *p, int pri, int pass)
{
/* we use unsigned to ensure zero fill on right shift */
- uint32_t val = (uint32_t)_collate_info->pri_count[pass];
+ uint32_t val = (uint32_t)loc->collate->lc_pri_count[pass];
int nc = 0;
while (val) {
@@ -514,7 +522,7 @@ xfrm(unsigned char *p, int pri, int pass)
}
size_t
-_collate_sxfrm(const wchar_t *src, char *xf, size_t room)
+_collate_sxfrm(const wchar_t *src, char *xf, size_t room, locale_t loc)
{
int pri;
int len;
@@ -522,15 +530,17 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
wchar_t *tr = NULL;
int direc;
int pass;
- int32_t *state;
+ const int32_t *state;
size_t want = 0;
size_t need = 0;
int b;
uint8_t buf[XFRM_BYTES];
+ const struct lc_collate *lcc = loc->collate;
+ int ndir = lcc->lc_directive_count;
assert(src);
- for (pass = 0; pass <= _collate_info->directive_count; pass++) {
+ for (pass = 0; pass <= ndir; pass++) {
state = NULL;
@@ -544,10 +554,10 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
}
/* special pass for undefined */
- if (pass == _collate_info->directive_count) {
+ if (pass == ndir) {
direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED;
} else {
- direc = _collate_info->directive[pass];
+ direc = lcc->lc_directive[pass];
}
t = src;
@@ -573,7 +583,8 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
if (direc & DIRECTIVE_POSITION) {
while (*t || state) {
- _collate_lookup(t, &len, &pri, pass, &state);
+ _collate_lookup(lcc, t, &len, &pri, pass,
+ &state);
t += len;
if (pri <= 0) {
if (pri < 0) {
@@ -583,7 +594,7 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
pri = COLLATE_MAX_PRIORITY;
}
- b = xfrm(buf, pri, pass);
+ b = xfrm(loc, buf, pri, pass);
want += b;
if (room) {
while (b) {
@@ -598,7 +609,8 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
}
} else {
while (*t || state) {
- _collate_lookup(t, &len, &pri, pass, &state);
+ _collate_lookup(lcc, t, &len, &pri, pass,
+ &state);
t += len;
if (pri <= 0) {
if (pri < 0) {
@@ -608,7 +620,7 @@ _collate_sxfrm(const wchar_t *src, char *xf, size_t room)
continue;
}
- b = xfrm(buf, pri, pass);
+ b = xfrm(loc, buf, pri, pass);
want += b;
if (room) {
diff --git a/usr/src/lib/libc/port/locale/collate.h b/usr/src/lib/libc/port/locale/collate.h
index a175ce45bf..d3496be7cf 100644
--- a/usr/src/lib/libc/port/locale/collate.h
+++ b/usr/src/lib/libc/port/locale/collate.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systmes, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
@@ -31,6 +32,8 @@
#include <sys/types.h>
#include <limits.h>
+#include <locale.h>
+#include "localeimpl.h"
#define COLLATE_STR_LEN 24 /* should be 64-bit multiple */
#define COLLATE_VERSION "IllumosCollate2\n"
@@ -92,14 +95,30 @@ typedef struct collate_subst {
int32_t pri[COLLATE_STR_LEN];
} collate_subst_t;
-int _collate_load_tables(const char *);
-void _collate_lookup(const wchar_t *, int *, int *, int, int **);
-size_t _collate_wxfrm(const wchar_t *, wchar_t *, size_t);
-size_t _collate_sxfrm(const wchar_t *, char *, size_t);
-int _collate_range_cmp(wchar_t, wchar_t);
+struct lc_collate {
+ int lc_is_posix;
-extern int _collate_load_error;
-extern int _collate_substitute_nontrivial;
-extern collate_info_t *_collate_info;
+ uint8_t lc_directive_count;
+ uint8_t lc_directive[COLL_WEIGHTS_MAX];
+ int32_t lc_pri_count[COLL_WEIGHTS_MAX];
+ int32_t lc_flags;
+ int32_t lc_chain_count;
+ int32_t lc_large_count;
+ int32_t lc_subst_count[COLL_WEIGHTS_MAX];
+ int32_t lc_undef_pri[COLL_WEIGHTS_MAX];
+
+ collate_info_t *lc_info;
+ collate_char_t *lc_char_table;
+ collate_large_t *lc_large_table;
+ collate_chain_t *lc_chain_table;
+ collate_subst_t *lc_subst_table[COLL_WEIGHTS_MAX];
+};
+
+void _collate_lookup(const struct lc_collate *, const wchar_t *,
+ int *, int *, int, const int **);
+size_t _collate_wxfrm(const struct lc_collate *, const wchar_t *,
+ wchar_t *, size_t);
+size_t _collate_sxfrm(const wchar_t *, char *, size_t, locale_t);
+int _collate_range_cmp(wchar_t, wchar_t, locale_t);
#endif /* !_COLLATE_H_ */
diff --git a/usr/src/lib/libc/port/locale/collcmp.c b/usr/src/lib/libc/port/locale/collcmp.c
index 1b075f3c5f..b3ec74fd5e 100644
--- a/usr/src/lib/libc/port/locale/collcmp.c
+++ b/usr/src/lib/libc/port/locale/collcmp.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia.
* All rights reserved.
*
@@ -30,15 +31,17 @@
#include "collate.h"
/*
- * Compare two characters using collate
+ * Compare two characters using collate - thread safe.
*/
int
-_collate_range_cmp(wchar_t c1, wchar_t c2)
+_collate_range_cmp(wchar_t c1, wchar_t c2, locale_t loc)
{
- static wchar_t s1[2], s2[2];
+ wchar_t s1[2], s2[2];
s1[0] = c1;
+ s1[1] = 0;
s2[0] = c2;
- return (wcscoll(s1, s2));
+ s2[1] = 0;
+ return (wcscoll_l(s1, s2, loc));
}
diff --git a/usr/src/lib/libc/port/locale/euc.c b/usr/src/lib/libc/port/locale/euc.c
index 03126946b7..36aad83ac2 100644
--- a/usr/src/lib/libc/port/locale/euc.c
+++ b/usr/src/lib/libc/port/locale/euc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
* Copyright (c) 1993
@@ -40,8 +41,8 @@
#include <wchar.h>
#include <sys/types.h>
#include <sys/euc.h>
-#include "runetype.h"
#include "mblocal.h"
+#include "lctype.h"
static size_t _EUC_mbrtowc_impl(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -61,6 +62,7 @@ static size_t _EUC_KR_mbrtowc(wchar_t *_RESTRICT_KYWD,
static size_t _EUC_TW_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
size_t, mbstate_t *_RESTRICT_KYWD);
+
static size_t _EUC_CN_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
static size_t _EUC_JP_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
@@ -69,6 +71,33 @@ static size_t _EUC_KR_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
static size_t _EUC_TW_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+
+static size_t _EUC_CN_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_JP_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_KR_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_TW_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
+static size_t _EUC_CN_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_JP_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_KR_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _EUC_TW_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
static int _EUC_mbsinit(const mbstate_t *);
typedef struct {
@@ -77,7 +106,7 @@ typedef struct {
int want;
} _EucState;
-static int
+int
_EUC_mbsinit(const mbstate_t *ps)
{
@@ -87,18 +116,17 @@ _EUC_mbsinit(const mbstate_t *ps)
/*
* EUC-CN uses CS0, CS1 and CS2 (4 bytes).
*/
-int
-_EUC_CN_init(_RuneLocale *rl)
+void
+_EUC_CN_init(struct lc_ctype *lct)
{
- __mbrtowc = _EUC_CN_mbrtowc;
- __wcrtomb = _EUC_CN_wcrtomb;
- __mbsinit = _EUC_mbsinit;
-
- _CurrentRuneLocale = rl;
-
- __ctype[520] = 4;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _EUC_CN_mbrtowc;
+ lct->lc_wcrtomb = _EUC_CN_wcrtomb;
+ lct->lc_mbsnrtowcs = _EUC_CN_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _EUC_CN_wcsnrtombs;
+ lct->lc_mbsinit = _EUC_mbsinit;
+
+ lct->lc_max_mblen = 4;
+ lct->lc_is_ascii = 0;
}
static size_t
@@ -109,27 +137,41 @@ _EUC_CN_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
}
static size_t
+_EUC_CN_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_CN_mbrtowc));
+}
+
+static size_t
_EUC_CN_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
mbstate_t *_RESTRICT_KYWD ps)
{
return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
}
+static size_t
+_EUC_CN_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_CN_wcrtomb));
+}
+
/*
* EUC-KR uses only CS0 and CS1.
*/
-int
-_EUC_KR_init(_RuneLocale *rl)
+void
+_EUC_KR_init(struct lc_ctype *lct)
{
- __mbrtowc = _EUC_KR_mbrtowc;
- __wcrtomb = _EUC_KR_wcrtomb;
- __mbsinit = _EUC_mbsinit;
-
- _CurrentRuneLocale = rl;
-
- __ctype[520] = 2;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _EUC_KR_mbrtowc;
+ lct->lc_wcrtomb = _EUC_KR_wcrtomb;
+ lct->lc_mbsnrtowcs = _EUC_KR_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _EUC_KR_wcsnrtombs;
+ lct->lc_mbsinit = _EUC_mbsinit;
+
+ lct->lc_max_mblen = 2;
+ lct->lc_is_ascii = 0;
}
static size_t
@@ -140,27 +182,41 @@ _EUC_KR_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
}
static size_t
+_EUC_KR_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_KR_mbrtowc));
+}
+
+static size_t
_EUC_KR_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
- mbstate_t *_RESTRICT_KYWD ps)
+ mbstate_t *_RESTRICT_KYWD ps)
{
return (_EUC_wcrtomb_impl(s, wc, ps, 0, 0, 0, 0));
}
+static size_t
+_EUC_KR_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_KR_wcrtomb));
+}
+
/*
* EUC-JP uses CS0, CS1, CS2, and CS3.
*/
-int
-_EUC_JP_init(_RuneLocale *rl)
+void
+_EUC_JP_init(struct lc_ctype *lct)
{
- __mbrtowc = _EUC_JP_mbrtowc;
- __wcrtomb = _EUC_JP_wcrtomb;
- __mbsinit = _EUC_mbsinit;
-
- _CurrentRuneLocale = rl;
-
- __ctype[520] = 3;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _EUC_JP_mbrtowc;
+ lct->lc_wcrtomb = _EUC_JP_wcrtomb;
+ lct->lc_mbsnrtowcs = _EUC_JP_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _EUC_JP_wcsnrtombs;
+ lct->lc_mbsinit = _EUC_mbsinit;
+
+ lct->lc_max_mblen = 3;
+ lct->lc_is_ascii = 0;
}
static size_t
@@ -171,51 +227,80 @@ _EUC_JP_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
}
static size_t
+_EUC_JP_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_JP_mbrtowc));
+}
+
+static size_t
_EUC_JP_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
mbstate_t *_RESTRICT_KYWD ps)
{
return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 2, SS3, 3));
}
+static size_t
+_EUC_JP_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_JP_wcrtomb));
+}
+
/*
* EUC-TW uses CS0, CS1, and CS2.
*/
-int
-_EUC_TW_init(_RuneLocale *rl)
+void
+_EUC_TW_init(struct lc_ctype *lct)
{
- __mbrtowc = _EUC_TW_mbrtowc;
- __wcrtomb = _EUC_TW_wcrtomb;
- __mbsinit = _EUC_mbsinit;
-
- _CurrentRuneLocale = rl;
-
- __ctype[520] = 4;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _EUC_TW_mbrtowc;
+ lct->lc_wcrtomb = _EUC_TW_wcrtomb;
+ lct->lc_mbsnrtowcs = _EUC_TW_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _EUC_TW_wcsnrtombs;
+ lct->lc_mbsinit = _EUC_mbsinit;
+
+ lct->lc_max_mblen = 4;
+ lct->lc_is_ascii = 0;
}
static size_t
_EUC_TW_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
- size_t n, mbstate_t *_RESTRICT_KYWD ps)
+ size_t n, mbstate_t *_RESTRICT_KYWD ps)
{
return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0));
}
static size_t
+_EUC_TW_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_TW_mbrtowc));
+}
+
+static size_t
_EUC_TW_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
- mbstate_t *_RESTRICT_KYWD ps)
+ mbstate_t *_RESTRICT_KYWD ps)
{
return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0));
}
+static size_t
+_EUC_TW_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_TW_wcrtomb));
+}
+
/*
* Common EUC code.
*/
static size_t
_EUC_mbrtowc_impl(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
- size_t n, mbstate_t *_RESTRICT_KYWD ps,
- uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
+ size_t n, mbstate_t *_RESTRICT_KYWD ps,
+ uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
{
_EucState *es;
int i, want;
diff --git a/usr/src/lib/libc/port/locale/fgetwc.c b/usr/src/lib/libc/port/locale/fgetwc.c
index 6f86247132..282b65cebc 100644
--- a/usr/src/lib/libc/port/locale/fgetwc.c
+++ b/usr/src/lib/libc/port/locale/fgetwc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -35,22 +36,26 @@
#include <wchar.h>
#include "mblocal.h"
#include "stdiom.h"
+#include "localeimpl.h"
+#include "lctype.h"
/*
* Non-MT-safe version.
*/
wint_t
-_fgetwc_unlocked(FILE *fp)
+_fgetwc_unlocked_l(FILE *fp, locale_t loc)
{
wchar_t wc;
size_t nconv;
int c;
mbstate_t *statep;
+ const struct lc_ctype *lct;
if ((c = GETC(fp)) == EOF)
return (WEOF);
- if (MB_CUR_MAX == 1) {
+ lct = loc->ctype;
+ if (lct->lc_max_mblen == 1) {
/* Fast path for single-byte encodings. */
return ((wint_t)c);
}
@@ -61,7 +66,7 @@ _fgetwc_unlocked(FILE *fp)
}
do {
char x = (char)c;
- nconv = __mbrtowc(&wc, &x, 1, statep);
+ nconv = lct->lc_mbrtowc(&wc, &x, 1, statep);
if (nconv == (size_t)-1) {
break;
} else if (nconv == (size_t)-2) {
@@ -89,51 +94,64 @@ _fgetwc_unlocked(FILE *fp)
return (WEOF);
}
+wint_t
+_fgetwc_unlocked(FILE *fp)
+{
+ return (_fgetwc_unlocked_l(fp, uselocale(NULL)));
+}
+
/*
* MT safe version
*/
+#undef getwc
+#pragma weak getwc = fgetwc
wint_t
fgetwc(FILE *fp)
{
wint_t r;
rmutex_t *l;
+ locale_t loc = uselocale(NULL);
FLOCKFILE(l, fp);
- r = _fgetwc_unlocked(fp);
+ r = _fgetwc_unlocked_l(fp, loc);
FUNLOCKFILE(l);
return (r);
}
-#undef getwc
-wint_t
-getwc(FILE *fp)
-{
- return (getwc(fp));
-}
-
/*
* XPG5 version.
*/
+#undef __getwc_xpg5
+#pragma weak __getwc_xpg5 = __fgetwc_xpg5
wint_t
__fgetwc_xpg5(FILE *fp)
{
wint_t r;
rmutex_t *l;
+ locale_t loc = uselocale(NULL);
FLOCKFILE(l, fp);
if (GET_NO_MODE(fp))
_setorientation(fp, _WC_MODE);
- r = _fgetwc_unlocked(fp);
+ r = _fgetwc_unlocked_l(fp, loc);
FUNLOCKFILE(l);
return (r);
}
-#undef __getwc_xpg5
+#pragma weak getwc_l = fgetwc_l
wint_t
-__getwc_xpg5(FILE *fp)
+fgetwc_l(FILE *fp, locale_t loc)
{
- return (__fgetwc_xpg5(fp));
+ wint_t r;
+ rmutex_t *l;
+ FLOCKFILE(l, fp);
+ if (GET_NO_MODE(fp))
+ _setorientation(fp, _WC_MODE);
+ r = _fgetwc_unlocked_l(fp, loc);
+ FUNLOCKFILE(l);
+
+ return (r);
}
diff --git a/usr/src/lib/libc/port/locale/fnmatch.c b/usr/src/lib/libc/port/locale/fnmatch.c
index c218812bf2..ebea076036 100644
--- a/usr/src/lib/libc/port/locale/fnmatch.c
+++ b/usr/src/lib/libc/port/locale/fnmatch.c
@@ -31,6 +31,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,8 +57,9 @@
#include <limits.h>
#include <string.h>
#include <wchar.h>
+#include <xlocale.h>
#include <wctype.h>
-
+#include "localeimpl.h"
#include "collate.h"
#define EOS '\0'
@@ -66,23 +68,26 @@
#define RANGE_NOMATCH 0
#define RANGE_ERROR (-1)
-static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
+static int rangematch(const char *, wchar_t, int, char **, mbstate_t *,
+ locale_t);
static int fnmatch1(const char *, const char *, const char *, int, mbstate_t,
- mbstate_t);
+ mbstate_t, locale_t);
int
fnmatch(pattern, string, flags)
const char *pattern, *string;
int flags;
{
+ locale_t loc = uselocale(NULL);
static const mbstate_t initial = { 0 };
- return (fnmatch1(pattern, string, string, flags, initial, initial));
+ return (fnmatch1(pattern, string, string, flags, initial, initial,
+ loc));
}
static int
fnmatch1(const char *pattern, const char *string, const char *stringstart,
- int flags, mbstate_t patmbs, mbstate_t strmbs)
+ int flags, mbstate_t patmbs, mbstate_t strmbs, locale_t loc)
{
char *newp;
char c;
@@ -90,11 +95,11 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
size_t pclen, sclen;
for (;;) {
- pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
+ pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc);
if (pclen == (size_t)-1 || pclen == (size_t)-2)
return (FNM_NOMATCH);
pattern += pclen;
- sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs);
+ sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc);
if (sclen == (size_t)-1 || sclen == (size_t)-2) {
sc = (unsigned char)*string;
sclen = 1;
@@ -145,10 +150,10 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
/* General case, use recursion. */
while (sc != EOS) {
if (!fnmatch1(pattern, string, stringstart,
- flags, patmbs, strmbs))
+ flags, patmbs, strmbs, loc))
return (0);
- sclen = mbrtowc(&sc, string, MB_LEN_MAX,
- &strmbs);
+ sclen = mbrtowc_l(&sc, string, MB_LEN_MAX,
+ &strmbs, loc);
if (sclen == (size_t)-1 ||
sclen == (size_t)-2) {
sc = (unsigned char)*string;
@@ -172,7 +177,7 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
return (FNM_NOMATCH);
switch (rangematch(pattern, sc, flags, &newp,
- &patmbs)) {
+ &patmbs, loc)) {
case RANGE_ERROR:
goto norm;
case RANGE_MATCH:
@@ -185,8 +190,8 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
- pclen = mbrtowc(&pc, pattern, MB_LEN_MAX,
- &patmbs);
+ pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX,
+ &patmbs, loc);
if (pclen == (size_t)-1 || pclen == (size_t)-2)
return (FNM_NOMATCH);
if (pclen == 0)
@@ -200,7 +205,7 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
string += sclen;
else if ((flags & FNM_IGNORECASE) &&
- (towlower(pc) == towlower(sc)))
+ (towlower_l(pc, loc) == towlower_l(sc, loc)))
string += sclen;
else
return (FNM_NOMATCH);
@@ -212,12 +217,8 @@ fnmatch1(const char *pattern, const char *string, const char *stringstart,
}
static int
-rangematch(pattern, test, flags, newp, patmbs)
- const char *pattern;
- wchar_t test;
- int flags;
- char **newp;
- mbstate_t *patmbs;
+rangematch(const char *pattern, wchar_t test, int flags, char **newp,
+ mbstate_t *patmbs, locale_t loc)
{
int negate, ok;
wchar_t c, c2;
@@ -235,7 +236,7 @@ rangematch(pattern, test, flags, newp, patmbs)
++pattern;
if (flags & FNM_IGNORECASE)
- test = towlower(test);
+ test = towlower_l(test, loc);
/*
* A right bracket shall lose its special meaning and represent
@@ -254,20 +255,21 @@ rangematch(pattern, test, flags, newp, patmbs)
return (RANGE_NOMATCH);
} else if (*pattern == '\\' && !(flags & FNM_NOESCAPE))
pattern++;
- pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs);
+ pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc);
if (pclen == (size_t)-1 || pclen == (size_t)-2)
return (RANGE_NOMATCH);
pattern += pclen;
if (flags & FNM_IGNORECASE)
- c = towlower(c);
+ c = towlower_l(c, loc);
if (*pattern == '-' && *(pattern + 1) != EOS &&
*(pattern + 1) != ']') {
if (*++pattern == '\\' && !(flags & FNM_NOESCAPE))
if (*pattern != EOS)
pattern++;
- pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs);
+ pclen = mbrtowc_l(&c2, pattern, MB_LEN_MAX, patmbs,
+ loc);
if (pclen == (size_t)-1 || pclen == (size_t)-2)
return (RANGE_NOMATCH);
pattern += pclen;
@@ -275,12 +277,12 @@ rangematch(pattern, test, flags, newp, patmbs)
return (RANGE_ERROR);
if (flags & FNM_IGNORECASE)
- c2 = towlower(c2);
+ c2 = towlower_l(c2, loc);
- if (_collate_load_error ?
+ if (loc->collate->lc_is_posix ?
c <= test && test <= c2 :
- _collate_range_cmp(c, test) <= 0 &&
- _collate_range_cmp(test, c2) <= 0)
+ _collate_range_cmp(c, test, loc) <= 0 &&
+ _collate_range_cmp(test, c2, loc) <= 0)
ok = 1;
} else if (c == test)
ok = 1;
diff --git a/usr/src/lib/libc/port/locale/fputwc.c b/usr/src/lib/libc/port/locale/fputwc.c
index c02d7e251f..4c386adcdd 100644
--- a/usr/src/lib/libc/port/locale/fputwc.c
+++ b/usr/src/lib/libc/port/locale/fputwc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
@@ -72,8 +73,6 @@ __fputwc_impl(wchar_t wc, FILE *fp, int orient)
if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) {
/*
* Assume single-byte locale with no special encoding.
- * A more careful test would be to check
- * _CurrentRuneLocale->encoding.
*/
*buf = (unsigned char)wc;
len = 1;
diff --git a/usr/src/lib/libc/port/locale/gb18030.c b/usr/src/lib/libc/port/locale/gb18030.c
index eab6e332c2..232daade50 100644
--- a/usr/src/lib/libc/port/locale/gb18030.c
+++ b/usr/src/lib/libc/port/locale/gb18030.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins
* All rights reserved.
@@ -34,11 +35,11 @@
#include "lint.h"
#include <sys/types.h>
#include <errno.h>
-#include "runetype.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _GB18030_mbrtowc(wchar_t *_RESTRICT_KYWD,
@@ -47,24 +48,30 @@ static size_t _GB18030_mbrtowc(wchar_t *_RESTRICT_KYWD,
static int _GB18030_mbsinit(const mbstate_t *);
static size_t _GB18030_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+static size_t _GB18030_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _GB18030_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
typedef struct {
int count;
uchar_t bytes[4];
} _GB18030State;
-int
-_GB18030_init(_RuneLocale *rl)
+void
+_GB18030_init(struct lc_ctype *lct)
{
- __mbrtowc = _GB18030_mbrtowc;
- __wcrtomb = _GB18030_wcrtomb;
- __mbsinit = _GB18030_mbsinit;
- _CurrentRuneLocale = rl;
- __ctype[520] = 4;
- charset_is_ascii = 0;
-
- return (0);
+ lct->lc_mbrtowc = _GB18030_mbrtowc;
+ lct->lc_wcrtomb = _GB18030_wcrtomb;
+ lct->lc_mbsinit = _GB18030_mbsinit;
+ lct->lc_mbsnrtowcs = _GB18030_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _GB18030_wcsnrtombs;
+ lct->lc_max_mblen = 4;
+ lct->lc_is_ascii = 0;
}
static int
@@ -221,3 +228,19 @@ ilseq:
errno = EILSEQ;
return ((size_t)-1);
}
+
+static size_t
+_GB18030_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src, size_t nms, size_t len,
+ mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GB18030_mbrtowc));
+}
+
+static size_t
+_GB18030_wcsnrtombs(char *_RESTRICT_KYWD dst,
+ const wchar_t **_RESTRICT_KYWD src, size_t nwc, size_t len,
+ mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GB18030_wcrtomb));
+}
diff --git a/usr/src/lib/libc/port/locale/gb2312.c b/usr/src/lib/libc/port/locale/gb2312.c
index 4658fe3944..a25af781b4 100644
--- a/usr/src/lib/libc/port/locale/gb2312.c
+++ b/usr/src/lib/libc/port/locale/gb2312.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2004 Tim J. Robbins. All rights reserved.
* Copyright (c) 2003 David Xu <davidxu@freebsd.org>
@@ -34,6 +35,7 @@
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _GB2312_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -41,23 +43,30 @@ static size_t _GB2312_mbrtowc(wchar_t *_RESTRICT_KYWD,
static int _GB2312_mbsinit(const mbstate_t *);
static size_t _GB2312_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+static size_t _GB2312_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _GB2312_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
typedef struct {
int count;
uchar_t bytes[2];
} _GB2312State;
-int
-_GB2312_init(_RuneLocale *rl)
+void
+_GB2312_init(struct lc_ctype *lct)
{
- _CurrentRuneLocale = rl;
- __mbrtowc = _GB2312_mbrtowc;
- __wcrtomb = _GB2312_wcrtomb;
- __mbsinit = _GB2312_mbsinit;
- __ctype[520] = 2;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _GB2312_mbrtowc;
+ lct->lc_wcrtomb = _GB2312_wcrtomb;
+ lct->lc_mbsinit = _GB2312_mbsinit;
+ lct->lc_mbsnrtowcs = _GB2312_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _GB2312_wcsnrtombs;
+ lct->lc_max_mblen = 2;
+ lct->lc_is_ascii = 0;
}
static int
@@ -155,3 +164,19 @@ _GB2312_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
*s = wc & 0xff;
return (1);
}
+
+static size_t
+_GB2312_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src, size_t nms, size_t len,
+ mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GB2312_mbrtowc));
+}
+
+static size_t
+_GB2312_wcsnrtombs(char *_RESTRICT_KYWD dst,
+ const wchar_t **_RESTRICT_KYWD src, size_t nwc, size_t len,
+ mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GB2312_wcrtomb));
+}
diff --git a/usr/src/lib/libc/port/locale/gbk.c b/usr/src/lib/libc/port/locale/gbk.c
index 1d02c189a1..5c94b9954b 100644
--- a/usr/src/lib/libc/port/locale/gbk.c
+++ b/usr/src/lib/libc/port/locale/gbk.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
* Copyright (c) 1993
@@ -35,11 +36,11 @@
#include "lint.h"
#include <sys/types.h>
#include <errno.h>
-#include "runetype.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _GBK_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -47,22 +48,27 @@ static size_t _GBK_mbrtowc(wchar_t *_RESTRICT_KYWD,
static int _GBK_mbsinit(const mbstate_t *);
static size_t _GBK_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+static size_t _GBK_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _GBK_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
typedef struct {
wchar_t ch;
} _GBKState;
-int
-_GBK_init(_RuneLocale *rl)
+void
+_GBK_init(struct lc_ctype *lct)
{
-
- __mbrtowc = _GBK_mbrtowc;
- __wcrtomb = _GBK_wcrtomb;
- __mbsinit = _GBK_mbsinit;
- _CurrentRuneLocale = rl;
- __ctype[520] = 2;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _GBK_mbrtowc;
+ lct->lc_wcrtomb = _GBK_wcrtomb;
+ lct->lc_mbsinit = _GBK_mbsinit;
+ lct->lc_mbsnrtowcs = _GBK_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _GBK_wcsnrtombs;
+ lct->lc_max_mblen = 2;
+ lct->lc_is_ascii = 0;
}
static int
@@ -164,3 +170,17 @@ _GBK_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc, mbstate_t *_RESTRICT_KYWD ps)
*s = wc & 0xff;
return (1);
}
+
+static size_t
+_GBK_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GBK_mbrtowc));
+}
+
+static size_t
+_GBK_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GBK_wcrtomb));
+}
diff --git a/usr/src/lib/libc/port/locale/isdigit.c b/usr/src/lib/libc/port/locale/isdigit.c
new file mode 100644
index 0000000000..c2cae89d93
--- /dev/null
+++ b/usr/src/lib/libc/port/locale/isdigit.c
@@ -0,0 +1,91 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * This file contains the implementation of various functional forms
+ * of the ctype tests, specifically the required by ISO C. These are defined
+ * in the "C" (POSIX) locale.
+ */
+
+#include "lint.h"
+#include <ctype.h>
+#include <locale.h>
+#include "localeimpl.h"
+#include "_ctype.h"
+#include "lctype.h"
+
+/*
+ * We are supplying functional forms, so make sure to suppress any macros
+ * we might have imported.
+ */
+
+/*
+ * Performance note: ASCII test is *much* faster, as we can avoid expensive
+ * function call overhead. This is the hot case, so we try to do that
+ * whenever possible. As far as we know, *every* encoding we support
+ * is a strict superset of ASCII. So we can make things faster by trying
+ * ASCII first, and only then falling to locale specific checks.
+ */
+
+static int
+isctype_l(int c, int mask, locale_t loc)
+{
+ return ((unsigned)c > 255 ? 0 : (loc->ctype->lc_ctype_mask[c] & mask));
+}
+
+#define ISTYPE_L(c, mask, loc) \
+ (isascii(c) ? (__ctype_mask[c] & (mask)) : isctype_l(c, mask, loc))
+
+#define ISTYPE(c, mask) ISTYPE_L(c, mask, uselocale(NULL))
+
+#define DEFN_ISTYPE(type, mask) \
+int \
+is##type##_l(int c, locale_t l) \
+{ \
+ return (ISTYPE_L(c, mask, l)); \
+} \
+ \
+int \
+is##type(int c) \
+{ \
+ return (ISTYPE(c, mask)); \
+}
+
+#undef isblank
+#undef isupper
+#undef islower
+#undef isdigit
+#undef isxdigit
+#undef isalpha
+#undef isalnum
+#undef isspace
+#undef iscntrl
+#undef isgraph
+#undef ispunct
+#undef isprint
+
+DEFN_ISTYPE(blank, _ISBLANK)
+DEFN_ISTYPE(upper, _ISUPPER)
+DEFN_ISTYPE(lower, _ISLOWER)
+DEFN_ISTYPE(digit, _ISDIGIT)
+DEFN_ISTYPE(xdigit, _ISXDIGIT)
+DEFN_ISTYPE(alpha, _ISALPHA)
+DEFN_ISTYPE(alnum, _ISALNUM)
+DEFN_ISTYPE(space, _ISSPACE)
+DEFN_ISTYPE(cntrl, _ISCNTRL)
+DEFN_ISTYPE(graph, _ISGRAPH)
+DEFN_ISTYPE(punct, _ISPUNCT)
+DEFN_ISTYPE(print, _ISPRINT)
diff --git a/usr/src/lib/libc/port/locale/iswctype.c b/usr/src/lib/libc/port/locale/iswctype.c
index c387a0cdae..1698113ace 100644
--- a/usr/src/lib/libc/port/locale/iswctype.c
+++ b/usr/src/lib/libc/port/locale/iswctype.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -38,178 +39,133 @@
#include "lint.h"
#include <wctype.h>
+#include <locale.h>
#include "runefile.h"
#include "runetype.h"
+#include "localeimpl.h"
#include "_ctype.h"
/*
- * We removed: iswascii, iswhexnumber, and iswnumber, as
- * these are not present on Solaris. Note that the standard requires
- * iswascii to be a macro, so it is defined in our headers.
+ * Note that the standard requires iswascii to be a macro, so it is defined
+ * in our headers.
*
- * We renamed (per Solaris) iswideogram, iswspecial, iswspecial to the
- * equivalent values without "w". We added a new isnumber, that looks
- * for non-ASCII numbers.
+ * We aliased (per Solaris) iswideogram, iswspecial, iswspecial to the
+ * equivalent values without "w". The Solaris specific function isenglish()
+ * is here, but does not get an isw* equivalent.
+ *
+ * Note that various code assumes that "numbers" (iswdigit, iswxdigit)
+ * only return true for characters in the portable set. While the assumption
+ * is not technically correct, it turns out that for all of our locales this
+ * is true. iswhexnumber is aliased to iswxdigit.
*/
static int
-__istype(wint_t c, unsigned int f)
+__istype_l(locale_t loc, wint_t c, unsigned int f)
{
unsigned int rt;
- /* Fast path for single byte locales */
if (c < 0 || c >= _CACHED_RUNES)
- rt = ___runetype(c);
+ rt = __runetype(loc->runelocale, c);
else
- rt = _CurrentRuneLocale->__runetype[c];
+ rt = loc->runelocale->__runetype[c];
return (rt & f);
}
static int
-__isctype(wint_t c, unsigned int f)
+__istype(wint_t c, unsigned int f)
{
- unsigned int rt;
+ return (__istype_l(uselocale(NULL), c, f));
+}
- /* Fast path for single byte locales */
- if (c < 0 || c >= _CACHED_RUNES)
- return (0);
- else
- rt = _CurrentRuneLocale->__runetype[c];
- return (rt & f);
+int
+iswctype_l(wint_t wc, wctype_t class, locale_t loc)
+{
+ if (iswascii(wc))
+ return (__ctype_mask[wc] & class);
+ return (__istype_l(loc, wc, class));
}
#undef iswctype
int
iswctype(wint_t wc, wctype_t class)
{
+ /*
+ * Note that we don't just call iswctype_l because we optimize for
+ * the iswascii() case, so that most of the time we have no need to
+ * call uselocale().
+ */
+ if (iswascii(wc))
+ return (__ctype_mask[wc] & class);
return (__istype(wc, class));
}
+/*
+ * This is a legacy version, baked into binaries.
+ */
#undef _iswctype
unsigned
_iswctype(wchar_t wc, int class)
{
+ if (iswascii(wc))
+ return (__ctype_mask[wc] & class);
return (__istype((wint_t)wc, (unsigned int)class));
}
-#undef iswalnum
-int
-iswalnum(wint_t wc)
-{
- return (__istype(wc, _CTYPE_A|_CTYPE_D));
-}
-
-#undef iswalpha
-int
-iswalpha(wint_t wc)
-{
- return (__istype(wc, _CTYPE_A));
-}
-
-#undef iswblank
-int
-iswblank(wint_t wc)
-{
- return (__istype(wc, _CTYPE_B));
-}
-
-#undef iswcntrl
-int
-iswcntrl(wint_t wc)
-{
- return (__istype(wc, _CTYPE_C));
-}
-
-#undef iswdigit
-int
-iswdigit(wint_t wc)
-{
- return (__isctype(wc, _CTYPE_D));
-}
-
-#undef iswgraph
-int
-iswgraph(wint_t wc)
-{
- return (__istype(wc, _CTYPE_G));
-}
+#define DEFN_ISWTYPE(type, mask) \
+int \
+isw##type##_l(wint_t wc, locale_t loc) \
+{ \
+ return (iswascii(wc) ? \
+ (__ctype_mask[wc] & (mask)) : \
+ __istype_l(loc, wc, mask)); \
+} \
+ \
+int \
+isw##type(wint_t wc) \
+{ \
+ return (iswascii(wc) ? \
+ (__ctype_mask[wc] & (mask)) : \
+ __istype(wc, mask)); \
+}
+
+/* kill off any macros */
+#undef iswalnum
+#undef iswalpha
+#undef iswblank
+
+DEFN_ISWTYPE(alnum, _CTYPE_A|_CTYPE_D)
+DEFN_ISWTYPE(alpha, _CTYPE_A)
+DEFN_ISWTYPE(blank, _CTYPE_B)
+DEFN_ISWTYPE(cntrl, _CTYPE_C)
+DEFN_ISWTYPE(digit, _CTYPE_D)
+DEFN_ISWTYPE(graph, _CTYPE_D)
+DEFN_ISWTYPE(lower, _CTYPE_L)
+DEFN_ISWTYPE(upper, _CTYPE_U)
+DEFN_ISWTYPE(print, _CTYPE_R)
+DEFN_ISWTYPE(punct, _CTYPE_P)
+DEFN_ISWTYPE(space, _CTYPE_S)
+DEFN_ISWTYPE(xdigit, _CTYPE_X)
+DEFN_ISWTYPE(ideogram, _CTYPE_I)
+DEFN_ISWTYPE(phonogram, _CTYPE_Q)
+DEFN_ISWTYPE(special, _CTYPE_T)
+DEFN_ISWTYPE(number, _CTYPE_N)
+
+
+#undef iswhexnumber
+#pragma weak iswhexnumber = iswxdigit
+#pragma weak iswhexnumber_l = iswxdigit_l
#undef isideogram
-int
-isideogram(wint_t wc)
-{
- return (__istype(wc, _CTYPE_I));
-}
-
-#undef iswlower
-int
-iswlower(wint_t wc)
-{
- return (__istype(wc, _CTYPE_L));
-}
+#pragma weak isideogram = iswideogram
#undef isphonogram
-int
-isphonogram(wint_t wc)
-{
- return (__istype(wc, _CTYPE_Q));
-}
-
-#undef iswprint
-int
-iswprint(wint_t wc)
-{
- return (__istype(wc, _CTYPE_R));
-}
-
-#undef iswpunct
-int
-iswpunct(wint_t wc)
-{
- return (__istype(wc, _CTYPE_P));
-}
-
-#undef iswspace
-int
-iswspace(wint_t wc)
-{
- return (__istype(wc, _CTYPE_S));
-}
-
-#undef iswupper
-int
-iswupper(wint_t wc)
-{
- return (__istype(wc, _CTYPE_U));
-}
-
-#undef iswxdigit
-int
-iswxdigit(wint_t wc)
-{
- return (__isctype(wc, _CTYPE_X));
-}
-
-#undef isenglish
-int
-isenglish(wint_t wc)
-{
- return (__istype(wc, _CTYPE_E));
-}
+#pragma weak isphonogram = iswphonogram
#undef isspecial
-int
-isspecial(wint_t wc)
-{
- return (__istype(wc, _CTYPE_T));
-}
+#pragma weak isspecial = iswspecial
#undef isnumber
-int
-isnumber(wint_t wc)
-{
- return (__istype(wc, _CTYPE_N));
-}
+#pragma weak isnumber = iswnumber
/*
* FreeBSD has iswrune() for use by external programs, and this is used by
@@ -228,6 +184,21 @@ __iswrune(wint_t wc)
* ctype values differently. We can't do that (ctype is baked into
* applications), but instead can just check if *any* bit is set in
* the ctype. Any bit being set indicates its a valid rune.
+ *
+ * NB: For ASCII all positions except NULL are runes.
*/
- return (__istype(wc, 0xffffffffU));
+ return (wc == 0 ? 0 : iswascii(wc) ? 1 : __istype(wc, 0xffffffffU));
+}
+
+/*
+ * isenglish is a Solaris legacy. No isw* equivalent. Note that this most
+ * likely doesn't work, as the locale data we have doesn't include it. It
+ * specifically is only valid for non-ASCII characters. We're not sure this
+ * is in actual use in the wild.
+ */
+#undef isenglish
+int
+isenglish(wint_t wc)
+{
+ return (__istype(wc, _CTYPE_E));
}
diff --git a/usr/src/lib/libc/port/locale/lctype.h b/usr/src/lib/libc/port/locale/lctype.h
new file mode 100644
index 0000000000..25652da1d4
--- /dev/null
+++ b/usr/src/lib/libc/port/locale/lctype.h
@@ -0,0 +1,66 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
+
+#ifndef _LCTYPE_H_
+#define _LCTYPE_H_
+
+#include <wchar.h>
+
+/* private LC_CTYPE related structures */
+
+/* encoding callbacks */
+struct lc_ctype {
+
+ size_t (*lc_mbrtowc)(wchar_t *_RESTRICT_KYWD,
+ const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
+
+ int (*lc_mbsinit)(const mbstate_t *);
+
+ size_t (*lc_mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
+ size_t (*lc_wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
+ mbstate_t *_RESTRICT_KYWD);
+
+ size_t (*lc_wcsnrtombs)(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+
+ unsigned char lc_is_ascii;
+ unsigned char lc_max_mblen;
+
+ const int *lc_trans_upper;
+ const int *lc_trans_lower;
+ const unsigned *lc_ctype_mask;
+};
+
+/*
+ * Default implementation (C locale, i.e. ASCII).
+ */
+size_t __mbrtowc_ascii(wchar_t *_RESTRICT_KYWD,
+ const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
+int __mbsinit_ascii(const mbstate_t *);
+size_t __mbsnrtowcs_ascii(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src, size_t nms, size_t len,
+ mbstate_t *_RESTRICT_KYWD);
+size_t __wcrtomb_ascii(char *_RESTRICT_KYWD, wchar_t,
+ mbstate_t *_RESTRICT_KYWD);
+size_t __wcsnrtombs_ascii(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD,
+ size_t, size_t, mbstate_t *_RESTRICT_KYWD);
+
+
+#endif /* !_LCTYPE_H_ */
diff --git a/usr/src/lib/libc/port/locale/ldpart.c b/usr/src/lib/libc/port/locale/ldpart.c
index 6ae51a9423..e0dfc35c9b 100644
--- a/usr/src/lib/libc/port/locale/ldpart.c
+++ b/usr/src/lib/libc/port/locale/ldpart.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
@@ -37,13 +38,14 @@
#include <unistd.h>
#include <stdio.h>
+#include "libc.h"
#include "ldpart.h"
#include "setlocale.h"
static int split_lines(char *, const char *);
int
-__part_load_locale(const char *name, int *using_locale,
+__part_load_locale(const char *name,
char **locale_buf, const char *category_filename,
int locale_buf_size_max, int locale_buf_size_min,
const char **dst_localebuf)
@@ -55,20 +57,6 @@ __part_load_locale(const char *name, int *using_locale,
struct stat st;
size_t namesize, bufsize;
- /* 'name' must be already checked. */
- if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) {
- *using_locale = 0;
- return (_LDP_CACHE);
- }
-
- /*
- * If the locale name is the same as our cache, use the cache.
- */
- if (*locale_buf != NULL && strcmp(name, *locale_buf) == 0) {
- *using_locale = 1;
- return (_LDP_CACHE);
- }
-
/*
* Slurp the locale file into the cache.
*/
@@ -88,7 +76,7 @@ __part_load_locale(const char *name, int *using_locale,
goto bad_locale;
}
bufsize = namesize + st.st_size;
- if ((lbuf = malloc(bufsize)) == NULL) {
+ if ((lbuf = libc_malloc(bufsize)) == NULL) {
errno = ENOMEM;
goto bad_locale;
}
@@ -117,14 +105,11 @@ __part_load_locale(const char *name, int *using_locale,
/*
* Record the successful parse in the cache.
*/
- if (*locale_buf != NULL)
- free(*locale_buf);
*locale_buf = lbuf;
for (p = *locale_buf, i = 0; i < num_lines; i++)
dst_localebuf[i] = (p += strlen(p) + 1);
for (i = num_lines; i < locale_buf_size_max; i++)
dst_localebuf[i] = NULL;
- *using_locale = 1;
return (_LDP_LOADED);
diff --git a/usr/src/lib/libc/port/locale/ldpart.h b/usr/src/lib/libc/port/locale/ldpart.h
index 040640237e..ba877de4b8 100644
--- a/usr/src/lib/libc/port/locale/ldpart.h
+++ b/usr/src/lib/libc/port/locale/ldpart.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
*
@@ -31,7 +32,7 @@
#define _LDP_ERROR (-1)
#define _LDP_CACHE 1
-int __part_load_locale(const char *, int *, char **, const char *,
+int __part_load_locale(const char *, char **, const char *,
int, int, const char **);
#endif /* !_LDPART_H_ */
diff --git a/usr/src/lib/libc/port/locale/lmessages.c b/usr/src/lib/libc/port/locale/lmessages.c
index 1cb83e0ac8..f15e143172 100644
--- a/usr/src/lib/libc/port/locale/lmessages.c
+++ b/usr/src/lib/libc/port/locale/lmessages.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
@@ -27,47 +28,54 @@
#include "lint.h"
#include <stddef.h>
+#include <errno.h>
#include "ldpart.h"
#include "lmessages.h"
+#include "localeimpl.h"
-#define LCMESSAGES_SIZE_FULL (sizeof (struct lc_messages_T) / sizeof (char *))
+#define LCMESSAGES_SIZE_FULL (sizeof (struct lc_messages) / sizeof (char *))
#define LCMESSAGES_SIZE_MIN \
- (offsetof(struct lc_messages_T, yesstr) / sizeof (char *))
+ (offsetof(struct lc_messages, yesstr) / sizeof (char *))
static char empty[] = "";
-static const struct lc_messages_T _C_messages_locale = {
+struct lc_messages lc_messages_posix = {
"^[yY]", /* yesexpr */
"^[nN]", /* noexpr */
"yes", /* yesstr */
"no" /* nostr */
};
-static struct lc_messages_T _messages_locale;
-static int _messages_using_locale;
-static char *_messages_locale_buf;
+struct locdata __posix_messages_locdata = {
+ .l_lname = "C",
+ .l_data = { &lc_messages_posix }
+};
-int
-__messages_load_locale(const char *name)
+struct locdata *
+__lc_messages_load(const char *name)
{
+ struct locdata *ldata;
+ struct lc_messages *lmsgs;
int ret;
- ret = __part_load_locale(name, &_messages_using_locale,
- &_messages_locale_buf, "LC_MESSAGES",
- LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN,
- (const char **)&_messages_locale);
- if (ret == _LDP_LOADED) {
- if (_messages_locale.yesstr == NULL)
- _messages_locale.yesstr = empty;
- if (_messages_locale.nostr == NULL)
- _messages_locale.nostr = empty;
+ if ((ldata = __locdata_alloc(name, sizeof (*lmsgs))) == NULL)
+ return (NULL);
+ lmsgs = ldata->l_data[0];
+
+ ret = __part_load_locale(name, (char **)&ldata->l_data[1],
+ "LC_MESSAGES", LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN,
+ (const char **)lmsgs);
+
+ if (ret != _LDP_LOADED) {
+ __locdata_free(ldata);
+ errno = EINVAL;
+ return (NULL);
}
- return (ret);
-}
-struct lc_messages_T *
-__get_current_messages_locale(void)
-{
- return (_messages_using_locale ? &_messages_locale :
- (struct lc_messages_T *)&_C_messages_locale);
+ if (lmsgs->yesstr == NULL)
+ lmsgs->yesstr = empty;
+ if (lmsgs->nostr == NULL)
+ lmsgs->nostr = empty;
+
+ return (ldata);
}
diff --git a/usr/src/lib/libc/port/locale/lmessages.h b/usr/src/lib/libc/port/locale/lmessages.h
index e08198b810..a26bc224b9 100644
--- a/usr/src/lib/libc/port/locale/lmessages.h
+++ b/usr/src/lib/libc/port/locale/lmessages.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
*
@@ -27,14 +28,11 @@
#ifndef _LMESSAGES_H_
#define _LMESSAGES_H_
-struct lc_messages_T {
+struct lc_messages {
const char *yesexpr;
const char *noexpr;
const char *yesstr;
const char *nostr;
};
-struct lc_messages_T *__get_current_messages_locale(void);
-int __messages_load_locale(const char *);
-
#endif /* !_LMESSAGES_H_ */
diff --git a/usr/src/lib/libc/port/locale/lmonetary.c b/usr/src/lib/libc/port/locale/lmonetary.c
index 051a6b4d6c..623abc6281 100644
--- a/usr/src/lib/libc/port/locale/lmonetary.c
+++ b/usr/src/lib/libc/port/locale/lmonetary.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
@@ -29,20 +30,24 @@
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "libc.h"
#include "ldpart.h"
#include "lmonetary.h"
+#include "localeimpl.h"
-extern int __mlocale_changed;
extern const char *__fix_locale_grouping_str(const char *);
-#define LCMONETARY_SIZE_FULL (sizeof (struct lc_monetary_T) / sizeof (char *))
+#define LCMONETARY_SIZE_FULL (sizeof (struct lc_monetary) / sizeof (char *))
#define LCMONETARY_SIZE_MIN \
- (offsetof(struct lc_monetary_T, int_p_cs_precedes) / sizeof (char *))
+ (offsetof(struct lc_monetary, int_p_cs_precedes) / sizeof (char *))
static char empty[] = "";
static char numempty[] = { CHAR_MAX, '\0' };
-static const struct lc_monetary_T _C_monetary_locale = {
+struct lc_monetary lc_monetary_posix = {
empty, /* int_curr_symbol */
empty, /* currency_symbol */
empty, /* mon_decimal_point */
@@ -63,12 +68,14 @@ static const struct lc_monetary_T _C_monetary_locale = {
numempty, /* int_p_sep_by_space */
numempty, /* int_n_sep_by_space */
numempty, /* int_p_sign_posn */
- numempty /* int_n_sign_posn */
+ numempty, /* int_n_sign_posn */
+ empty /* crncystr */
};
-static struct lc_monetary_T _monetary_locale;
-static int _monetary_using_locale;
-static char *_monetary_locale_buf;
+struct locdata __posix_monetary_locdata = {
+ .l_lname = "C",
+ .l_data = { &lc_monetary_posix }
+};
static char
cnv(const char *str)
@@ -80,59 +87,93 @@ cnv(const char *str)
return ((char)i);
}
-int
-__monetary_load_locale(const char *name)
+struct locdata *
+__lc_monetary_load(const char *name)
{
int ret;
+ int clen;
+ struct lc_monetary *lmon;
+ struct locdata *ldata;
+
+ if ((ldata = __locdata_alloc(name, sizeof (*lmon))) == NULL) {
+ return (NULL);
+ }
+ lmon = ldata->l_data[0];
+
+ ret = __part_load_locale(name, (char **)&ldata->l_data[1],
+ "LC_MONETARY", LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN,
+ (const char **)lmon);
+
+ if (ret != _LDP_LOADED) {
+ __locdata_free(ldata);
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* special storage for currency string */
+ clen = strlen(lmon->currency_symbol) + 2;
+ ldata->l_data[2] = libc_malloc(clen);
+ lmon->crncystr = ldata->l_data[2];
- ret = __part_load_locale(name, &_monetary_using_locale,
- &_monetary_locale_buf, "LC_MONETARY",
- LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN,
- (const char **)&_monetary_locale);
- if (ret != _LDP_ERROR)
- __mlocale_changed = 1;
- if (ret == _LDP_LOADED) {
- _monetary_locale.mon_grouping =
- __fix_locale_grouping_str(_monetary_locale.mon_grouping);
+ lmon->mon_grouping = __fix_locale_grouping_str(lmon->mon_grouping);
#define M_ASSIGN_CHAR(NAME) \
- (((char *)_monetary_locale.NAME)[0] = \
- cnv(_monetary_locale.NAME))
-
- M_ASSIGN_CHAR(int_frac_digits);
- M_ASSIGN_CHAR(frac_digits);
- M_ASSIGN_CHAR(p_cs_precedes);
- M_ASSIGN_CHAR(p_sep_by_space);
- M_ASSIGN_CHAR(n_cs_precedes);
- M_ASSIGN_CHAR(n_sep_by_space);
- M_ASSIGN_CHAR(p_sign_posn);
- M_ASSIGN_CHAR(n_sign_posn);
-
- /*
- * The six additional C99 international monetary formatting
- * parameters default to the national parameters when
- * reading FreeBSD LC_MONETARY data files.
- */
-#define M_ASSIGN_ICHAR(NAME) \
- if (_monetary_locale.int_##NAME == NULL) \
- _monetary_locale.int_##NAME = \
- _monetary_locale.NAME; \
- else \
- M_ASSIGN_CHAR(int_##NAME);
-
- M_ASSIGN_ICHAR(p_cs_precedes);
- M_ASSIGN_ICHAR(n_cs_precedes);
- M_ASSIGN_ICHAR(p_sep_by_space);
- M_ASSIGN_ICHAR(n_sep_by_space);
- M_ASSIGN_ICHAR(p_sign_posn);
- M_ASSIGN_ICHAR(n_sign_posn);
+ (((char *)lmon->NAME)[0] = cnv(lmon->NAME))
+
+ M_ASSIGN_CHAR(int_frac_digits);
+ M_ASSIGN_CHAR(frac_digits);
+ M_ASSIGN_CHAR(p_cs_precedes);
+ M_ASSIGN_CHAR(p_sep_by_space);
+ M_ASSIGN_CHAR(n_cs_precedes);
+ M_ASSIGN_CHAR(n_sep_by_space);
+ M_ASSIGN_CHAR(p_sign_posn);
+ M_ASSIGN_CHAR(n_sign_posn);
+
+ /*
+ * The six additional C99 international monetary formatting
+ * parameters default to the national parameters when
+ * reading FreeBSD LC_MONETARY data files.
+ */
+#define M_ASSIGN_ICHAR(NAME) \
+ if (lmon->int_##NAME == NULL) \
+ lmon->int_##NAME = lmon->NAME; \
+ else \
+ M_ASSIGN_CHAR(int_##NAME);
+
+ M_ASSIGN_ICHAR(p_cs_precedes);
+ M_ASSIGN_ICHAR(n_cs_precedes);
+ M_ASSIGN_ICHAR(p_sep_by_space);
+ M_ASSIGN_ICHAR(n_sep_by_space);
+ M_ASSIGN_ICHAR(p_sign_posn);
+ M_ASSIGN_ICHAR(n_sign_posn);
+
+ /*
+ * Now calculate the currency string (CRNCYSTR) for nl_langinfo.
+ * This is a legacy SUSv2 interface.
+ */
+ if ((lmon->p_cs_precedes[0] == lmon->n_cs_precedes[0]) &&
+ (lmon->currency_symbol[0] != '\0')) {
+ char sign = '\0';
+ switch (lmon->p_cs_precedes[0]) {
+ case 0:
+ sign = '-';
+ break;
+ case 1:
+ sign = '+';
+ break;
+ case CHAR_MAX:
+ /*
+ * Substitute currency string for radix character.
+ * To the best of my knowledge, no locale uses this.
+ */
+ if (strcmp(lmon->mon_decimal_point,
+ lmon->currency_symbol) == 0)
+ sign = '.';
+ break;
+ }
+ (void) snprintf(lmon->crncystr, clen, "%c%s", sign,
+ lmon->currency_symbol);
}
- return (ret);
-}
-struct lc_monetary_T *
-__get_current_monetary_locale(void)
-{
- return (_monetary_using_locale ? &_monetary_locale :
- (struct lc_monetary_T *)&_C_monetary_locale);
+ return (ldata);
}
diff --git a/usr/src/lib/libc/port/locale/lmonetary.h b/usr/src/lib/libc/port/locale/lmonetary.h
index ac7624fd30..5e97d64c10 100644
--- a/usr/src/lib/libc/port/locale/lmonetary.h
+++ b/usr/src/lib/libc/port/locale/lmonetary.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
*
@@ -27,7 +28,7 @@
#ifndef _LMONETARY_H_
#define _LMONETARY_H_
-struct lc_monetary_T {
+struct lc_monetary {
const char *int_curr_symbol;
const char *currency_symbol;
const char *mon_decimal_point;
@@ -49,9 +50,9 @@ struct lc_monetary_T {
const char *int_n_sep_by_space;
const char *int_p_sign_posn;
const char *int_n_sign_posn;
+ char *crncystr; /* nl_langinfo */
};
-struct lc_monetary_T *__get_current_monetary_locale(void);
int __monetary_load_locale(const char *);
#endif /* !_LMONETARY_H_ */
diff --git a/usr/src/lib/libc/port/locale/lnumeric.c b/usr/src/lib/libc/port/locale/lnumeric.c
index f887cf31ff..e5a1c08e9b 100644
--- a/usr/src/lib/libc/port/locale/lnumeric.c
+++ b/usr/src/lib/libc/port/locale/lnumeric.c
@@ -1,4 +1,5 @@
/*
+ * 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.
@@ -27,59 +28,57 @@
#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_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.
+ */
+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];
+
+ ret = __part_load_locale(name, (char **)&ldata->l_data[1],
+ "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE, (const char **)lnum);
- __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;
+ if (ret != _LDP_LOADED) {
+ __locdata_free(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);
}
diff --git a/usr/src/lib/libc/port/locale/lnumeric.h b/usr/src/lib/libc/port/locale/lnumeric.h
index 74cac4dfa2..eda7fcb4cd 100644
--- a/usr/src/lib/libc/port/locale/lnumeric.h
+++ b/usr/src/lib/libc/port/locale/lnumeric.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
*
@@ -27,13 +28,10 @@
#ifndef _LNUMERIC_H_
#define _LNUMERIC_H_
-struct lc_numeric_T {
+struct lc_numeric {
const char *decimal_point;
const char *thousands_sep;
const char *grouping;
};
-struct lc_numeric_T *__get_current_numeric_locale(void);
-int __numeric_load_locale(const char *);
-
#endif /* !_LNUMERIC_H_ */
diff --git a/usr/src/lib/libc/port/locale/localeconv.c b/usr/src/lib/libc/port/locale/localeconv.c
index f2ad7f5559..0a36321870 100644
--- a/usr/src/lib/libc/port/locale/localeconv.c
+++ b/usr/src/lib/libc/port/locale/localeconv.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* Copyright (c) 1991, 1993
@@ -37,35 +38,37 @@
#include <locale.h>
#include "lmonetary.h"
#include "lnumeric.h"
+#include "localeimpl.h"
/*
- * The localeconv() function constructs a struct lconv from the current
- * monetary and numeric locales.
+ * Return the current locale conversion.
+ *
+ * Note that XPG7 specifically states that localeconv's return value may
+ * be invalidated if the application calls setlocale() or uselocale() within
+ * the same thread.
*
* Because localeconv() may be called many times (especially by library
* routines like printf() & strtod()), the approprate members of the
* lconv structure are computed only when the monetary or numeric
* locale has been changed.
*/
-int __mlocale_changed = 1;
-int __nlocale_changed = 1;
-
-/*
- * Return the current locale conversion.
- */
struct lconv *
localeconv(void)
{
- static struct lconv ret;
+ struct lconv *lconv;
+ locale_t loc;
+ struct lc_monetary *mptr;
+ struct lc_numeric *nptr;
+
+ loc = uselocale(NULL);
+ lconv = &loc->lconv;
- if (__mlocale_changed) {
- /* LC_MONETARY part */
- struct lc_monetary_T *mptr;
+ if (loc->loaded[LC_MONETARY] == 0) {
+ mptr = loc->locdata[LC_MONETARY]->l_data[0];
-#define M_ASSIGN_STR(NAME) (ret.NAME = (char *)mptr->NAME)
-#define M_ASSIGN_CHAR(NAME) (ret.NAME = mptr->NAME[0])
+#define M_ASSIGN_STR(NAME) (lconv->NAME = (char *)mptr->NAME)
+#define M_ASSIGN_CHAR(NAME) (lconv->NAME = mptr->NAME[0])
- mptr = __get_current_monetary_locale();
M_ASSIGN_STR(int_curr_symbol);
M_ASSIGN_STR(currency_symbol);
M_ASSIGN_STR(mon_decimal_point);
@@ -87,21 +90,19 @@ localeconv(void)
M_ASSIGN_CHAR(int_n_sep_by_space);
M_ASSIGN_CHAR(int_p_sign_posn);
M_ASSIGN_CHAR(int_n_sign_posn);
- __mlocale_changed = 0;
+ loc->loaded[LC_MONETARY] = 1;
}
- if (__nlocale_changed) {
- /* LC_NUMERIC part */
- struct lc_numeric_T *nptr;
+ if (loc->loaded[LC_NUMERIC] == 0) {
+ nptr = loc->locdata[LC_NUMERIC]->l_data[0];
-#define N_ASSIGN_STR(NAME) (ret.NAME = (char *)nptr->NAME)
+#define N_ASSIGN_STR(NAME) (lconv->NAME = (char *)nptr->NAME)
- nptr = __get_current_numeric_locale();
N_ASSIGN_STR(decimal_point);
N_ASSIGN_STR(thousands_sep);
N_ASSIGN_STR(grouping);
- __nlocale_changed = 0;
+ loc->loaded[LC_NUMERIC] = 1;
}
- return (&ret);
+ return (lconv);
}
diff --git a/usr/src/lib/libc/port/locale/localeimpl.c b/usr/src/lib/libc/port/locale/localeimpl.c
new file mode 100644
index 0000000000..a7be44a31b
--- /dev/null
+++ b/usr/src/lib/libc/port/locale/localeimpl.c
@@ -0,0 +1,537 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
+/*
+ * This file implements the 2008 newlocale and friends handling.
+ */
+
+#ifndef _LCONV_C99
+#define _LCONV_C99
+#endif
+
+#include "lint.h"
+#include <atomic.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+#include "libc.h"
+#include "mtlib.h"
+#include "tsd.h"
+#include "localeimpl.h"
+#include "lctype.h"
+
+/*
+ * Big Theory of Locales:
+ *
+ * (It is recommended that readers familiarize themselves with the POSIX
+ * 2008 (XPG Issue 7) specifications for locales, first.)
+ *
+ * Historically, we had a bunch of global variables that stored locale
+ * data. While this worked well, it limited applications to a single locale
+ * at a time. This doesn't work well in certain server applications.
+ *
+ * Issue 7, X/Open introduced the concept of a locale_t object, along with
+ * versions of functions that can take this object as a parameter, along
+ * with functions to clone and manipulate these locale objects. The new
+ * functions are named with a _l() suffix.
+ *
+ * Additionally uselocale() is introduced which can change the locale of
+ * of a single thread. However, setlocale() can still be used to change
+ * the global locale.
+ *
+ * In our implementation, we use libc's TSD to store the locale data that
+ * was previously global. We still have global data because some applications
+ * have had those global objects compiled into them. (Such applications will
+ * be unable to benefit from uselocale(), btw.) The legacy routines are
+ * reimplemented as wrappers that use the appropriate locale object by
+ * calling uselocale(). uselocale() when passed a NULL pointer returns the
+ * thread-specific locale object if one is present, or the global locale
+ * object otherwise. Note that once the TSD data is set, the only way
+ * to revert to the global locale is to pass the global locale LC_GLOBAL_LOCALE
+ * to uselocale().
+ *
+ * We are careful to minimize performance impact of multiple calls to
+ * uselocale() or setlocale() by using a cache of locale data whenever possible.
+ * As a consequence of this, applications that iterate over all possible
+ * locales will burn through a lot of virtual memory, but we find such
+ * applications rare. (locale -a might be an exception, but it is short lived.)
+ *
+ * Category data is never released (although enclosing locale objects might be),
+ * in order to guarantee thread-safety. Calling freelocale() on an object
+ * while it is in use by another thread is a programmer error (use-after-free)
+ * and we don't bother to note it further.
+ *
+ * Locale objects (global locales) established by setlocale() are also
+ * never freed (for MT safety), but we will save previous locale objects
+ * and reuse them when we can.
+ */
+
+typedef struct locdata *(*loadfn_t)(const char *);
+
+static const loadfn_t loaders[LC_ALL] = {
+ __lc_ctype_load,
+ __lc_numeric_load,
+ __lc_time_load,
+ __lc_collate_load,
+ __lc_monetary_load,
+ __lc_messages_load,
+};
+
+extern struct lc_monetary lc_monetary_posix;
+extern struct lc_numeric lc_numeric_posix;
+extern struct lc_messages lc_messages_posix;
+extern struct lc_time lc_time_posix;
+extern struct lc_ctype lc_ctype_posix;
+extern struct lc_collate lc_collate_posix;
+
+static struct locale posix_locale = {
+ /* locdata */
+ .locdata = {
+ &__posix_ctype_locdata,
+ &__posix_numeric_locdata,
+ &__posix_time_locdata,
+ &__posix_collate_locdata,
+ &__posix_monetary_locdata,
+ &__posix_messages_locdata,
+ },
+ .locname = "C",
+ .ctype = &lc_ctype_posix,
+ .numeric = &lc_numeric_posix,
+ .collate = &lc_collate_posix,
+ .monetary = &lc_monetary_posix,
+ .messages = &lc_messages_posix,
+ .time = &lc_time_posix,
+ .runelocale = &_DefaultRuneLocale,
+};
+
+locale_t ___global_locale = &posix_locale;
+
+locale_t
+__global_locale(void)
+{
+ return (___global_locale);
+}
+
+/*
+ * Category names for getenv() Note that this was modified
+ * for Solaris. See <iso/locale_iso.h>.
+ */
+#define NUM_CATS 7
+static char *categories[7] = {
+ "LC_CTYPE",
+ "LC_NUMERIC",
+ "LC_TIME",
+ "LC_COLLATE",
+ "LC_MONETARY",
+ "LC_MESSAGES",
+ "LC_ALL",
+};
+
+/*
+ * Prototypes.
+ */
+static const char *get_locale_env(int);
+static struct locdata *locdata_get(int, const const char *);
+static struct locdata *locdata_get_cache(int, const char *);
+static locale_t mklocname(locale_t);
+
+/*
+ * Some utility routines.
+ */
+
+struct locdata *
+__locdata_alloc(const char *name, size_t memsz)
+{
+ struct locdata *ldata;
+
+ if ((ldata = lmalloc(sizeof (*ldata))) == NULL) {
+ return (NULL);
+ }
+ if ((ldata->l_data[0] = libc_malloc(memsz)) == NULL) {
+ lfree(ldata, sizeof (*ldata));
+ errno = ENOMEM;
+ return (NULL);
+ }
+ (void) strlcpy(ldata->l_lname, name, sizeof (ldata->l_lname));
+
+ return (ldata);
+}
+
+/*
+ * Normally we never free locale data truly, but if we failed to load it
+ * for some reason, this routine is used to cleanup the partial mess.
+ */
+void
+__locdata_free(struct locdata *ldata)
+{
+ for (int i = 0; i < NLOCDATA; i++)
+ libc_free(ldata->l_data[i]);
+ if (ldata->l_map != NULL && ldata->l_map_len)
+ (void) munmap(ldata->l_map, ldata->l_map_len);
+ lfree(ldata, sizeof (*ldata));
+}
+
+/*
+ * It turns out that for performance reasons we would really like to
+ * cache the most recently referenced locale data to avoid wasteful
+ * loading from files.
+ */
+
+static struct locdata *cache_data[LC_ALL];
+static struct locdata *cat_data[LC_ALL];
+static mutex_t cache_lock = DEFAULTMUTEX;
+
+/*
+ * Returns the cached data if the locale name is the same. If not,
+ * returns NULL (cache miss). The locdata is returned with a hold on
+ * it, taken on behalf of the caller. The caller should drop the hold
+ * when it is finished.
+ */
+static struct locdata *
+locdata_get_cache(int category, const char *locname)
+{
+ struct locdata *loc;
+
+ if (category < 0 || category >= LC_ALL)
+ return (NULL);
+
+ /* Try cache first. */
+ lmutex_lock(&cache_lock);
+ loc = cache_data[category];
+
+ if ((loc != NULL) && (strcmp(loc->l_lname, locname) == 0)) {
+ lmutex_unlock(&cache_lock);
+ return (loc);
+ }
+
+ /*
+ * Failing that try previously loaded locales (linear search) --
+ * this could be optimized to a hash, but its unlikely that a single
+ * application will ever need to work with more than a few locales.
+ */
+ for (loc = cat_data[category]; loc != NULL; loc = loc->l_next) {
+ if (strcmp(locname, loc->l_lname) == 0) {
+ break;
+ }
+ }
+
+ /*
+ * Finally, if we still don't have one, try loading the locale
+ * data from the actual on-disk data.
+ *
+ * We drop the lock (libc wants to ensure no internal locks
+ * are held when we call other routines required to read from
+ * files, allocate memory, etc.) There is a small race here,
+ * but the consequences of the race are benign -- if multiple
+ * threads hit this at precisely the same point, we could
+ * wind up with duplicates of the locale data in the cache.
+ *
+ * This wastes the memory for an extra copy of the locale
+ * data, but there is no further harm beyond that. Its not
+ * worth the effort to recode this to something "safe"
+ * (which would require rescanning the list, etc.), given
+ * that this race will probably never actually occur.
+ */
+ if (loc == NULL) {
+ lmutex_unlock(&cache_lock);
+ loc = (*loaders[category])(locname);
+ lmutex_lock(&cache_lock);
+ if (loc != NULL)
+ (void) strlcpy(loc->l_lname, locname,
+ sizeof (loc->l_lname));
+ }
+
+ /*
+ * Assuming we got one, update the cache, and stick us on the list
+ * of loaded locale data. We insert into the head (more recent
+ * use is likely to win.)
+ */
+ if (loc != NULL) {
+ cache_data[category] = loc;
+ if (!loc->l_cached) {
+ loc->l_cached = 1;
+ loc->l_next = cat_data[category];
+ cat_data[category] = loc;
+ }
+ }
+
+ lmutex_unlock(&cache_lock);
+ return (loc);
+}
+
+/*
+ * Routine to get the locdata for a given category and locale.
+ * This includes retrieving it from cache, retrieving it from
+ * a file, etc.
+ */
+static struct locdata *
+locdata_get(int category, const char *locname)
+{
+ char scratch[ENCODING_LEN + 1];
+ char *slash;
+ int cnt;
+ int len;
+
+ if (locname == NULL || *locname == 0) {
+ locname = get_locale_env(category);
+ }
+
+ /*
+ * Extract the locale name for the category if it is a composite
+ * locale.
+ */
+ if ((slash = strchr(locname, '/')) != NULL) {
+ for (cnt = category; cnt && slash != NULL; cnt--) {
+ locname = slash + 1;
+ slash = strchr(locname, '/');
+ }
+ if (slash) {
+ len = slash - locname + 1;
+ if (len >= sizeof (scratch)) {
+ len = sizeof (scratch);
+ }
+ } else {
+ len = sizeof (scratch);
+ }
+ (void) strlcpy(scratch, locname, len);
+ locname = scratch;
+ }
+
+ if ((strcmp(locname, "C") == 0) || (strcmp(locname, "POSIX") == 0))
+ return (posix_locale.locdata[category]);
+
+ return (locdata_get_cache(category, locname));
+}
+
+/* tsd destructor */
+static void
+freelocptr(void *arg)
+{
+ locale_t *locptr = arg;
+ if (*locptr != NULL)
+ freelocale(*locptr);
+}
+
+static const char *
+get_locale_env(int category)
+{
+ const char *env;
+
+ /* 1. check LC_ALL. */
+ env = getenv(categories[LC_ALL]);
+
+ /* 2. check LC_* */
+ if (env == NULL || *env == '\0')
+ env = getenv(categories[category]);
+
+ /* 3. check LANG */
+ if (env == NULL || *env == '\0')
+ env = getenv("LANG");
+
+ /* 4. if none is set, fall to "C" */
+ if (env == NULL || *env == '\0')
+ env = "C";
+
+ return (env);
+}
+
+
+/*
+ * This routine is exposed via the MB_CUR_MAX macro. Note that legacy
+ * code will continue to use _ctype[520], but we prefer this function as
+ * it is the only way to get thread-specific information.
+ */
+unsigned char
+__mb_cur_max_l(locale_t loc)
+{
+ return (loc->ctype->lc_max_mblen);
+}
+
+unsigned char
+__mb_cur_max(void)
+{
+ return (__mb_cur_max_l(uselocale(NULL)));
+}
+
+/*
+ * Public interfaces.
+ */
+
+locale_t
+duplocale(locale_t src)
+{
+ locale_t loc;
+ int i;
+
+ loc = lmalloc(sizeof (*loc));
+ if (loc == NULL) {
+ return (NULL);
+ }
+ if (src == NULL) {
+ /* illumos extension: POSIX says LC_GLOBAL_LOCALE here */
+ src = ___global_locale;
+ }
+ for (i = 0; i < LC_ALL; i++) {
+ loc->locdata[i] = src->locdata[i];
+ loc->loaded[i] = 0;
+ }
+ loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
+ loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
+ loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
+ loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
+ loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
+ loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
+ loc->time = loc->locdata[LC_TIME]->l_data[0];
+ return (loc);
+}
+
+void
+freelocale(locale_t loc)
+{
+ /*
+ * We take extra care never to free a saved locale created by
+ * setlocale(). This shouldn't be strictly necessary, but a little
+ * extra safety doesn't hurt here.
+ */
+ if ((loc != NULL) && (loc != &posix_locale) && (!loc->on_list))
+ lfree(loc, sizeof (*loc));
+}
+
+locale_t
+newlocale(int catmask, const char *locname, locale_t base)
+{
+ locale_t loc;
+ int i, e;
+
+ if (catmask & ~(LC_ALL_MASK)) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /*
+ * Technically passing LC_GLOBAL_LOCALE here is illegal,
+ * but we allow it.
+ */
+ if (base == NULL || base == ___global_locale) {
+ loc = duplocale(___global_locale);
+ } else {
+ loc = duplocale(base);
+ }
+ if (loc == NULL) {
+ return (NULL);
+ }
+
+ for (i = 0; i < LC_ALL; i++) {
+ struct locdata *ldata;
+ loc->loaded[i] = 0;
+ if (((1 << i) & catmask) == 0) {
+ /* Default to base locale if not overriding */
+ continue;
+ }
+ ldata = locdata_get(i, locname);
+ if (ldata == NULL) {
+ e = errno;
+ freelocale(loc);
+ errno = e;
+ return (NULL);
+ }
+ loc->locdata[i] = ldata;
+ }
+ loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
+ loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
+ loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
+ loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
+ loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
+ loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
+ loc->time = loc->locdata[LC_TIME]->l_data[0];
+ freelocale(base);
+
+ return (mklocname(loc));
+}
+
+locale_t
+uselocale(locale_t loc)
+{
+ locale_t lastloc = ___global_locale;
+ locale_t *locptr;
+
+ locptr = tsdalloc(_T_SETLOCALE, sizeof (locale_t), freelocptr);
+ /* Should never occur */
+ if (locptr == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (*locptr != NULL)
+ lastloc = *locptr;
+
+ /* Argument loc is NULL if we are just querying. */
+ if (loc != NULL) {
+ /*
+ * Set it to LC_GLOBAL_LOCAL to return to using
+ * the global locale (setlocale).
+ */
+ if (loc == ___global_locale) {
+ *locptr = NULL;
+ } else {
+ /* No validation of the provided locale at present */
+ *locptr = loc;
+ }
+ }
+
+ /*
+ * The caller is responsible for freeing, of course it would be
+ * gross error to call freelocale() on a locale object that is still
+ * in use.
+ */
+ return (lastloc);
+}
+
+static locale_t
+mklocname(locale_t loc)
+{
+ int composite = 0;
+
+ /* Look to see if any category is different */
+ for (int i = 1; i < LC_ALL; ++i) {
+ if (strcmp(loc->locdata[0]->l_lname,
+ loc->locdata[i]->l_lname) != 0) {
+ composite = 1;
+ break;
+ }
+ }
+
+ if (composite) {
+ /*
+ * Note ordering of these follows the numeric order,
+ * if the order is changed, then setlocale() will need
+ * to be changed as well.
+ */
+ (void) snprintf(loc->locname, sizeof (loc->locname),
+ "%s/%s/%s/%s/%s/%s",
+ loc->locdata[LC_CTYPE]->l_lname,
+ loc->locdata[LC_NUMERIC]->l_lname,
+ loc->locdata[LC_TIME]->l_lname,
+ loc->locdata[LC_COLLATE]->l_lname,
+ loc->locdata[LC_MONETARY]->l_lname,
+ loc->locdata[LC_MESSAGES]->l_lname);
+ } else {
+ (void) strlcpy(loc->locname, loc->locdata[LC_CTYPE]->l_lname,
+ sizeof (loc->locname));
+ }
+ return (loc);
+}
diff --git a/usr/src/lib/libc/port/locale/localeimpl.h b/usr/src/lib/libc/port/locale/localeimpl.h
new file mode 100644
index 0000000000..94045209f8
--- /dev/null
+++ b/usr/src/lib/libc/port/locale/localeimpl.h
@@ -0,0 +1,107 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
+/*
+ * This file implements the 2008 newlocale and friends handling. It is
+ * private to libc.
+ */
+#ifndef _LOCALEIMPL_H_
+#define _LOCALEIMPL_H_
+
+#ifndef _LCONV_C99
+#define _LCONV_C99 /* so we get all the extensions */
+#endif
+
+#include <sys/types.h>
+#include <locale.h>
+#include <xlocale.h>
+#include "setlocale.h"
+#include "runetype.h"
+
+/* private locale structures */
+
+/*
+ * Because some locale data is rather ahem.. large, we would like to keep
+ * reference counts on it. We create an abstract header (locdata) structure
+ * which keeps a point to the opaque per-category data, along with a reference
+ * count to it. To be threadsafe, we will use atomics when holding it or
+ * freeing it. (This only occurs when locale objects are created or destroyed,
+ * so there should be no performance impact on hot code paths. If your code
+ * uses locale_t creation/destruction on a hot code path, its broken. But
+ * even so, the atomic and reference counting will probably *greatly* improve
+ * your life as bootstrapping locale data from files is quite expensive.
+ */
+
+#define NLOCDATA 4
+struct locdata {
+ char l_lname[ENCODING_LEN+1]; /* locale name */
+ void *l_data[NLOCDATA]; /* storage area */
+ void *l_map; /* mapped file */
+ size_t l_map_len;
+ struct locdata *l_next; /* link cached list */
+ int l_cached; /* nonzero if cached */
+};
+
+
+struct locale {
+ struct locdata *locdata[LC_ALL];
+ struct locale *next;
+ int on_list; /* on linked list */
+ char locname[(ENCODING_LEN+1)*NLOCDATA + 1];
+
+ /*
+ * Convenience pointers.
+ */
+ const struct lc_ctype *ctype;
+ const struct lc_collate *collate;
+ const struct lc_messages *messages;
+ const struct lc_monetary *monetary;
+ const struct lc_numeric *numeric;
+ const struct lc_time *time;
+ const _RuneLocale *runelocale;
+
+ /*
+ * The loaded value is used for localeconv. In paticular, when
+ * when we change the value of one of the above categories, we will
+ * also need to update the lconv structure. The loaded bit indicates
+ * that the lconv structure is "current" for that category. It's
+ * sort of an "inverse dirty" bit.
+ */
+ int loaded[LC_ALL];
+ struct lconv lconv;
+};
+
+
+struct locdata *__locdata_alloc(const char *, size_t);
+void __locdata_free(struct locdata *);
+struct locdata *__locdata_get_cache(int, const char *);
+void __locdata_set_cache(int, struct locdata *);
+
+struct locdata *__lc_numeric_load(const char *name);
+struct locdata *__lc_monetary_load(const char *name);
+struct locdata *__lc_messages_load(const char *name);
+struct locdata *__lc_time_load(const char *name);
+struct locdata *__lc_ctype_load(const char *name);
+struct locdata *__lc_collate_load(const char *name);
+
+extern struct locdata __posix_numeric_locdata;
+extern struct locdata __posix_monetary_locdata;
+extern struct locdata __posix_messages_locdata;
+extern struct locdata __posix_time_locdata;
+extern struct locdata __posix_ctype_locdata;
+extern struct locdata __posix_collate_locdata;
+extern locale_t ___global_locale;
+
+#endif /* _LOCALEIMPL_H_ */
diff --git a/usr/src/lib/libc/port/locale/mblen.c b/usr/src/lib/libc/port/locale/mblen.c
index 454aeead6c..773daf7478 100644
--- a/usr/src/lib/libc/port/locale/mblen.c
+++ b/usr/src/lib/libc/port/locale/mblen.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -28,22 +29,29 @@
#include "lint.h"
#include <stdlib.h>
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
+#include "localeimpl.h"
int
-mblen(const char *s, size_t n)
+mblen_l(const char *s, size_t n, locale_t loc)
{
- static const mbstate_t initial = { 0 };
- static mbstate_t mbs;
+ mbstate_t mbs = { 0 };
size_t rval;
if (s == NULL) {
/* No support for state dependent encodings. */
- mbs = initial;
return (0);
}
- rval = __mbrtowc(NULL, s, n, &mbs);
+ rval = mbrtowc_l(NULL, s, n, &mbs, loc);
if (rval == (size_t)-1 || rval == (size_t)-2)
return (-1);
return ((int)rval);
}
+
+int
+mblen(const char *s, size_t n)
+{
+ return (mblen_l(s, n, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/mblocal.h b/usr/src/lib/libc/port/locale/mblocal.h
index c1b0ff502a..4412bec7cb 100644
--- a/usr/src/lib/libc/port/locale/mblocal.h
+++ b/usr/src/lib/libc/port/locale/mblocal.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2004 Tim J. Robbins.
* All rights reserved.
@@ -29,43 +30,31 @@
#define _MBLOCAL_H_
#include "runetype.h"
+#include "lctype.h"
/*
* Rune initialization function prototypes.
*/
-int _none_init(_RuneLocale *);
-int _UTF8_init(_RuneLocale *);
-int _EUC_CN_init(_RuneLocale *);
-int _EUC_JP_init(_RuneLocale *);
-int _EUC_KR_init(_RuneLocale *);
-int _EUC_TW_init(_RuneLocale *);
-int _GB18030_init(_RuneLocale *);
-int _GB2312_init(_RuneLocale *);
-int _GBK_init(_RuneLocale *);
-int _BIG5_init(_RuneLocale *);
-int _MSKanji_init(_RuneLocale *);
-
-/*
- * Conversion function pointers for current encoding.
- */
-extern size_t (*__mbrtowc)(wchar_t *_RESTRICT_KYWD,
+void _none_init(struct lc_ctype *);
+void _UTF8_init(struct lc_ctype *);
+void _EUC_CN_init(struct lc_ctype *);
+void _EUC_JP_init(struct lc_ctype *);
+void _EUC_KR_init(struct lc_ctype *);
+void _EUC_TW_init(struct lc_ctype *);
+void _GB18030_init(struct lc_ctype *);
+void _GB2312_init(struct lc_ctype *);
+void _GBK_init(struct lc_ctype *);
+void _BIG5_init(struct lc_ctype *);
+void _MSKanji_init(struct lc_ctype *);
+
+typedef size_t (*mbrtowc_pfn_t)(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
-extern int (*__mbsinit)(const mbstate_t *);
-extern size_t (*__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
- const char **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD);
-
-extern size_t (*__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
+typedef size_t (*wcrtomb_pfn_t)(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
-
-extern size_t (*__wcsnrtombs)(char *_RESTRICT_KYWD,
- const wchar_t **_RESTRICT_KYWD, size_t, size_t, mbstate_t *_RESTRICT_KYWD);
-
-extern int charset_is_ascii;
-
size_t __mbsnrtowcs_std(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
- size_t, size_t, mbstate_t *_RESTRICT_KYWD);
+ size_t, size_t, mbstate_t *_RESTRICT_KYWD, mbrtowc_pfn_t);
size_t __wcsnrtombs_std(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
- size_t, size_t, mbstate_t *_RESTRICT_KYWD);
+ size_t, size_t, mbstate_t *_RESTRICT_KYWD, wcrtomb_pfn_t);
#define MIN(a, b) ((a) < (b) ? (a) : (b))
diff --git a/usr/src/lib/libc/port/locale/mbrlen.c b/usr/src/lib/libc/port/locale/mbrlen.c
index d01ac90b60..e2be484094 100644
--- a/usr/src/lib/libc/port/locale/mbrlen.c
+++ b/usr/src/lib/libc/port/locale/mbrlen.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -27,14 +28,23 @@
#include "lint.h"
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
size_t
-mbrlen(const char *_RESTRICT_KYWD s, size_t n, mbstate_t *_RESTRICT_KYWD ps)
+mbrlen_l(const char *_RESTRICT_KYWD s, size_t n, mbstate_t *_RESTRICT_KYWD ps,
+ locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__mbrtowc(NULL, s, n, ps));
+ return (mbrtowc_l(NULL, s, n, ps, loc));
+}
+
+size_t
+mbrlen(const char *_RESTRICT_KYWD s, size_t n, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (mbrlen_l(s, n, ps, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/mbrtowc.c b/usr/src/lib/libc/port/locale/mbrtowc.c
index 2d155d2bca..cd1e7b064f 100644
--- a/usr/src/lib/libc/port/locale/mbrtowc.c
+++ b/usr/src/lib/libc/port/locale/mbrtowc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -28,14 +29,23 @@
#include "lint.h"
#include <wchar.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
size_t
-mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
- size_t n, mbstate_t *_RESTRICT_KYWD ps)
+mbrtowc_l(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
+ size_t n, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__mbrtowc(pwc, s, n, ps));
+ return (loc->ctype->lc_mbrtowc(pwc, s, n, ps));
+}
+
+size_t
+mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
+ size_t n, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (mbrtowc_l(pwc, s, n, ps, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/mbsinit.c b/usr/src/lib/libc/port/locale/mbsinit.c
index 036f704260..ae956d0f15 100644
--- a/usr/src/lib/libc/port/locale/mbsinit.c
+++ b/usr/src/lib/libc/port/locale/mbsinit.c
@@ -1,37 +1,31 @@
/*
- * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2002-2004 Tim J. Robbins.
- * All rights reserved.
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
*
- * 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.
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
*/
#include "lint.h"
-#include <wchar.h>
-#include "mblocal.h"
+#include <locale.h>
+#include "localeimpl.h"
+#include "lctype.h"
int
-mbsinit(const mbstate_t *ps)
+mbsinit_l(const mbstate_t *s, locale_t loc)
{
+ return (loc->ctype->lc_mbsinit(s));
+}
- return (__mbsinit(ps));
+int
+mbsinit(const mbstate_t *s)
+{
+ return (mbsinit_l(s, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/mbsnrtowcs.c b/usr/src/lib/libc/port/locale/mbsnrtowcs.c
index 3ed93cfeb5..533b7776e0 100644
--- a/usr/src/lib/libc/port/locale/mbsnrtowcs.c
+++ b/usr/src/lib/libc/port/locale/mbsnrtowcs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -31,22 +32,32 @@
#include <stdlib.h>
#include <wchar.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
size_t
-mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
- size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+mbsnrtowcs_l(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__mbsnrtowcs(dst, src, nms, len, ps));
+ return (loc->ctype->lc_mbsnrtowcs(dst, src, nms, len, ps));
}
size_t
-__mbsnrtowcs_std(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps)
{
+ return (mbsnrtowcs_l(dst, src, nms, len, ps, uselocale(NULL)));
+}
+
+size_t
+__mbsnrtowcs_std(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+ size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD ps,
+ mbrtowc_pfn_t pmbrtowc)
+{
const char *s;
size_t nchr;
wchar_t wc;
@@ -57,7 +68,7 @@ __mbsnrtowcs_std(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
if (dst == NULL) {
for (;;) {
- if ((nb = __mbrtowc(&wc, s, nms, ps)) == (size_t)-1)
+ if ((nb = pmbrtowc(&wc, s, nms, ps)) == (size_t)-1)
/* Invalid sequence - mbrtowc() sets errno. */
return ((size_t)-1);
else if (nb == 0 || nb == (size_t)-2)
@@ -70,7 +81,7 @@ __mbsnrtowcs_std(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
}
while (len-- > 0) {
- if ((nb = __mbrtowc(dst, s, nms, ps)) == (size_t)-1) {
+ if ((nb = pmbrtowc(dst, s, nms, ps)) == (size_t)-1) {
*src = s;
return ((size_t)-1);
} else if (nb == (size_t)-2) {
diff --git a/usr/src/lib/libc/port/locale/mbsrtowcs.c b/usr/src/lib/libc/port/locale/mbsrtowcs.c
index 592a0e3c83..1f219e308e 100644
--- a/usr/src/lib/libc/port/locale/mbsrtowcs.c
+++ b/usr/src/lib/libc/port/locale/mbsrtowcs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -26,19 +27,24 @@
*/
#include "lint.h"
-#include <errno.h>
+#include <locale.h>
#include <limits.h>
#include <stdlib.h>
#include <wchar.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
+
+size_t
+mbsrtowcs_l(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+ size_t len, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
+{
+ return (loc->ctype->lc_mbsnrtowcs(dst, src, ULONG_MAX, len, ps));
+}
size_t
mbsrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
size_t len, mbstate_t *_RESTRICT_KYWD ps)
{
- static mbstate_t mbs;
-
- if (ps == NULL)
- ps = &mbs;
- return (__mbsnrtowcs(dst, src, ULONG_MAX, len, ps));
+ return (mbsrtowcs_l(dst, src, len, ps, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/mbstowcs.c b/usr/src/lib/libc/port/locale/mbstowcs.c
index 343564ec93..1e853f2682 100644
--- a/usr/src/lib/libc/port/locale/mbstowcs.c
+++ b/usr/src/lib/libc/port/locale/mbstowcs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -29,10 +30,14 @@
#include <limits.h>
#include <stdlib.h>
#include <wchar.h>
+#include <locale.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
size_t
-mbstowcs(wchar_t *_RESTRICT_KYWD pwcs, const char *_RESTRICT_KYWD s, size_t n)
+mbstowcs_l(wchar_t *_RESTRICT_KYWD pwcs, const char *_RESTRICT_KYWD s,
+ size_t n, locale_t loc)
{
static const mbstate_t initial = { 0 };
mbstate_t mbs;
@@ -40,5 +45,11 @@ mbstowcs(wchar_t *_RESTRICT_KYWD pwcs, const char *_RESTRICT_KYWD s, size_t n)
mbs = initial;
sp = s;
- return (__mbsnrtowcs(pwcs, &sp, ULONG_MAX, n, &mbs));
+ return (loc->ctype->lc_mbsnrtowcs(pwcs, &sp, ULONG_MAX, n, &mbs));
+}
+
+size_t
+mbstowcs(wchar_t *_RESTRICT_KYWD pwcs, const char *_RESTRICT_KYWD s, size_t n)
+{
+ return (mbstowcs_l(pwcs, s, n, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/mbtowc.c b/usr/src/lib/libc/port/locale/mbtowc.c
index 66718fa90a..90dc2e6080 100644
--- a/usr/src/lib/libc/port/locale/mbtowc.c
+++ b/usr/src/lib/libc/port/locale/mbtowc.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -28,22 +29,29 @@
#include "lint.h"
#include <stdlib.h>
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
int
-mbtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, size_t n)
+mbtowc_l(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, size_t n,
+ locale_t loc)
{
- static const mbstate_t initial = { 0 };
- static mbstate_t mbs;
+ mbstate_t mbs = { 0 };
size_t rval;
if (s == NULL) {
/* No support for state dependent encodings. */
- mbs = initial;
return (0);
}
- rval = __mbrtowc(pwc, s, n, &mbs);
+ rval = mbrtowc_l(pwc, s, n, &mbs, loc);
if (rval == (size_t)-1 || rval == (size_t)-2)
return (-1);
return ((int)rval);
}
+
+int
+mbtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s, size_t n)
+{
+ return (mbtowc_l(pwc, s, n, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/mskanji.c b/usr/src/lib/libc/port/locale/mskanji.c
index 1b6c2d0584..5d9b899aae 100644
--- a/usr/src/lib/libc/port/locale/mskanji.c
+++ b/usr/src/lib/libc/port/locale/mskanji.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
*
@@ -37,11 +38,11 @@
#include "lint.h"
#include <sys/types.h>
#include <errno.h>
-#include "runetype.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _MSKanji_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -49,22 +50,28 @@ static size_t _MSKanji_mbrtowc(wchar_t *_RESTRICT_KYWD,
static int _MSKanji_mbsinit(const mbstate_t *);
static size_t _MSKanji_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
mbstate_t *_RESTRICT_KYWD);
+static size_t _MSKanji_mbsnrtowcs(wchar_t *_RESTRICT_KYWD,
+ const char **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
+static size_t _MSKanji_wcsnrtombs(char *_RESTRICT_KYWD,
+ const wchar_t **_RESTRICT_KYWD, size_t, size_t,
+ mbstate_t *_RESTRICT_KYWD);
typedef struct {
wchar_t ch;
} _MSKanjiState;
-int
-_MSKanji_init(_RuneLocale *rl)
+void
+_MSKanji_init(struct lc_ctype *lct)
{
- __mbrtowc = _MSKanji_mbrtowc;
- __wcrtomb = _MSKanji_wcrtomb;
- __mbsinit = _MSKanji_mbsinit;
- _CurrentRuneLocale = rl;
- __ctype[520] = 2;
- charset_is_ascii = 0;
- return (0);
+ lct->lc_mbrtowc = _MSKanji_mbrtowc;
+ lct->lc_wcrtomb = _MSKanji_wcrtomb;
+ lct->lc_mbsnrtowcs = _MSKanji_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _MSKanji_wcsnrtombs;
+ lct->lc_mbsinit = _MSKanji_mbsinit;
+ lct->lc_max_mblen = 2;
+ lct->lc_is_ascii = 0;
}
static int
@@ -154,3 +161,19 @@ _MSKanji_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
*s++ = wc >> (i << 3);
return (len);
}
+
+static size_t
+_MSKanji_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
+ const char **_RESTRICT_KYWD src, size_t nms,
+ size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__mbsnrtowcs_std(dst, src, nms, len, ps, _MSKanji_mbrtowc));
+}
+
+static size_t
+_MSKanji_wcsnrtombs(char *_RESTRICT_KYWD dst,
+ const wchar_t **_RESTRICT_KYWD src, size_t nwc,
+ size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (__wcsnrtombs_std(dst, src, nwc, len, ps, _MSKanji_wcrtomb));
+}
diff --git a/usr/src/lib/libc/port/locale/nextwctype.c b/usr/src/lib/libc/port/locale/nextwctype.c
index 54a9d2a07b..53b0c163e8 100644
--- a/usr/src/lib/libc/port/locale/nextwctype.c
+++ b/usr/src/lib/libc/port/locale/nextwctype.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2004 Tim J. Robbins.
* All rights reserved.
*
@@ -28,20 +29,32 @@
#include "runetype.h"
#include <wchar.h>
#include <wctype.h>
+#include "localeimpl.h"
-wint_t
-__nextwctype(wint_t wc, wctype_t wct)
+/*
+ * nextwctype, while exposed on *BSD/MacOS X, is considered "consolidation
+ * private" for illumos. Hence, we keep the _l version static for now.
+ * If we decide to make this public, just remove the static keyword and
+ * put it in the headers and mapfile. (Should fix up the underscore prefix
+ * to __nextwctype() as well.)
+ */
+static wint_t
+nextwctype_l(wint_t wc, wctype_t wct, locale_t loc)
{
size_t lim;
- _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext;
- _RuneEntry *base, *re;
+ const _RuneLocale *rl;
+ const _RuneRange *rr;
+ const _RuneEntry *base, *re;
int noinc;
+ rl = loc->runelocale;
+ rr = &rl->__runetype_ext;
+
noinc = 0;
if (wc < _CACHED_RUNES) {
wc++;
while (wc < _CACHED_RUNES) {
- if (_CurrentRuneLocale->__runetype[wc] & wct)
+ if (rl->__runetype[wc] & wct)
return (wc);
wc++;
}
@@ -86,3 +99,12 @@ found:
}
return (-1);
}
+
+/*
+ * External, but consolidation private routine.
+ */
+wint_t
+__nextwctype(wint_t wc, wctype_t wct)
+{
+ return (nextwctype_l(wc, wct, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/nl_langinfo.c b/usr/src/lib/libc/port/locale/nl_langinfo.c
index 840f45ef45..01de8b78d7 100644
--- a/usr/src/lib/libc/port/locale/nl_langinfo.c
+++ b/usr/src/lib/libc/port/locale/nl_langinfo.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2001, 2003 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
@@ -36,33 +37,38 @@
#include "lmessages.h"
#include "lmonetary.h"
#include "timelocal.h"
+#include "localeimpl.h"
#define _REL(BASE) ((int)item-BASE)
-#define MONETARY (__get_current_monetary_locale())
-#define TIME (__get_current_time_locale())
-#define MESSAGES (__get_current_messages_locale())
-#define NUMERIC (__get_current_numeric_locale())
-
#pragma weak _nl_langinfo = nl_langinfo
char *
-nl_langinfo(nl_item item)
+nl_langinfo_l(nl_item item, locale_t loc)
{
char *ret, *s, *cs;
- static char *csym = NULL;
+ struct locdata *ldata;
+ const struct lc_monetary *lmon = loc->monetary;
+ const struct lc_numeric *lnum = loc->numeric;
+ const struct lc_messages *lmsgs = loc->messages;
+ const struct lc_time *ltime = loc->time;
switch (item) {
case CODESET:
ret = "";
/*
* The codeset is the suffix of a locale, for most it will
- * will be UTF-8, as in "en.UTF-8". Short form locales are
+ * will be UTF-8, as in "en_US.UTF-8". Short form locales are
* not supported. Note also that although FreeBSD uses
* US-ASCII, Solaris historically has reported "646" for the
* C locale.
+ *
+ * Note that this code will need to change if we ever support
+ * POSIX defined locale variants (suffixes with an @ sign)
*/
- if ((s = setlocale(LC_CTYPE, NULL)) != NULL) {
+ ldata = loc->locdata[LC_CTYPE];
+ s = ldata ? ldata->l_lname : NULL;
+ if (s != NULL) {
if ((cs = strchr(s, '.')) != NULL)
ret = cs + 1;
else if (strcmp(s, "C") == 0 || strcmp(s, "POSIX") == 0)
@@ -70,40 +76,40 @@ nl_langinfo(nl_item item)
}
break;
case D_T_FMT:
- ret = (char *)TIME->c_fmt;
+ ret = (char *)ltime->c_fmt;
break;
case D_FMT:
- ret = (char *)TIME->x_fmt;
+ ret = (char *)ltime->x_fmt;
break;
case T_FMT:
- ret = (char *)TIME->X_fmt;
+ ret = (char *)ltime->X_fmt;
break;
case T_FMT_AMPM:
- ret = (char *)TIME->ampm_fmt;
+ ret = (char *)ltime->ampm_fmt;
break;
case AM_STR:
- ret = (char *)TIME->am;
+ ret = (char *)ltime->am;
break;
case PM_STR:
- ret = (char *)TIME->pm;
+ ret = (char *)ltime->pm;
break;
case DAY_1: case DAY_2: case DAY_3:
case DAY_4: case DAY_5: case DAY_6: case DAY_7:
- ret = (char *)TIME->weekday[_REL(DAY_1)];
+ ret = (char *)ltime->weekday[_REL(DAY_1)];
break;
case ABDAY_1: case ABDAY_2: case ABDAY_3:
case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7:
- ret = (char *)TIME->wday[_REL(ABDAY_1)];
+ ret = (char *)ltime->wday[_REL(ABDAY_1)];
break;
case MON_1: case MON_2: case MON_3: case MON_4:
case MON_5: case MON_6: case MON_7: case MON_8:
case MON_9: case MON_10: case MON_11: case MON_12:
- ret = (char *)TIME->month[_REL(MON_1)];
+ ret = (char *)ltime->month[_REL(MON_1)];
break;
case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4:
case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8:
case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
- ret = (char *)TIME->mon[_REL(ABMON_1)];
+ ret = (char *)ltime->mon[_REL(ABMON_1)];
break;
case ERA:
/* XXX: need to be implemented */
@@ -126,64 +132,37 @@ nl_langinfo(nl_item item)
ret = "";
break;
case RADIXCHAR:
- ret = (char *)NUMERIC->decimal_point;
+ ret = (char *)lnum->decimal_point;
break;
case THOUSEP:
- ret = (char *)NUMERIC->thousands_sep;
+ ret = (char *)lnum->thousands_sep;
break;
case YESEXPR:
- ret = (char *)MESSAGES->yesexpr;
+ ret = (char *)lmsgs->yesexpr;
break;
case NOEXPR:
- ret = (char *)MESSAGES->noexpr;
+ ret = (char *)lmsgs->noexpr;
break;
/*
- * YESSTR and NOSTR items marked with LEGACY are available, but not
- * recomended by SUSv2 to be used in portable applications since
- * they're subject to remove in future specification editions.
+ * YESSTR and NOSTR items were removed from Issue 7. But
+ * older applications might still need them. Their use is
+ * discouraged.
*/
case YESSTR: /* LEGACY */
- ret = (char *)MESSAGES->yesstr;
+ ret = (char *)lmsgs->yesstr;
break;
case NOSTR: /* LEGACY */
- ret = (char *)MESSAGES->nostr;
+ ret = (char *)lmsgs->nostr;
break;
/*
* SUSv2 special formatted currency string
*/
case CRNCYSTR:
- ret = "";
- cs = (char *)MONETARY->currency_symbol;
- if (*cs != '\0') {
- char pos = localeconv()->p_cs_precedes;
-
- if (pos == localeconv()->n_cs_precedes) {
- char psn = '\0';
-
- if (pos == CHAR_MAX) {
- if (strcmp(cs,
- MONETARY->mon_decimal_point) == 0)
- psn = '.';
- } else
- psn = pos ? '-' : '+';
- if (psn != '\0') {
- int clen = strlen(cs);
- char *newc;
-
- newc = realloc(csym, clen + 2);
- if (newc != NULL) {
- free(csym);
- csym = newc;
- *csym = psn;
- (void) strcpy(csym + 1, cs);
- ret = csym;
- }
- }
- }
- }
+ ret = lmon->crncystr;
break;
+
case _DATE_FMT: /* Solaris specific extension */
- ret = (char *)TIME->date_fmt;
+ ret = (char *)ltime->date_fmt;
break;
/*
* Note that FreeBSD also had a private D_MD_ORDER, but that appears
@@ -194,3 +173,9 @@ nl_langinfo(nl_item item)
}
return (ret);
}
+
+char *
+nl_langinfo(nl_item item)
+{
+ return (nl_langinfo_l(item, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/none.c b/usr/src/lib/libc/port/locale/none.c
index 14b6d71abb..0511563cb1 100644
--- a/usr/src/lib/libc/port/locale/none.c
+++ b/usr/src/lib/libc/port/locale/none.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
* Copyright (c) 1993
@@ -41,40 +42,25 @@
#include <string.h>
#include <wchar.h>
#include <note.h>
-#include "runetype.h"
#include "mblocal.h"
-
-static size_t _none_mbrtowc(wchar_t *_RESTRICT_KYWD,
- const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
-
-static int _none_mbsinit(const mbstate_t *);
-static size_t _none_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst,
- const char **_RESTRICT_KYWD src, size_t nms, size_t len,
- mbstate_t *_RESTRICT_KYWD);
-static size_t _none_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
- mbstate_t *_RESTRICT_KYWD);
-static size_t _none_wcsnrtombs(char *_RESTRICT_KYWD,
- const wchar_t **_RESTRICT_KYWD,
- size_t, size_t, mbstate_t *_RESTRICT_KYWD);
+#include "lctype.h"
/* setup defaults */
-int
-_none_init(_RuneLocale *rl)
+void
+_none_init(struct lc_ctype *lct)
{
- charset_is_ascii = 1;
-
- __mbrtowc = _none_mbrtowc;
- __mbsinit = _none_mbsinit;
- __mbsnrtowcs = _none_mbsnrtowcs;
- __wcrtomb = _none_wcrtomb;
- __wcsnrtombs = _none_wcsnrtombs;
- _CurrentRuneLocale = rl;
- return (0);
+ lct->lc_is_ascii = 1;
+ lct->lc_mbrtowc = __mbrtowc_ascii;
+ lct->lc_mbsinit = __mbsinit_ascii;
+ lct->lc_mbsnrtowcs = __mbsnrtowcs_ascii;
+ lct->lc_wcrtomb = __wcrtomb_ascii;
+ lct->lc_wcsnrtombs = __wcsnrtombs_ascii;
+ lct->lc_max_mblen = 1;
}
-static int
-_none_mbsinit(const mbstate_t *unused)
+int
+__mbsinit_ascii(const mbstate_t *unused)
{
_NOTE(ARGUNUSED(unused));
@@ -85,8 +71,8 @@ _none_mbsinit(const mbstate_t *unused)
return (1);
}
-static size_t
-_none_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
+size_t
+__mbrtowc_ascii(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
size_t n, mbstate_t *_RESTRICT_KYWD unused)
{
_NOTE(ARGUNUSED(unused));
@@ -102,8 +88,8 @@ _none_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
return (*s == '\0' ? 0 : 1);
}
-static size_t
-_none_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
+size_t
+__wcrtomb_ascii(char *_RESTRICT_KYWD s, wchar_t wc,
mbstate_t *_RESTRICT_KYWD unused)
{
_NOTE(ARGUNUSED(unused));
@@ -119,8 +105,8 @@ _none_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
return (1);
}
-static size_t
-_none_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
+size_t
+__mbsnrtowcs_ascii(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
size_t nms, size_t len, mbstate_t *_RESTRICT_KYWD unused)
{
const char *s;
@@ -146,8 +132,8 @@ _none_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst, const char **_RESTRICT_KYWD src,
return (nchr);
}
-static size_t
-_none_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+size_t
+__wcsnrtombs_ascii(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD unused)
{
const wchar_t *s;
@@ -181,19 +167,3 @@ _none_wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
*src = s;
return (nchr);
}
-
-/* setup defaults */
-
-size_t (*__mbrtowc)(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
- size_t, mbstate_t *_RESTRICT_KYWD) = _none_mbrtowc;
-
-int (*__mbsinit)(const mbstate_t *) = _none_mbsinit;
-
-size_t (*__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
- size_t, size_t, mbstate_t *_RESTRICT_KYWD) = _none_mbsnrtowcs;
-
-size_t (*__wcrtomb)(char *_RESTRICT_KYWD, wchar_t, mbstate_t *_RESTRICT_KYWD) =
- _none_wcrtomb;
-
-size_t (*__wcsnrtombs)(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
- size_t, size_t, mbstate_t *_RESTRICT_KYWD) = _none_wcsnrtombs;
diff --git a/usr/src/lib/libc/port/locale/regcomp.c b/usr/src/lib/libc/port/locale/regcomp.c
index f67e5cadf7..f3027d8a02 100644
--- a/usr/src/lib/libc/port/locale/regcomp.c
+++ b/usr/src/lib/libc/port/locale/regcomp.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright 2012 Milan Jurik. All rights reserved.
* Copyright (c) 1992, 1993, 1994 Henry Spencer.
@@ -725,6 +726,7 @@ p_b_term(struct parse *p, cset *cs)
char c;
wint_t start, finish;
wint_t i;
+ locale_t loc = uselocale(NULL);
/* classify what we've got */
switch ((MORE()) ? PEEK() : '\0') {
@@ -772,16 +774,18 @@ p_b_term(struct parse *p, cset *cs)
if (start == finish)
CHadd(p, cs, start);
else {
- if (_collate_load_error) {
+ if (loc->collate->lc_is_posix) {
(void) REQUIRE((uch)start <= (uch)finish,
REG_ERANGE);
CHaddrange(p, cs, start, finish);
} else {
(void) REQUIRE(_collate_range_cmp(start,
- finish) <= 0, REG_ERANGE);
+ finish, loc) <= 0, REG_ERANGE);
for (i = 0; i <= UCHAR_MAX; i++) {
- if (_collate_range_cmp(start, i) <= 0 &&
- _collate_range_cmp(i, finish) <= 0)
+ if (_collate_range_cmp(start, i, loc)
+ <= 0 &&
+ _collate_range_cmp(i, finish, loc)
+ <= 0)
CHadd(p, cs, i);
}
}
@@ -1367,6 +1371,7 @@ findmust(struct parse *p, struct re_guts *g)
char buf[MB_LEN_MAX];
size_t clen;
mbstate_t mbs;
+ locale_t loc = uselocale(NULL);
/* avoid making error situations worse */
if (p->error != 0)
@@ -1378,7 +1383,7 @@ findmust(struct parse *p, struct re_guts *g)
* UTF-8 (see RFC 3629).
*/
if (MB_CUR_MAX > 1 &&
- strcmp(_CurrentRuneLocale->__encoding, "UTF-8") != 0)
+ strcmp(loc->runelocale->__encoding, "UTF-8") != 0)
return;
/* find the longest OCHAR sequence in strip */
diff --git a/usr/src/lib/libc/port/locale/rune.c b/usr/src/lib/libc/port/locale/rune.c
index 545682691e..38e32d42ba 100644
--- a/usr/src/lib/libc/port/locale/rune.c
+++ b/usr/src/lib/libc/port/locale/rune.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -39,14 +40,16 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "libc.h"
#include "runetype.h"
#include "runefile.h"
-_RuneLocale *_Read_RuneMagi(FILE *);
-
_RuneLocale *
-_Read_RuneMagi(FILE *fp)
+_Read_RuneMagi(const char *fname)
{
char *fdata, *data;
void *lastp;
@@ -61,31 +64,30 @@ _Read_RuneMagi(FILE *fp)
_FileRuneEntry *maplower_ext_ranges;
_FileRuneEntry *mapupper_ext_ranges;
int runetype_ext_len = 0;
+ int fd;
- if (fstat(fileno(fp), &sb) < 0)
- return (NULL);
-
- if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
+ if ((fd = open(fname, O_RDONLY)) < 0) {
errno = EINVAL;
return (NULL);
}
- if ((fdata = malloc(sb.st_size)) == NULL)
+ if (fstat(fd, &sb) < 0) {
+ (void) close(fd);
+ errno = EINVAL;
return (NULL);
+ }
- errno = 0;
- rewind(fp); /* Someone might have read the magic number once already */
- if (errno) {
- saverr = errno;
- free(fdata);
- errno = saverr;
+ if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
+ (void) close(fd);
+ errno = EINVAL;
return (NULL);
}
- if (fread(fdata, sb.st_size, 1, fp) != 1) {
- saverr = errno;
- free(fdata);
- errno = saverr;
+
+ fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ (void) close(fd);
+ if (fdata == NULL) {
+ errno = EINVAL;
return (NULL);
}
@@ -95,33 +97,25 @@ _Read_RuneMagi(FILE *fp)
variable = frl + 1;
if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
runetype_ext_ranges = (_FileRuneEntry *)variable;
variable = runetype_ext_ranges + frl->runetype_ext_nranges;
if (variable > lastp) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
maplower_ext_ranges = (_FileRuneEntry *)variable;
variable = maplower_ext_ranges + frl->maplower_ext_nranges;
if (variable > lastp) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
mapupper_ext_ranges = (_FileRuneEntry *)variable;
variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
if (variable > lastp) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
frr = runetype_ext_ranges;
@@ -134,30 +128,26 @@ _Read_RuneMagi(FILE *fp)
variable = types + len;
runetype_ext_len += len;
if (variable > lastp) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
}
}
if ((char *)variable + frl->variable_len > (char *)lastp) {
- free(fdata);
- errno = EINVAL;
- return (NULL);
+ goto invalid;
}
/*
* Convert from disk format to host format.
*/
- data = malloc(sizeof (_RuneLocale) +
+ data = libc_malloc(sizeof (_RuneLocale) +
(frl->runetype_ext_nranges + frl->maplower_ext_nranges +
frl->mapupper_ext_nranges) * sizeof (_RuneEntry) +
runetype_ext_len * sizeof (*rr->__types) +
frl->variable_len);
if (data == NULL) {
saverr = errno;
- free(fdata);
+ (void) munmap(fdata, sb.st_size);
errno = saverr;
return (NULL);
}
@@ -229,7 +219,7 @@ _Read_RuneMagi(FILE *fp)
}
(void) memcpy(rl->__variable, variable, rl->__variable_len);
- free(fdata);
+ (void) munmap(fdata, sb.st_size);
/*
* Go out and zero pointers that should be zero.
@@ -247,4 +237,9 @@ _Read_RuneMagi(FILE *fp)
rl->__mapupper_ext.__ranges = NULL;
return (rl);
+
+invalid:
+ (void) munmap(fdata, sb.st_size);
+ errno = EINVAL;
+ return (NULL);
}
diff --git a/usr/src/lib/libc/port/locale/runetype.c b/usr/src/lib/libc/port/locale/runetype.c
index 3a978fe038..102f483449 100644
--- a/usr/src/lib/libc/port/locale/runetype.c
+++ b/usr/src/lib/libc/port/locale/runetype.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -37,11 +38,11 @@
#include "runetype.h"
unsigned int
-___runetype(__ct_rune_t c)
+__runetype(const _RuneLocale *rl, __ct_rune_t c)
{
size_t lim;
- _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext;
- _RuneEntry *base, *re;
+ const _RuneRange *rr = &rl->__runetype_ext;
+ const _RuneEntry *base, *re;
if (c < 0 || c == EOF)
return (0L);
diff --git a/usr/src/lib/libc/port/locale/runetype.h b/usr/src/lib/libc/port/locale/runetype.h
index 9d5648496c..3abdd1afa9 100644
--- a/usr/src/lib/libc/port/locale/runetype.h
+++ b/usr/src/lib/libc/port/locale/runetype.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -110,7 +111,7 @@ typedef struct {
typedef struct {
char __magic[8]; /* Magic saying what version we are */
- char __encoding[32]; /* ASCII name of this encoding */
+ char __encoding[32]; /* ASCII name of encoding */
unsigned int __runetype[_CACHED_RUNES];
__rune_t __maplower[_CACHED_RUNES];
@@ -132,6 +133,7 @@ typedef struct {
#define _RUNE_MAGIC_1 "RuneMagi" /* Indicates version 0 of RuneLocale */
extern _RuneLocale _DefaultRuneLocale;
-extern _RuneLocale *_CurrentRuneLocale;
+
+unsigned int __runetype(const _RuneLocale *, int);
#endif /* !_RUNETYPE_H_ */
diff --git a/usr/src/lib/libc/port/locale/setlocale.c b/usr/src/lib/libc/port/locale/setlocale.c
index 8cf7f88f98..e0a56ef8de 100644
--- a/usr/src/lib/libc/port/locale/setlocale.c
+++ b/usr/src/lib/libc/port/locale/setlocale.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1996 - 2002 FreeBSD Project
* Copyright (c) 1991, 1993
@@ -41,289 +42,144 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <alloca.h>
#include <stdio.h>
+#include "mtlib.h"
#include "collate.h"
-#include "lmonetary.h" /* for __monetary_load_locale() */
-#include "lnumeric.h" /* for __numeric_load_locale() */
-#include "lmessages.h" /* for __messages_load_locale() */
+#include "lnumeric.h" /* for struct lc_numeric */
+#include "lctype.h" /* for struct lc_ctype */
#include "setlocale.h"
-#include "ldpart.h"
-#include "timelocal.h" /* for __time_load_locale() */
#include "../i18n/_loc_path.h"
-
-/*
- * Category names for getenv() Note that this was modified
- * for Solaris. See <iso/locale_iso.h>.
- */
-#define NUM_CATS 7
-static char *categories[7] = {
- "LC_CTYPE",
- "LC_NUMERIC",
- "LC_TIME",
- "LC_COLLATE",
- "LC_MONETARY",
- "LC_MESSAGES",
- "LC_ALL",
-};
-
-/*
- * Current locales for each category
- */
-static char current_categories[NUM_CATS][ENCODING_LEN + 1] = {
- "C",
- "C",
- "C",
- "C",
- "C",
- "C",
- "C",
-};
+#include "localeimpl.h"
+#include "../i18n/_locale.h"
/*
* Path to locale storage directory. See ../i18n/_loc_path.h
*/
char *_PathLocale = _DFLT_LOC_PATH;
-/*
- * The locales we are going to try and load
- */
-static char new_categories[NUM_CATS][ENCODING_LEN + 1];
-static char saved_categories[NUM_CATS][ENCODING_LEN + 1];
-static char current_locale_string[NUM_CATS * (ENCODING_LEN + 1 + 1)];
+static char *current_locale(locale_t, int);
+static void install_legacy(locale_t, int);
-static char *currentlocale(void);
-static char *loadlocale(int);
-static const char *__get_locale_env(int);
+static mutex_t setlocale_lock = DEFAULTMUTEX;
+static locale_t setlocale_list = NULL;
char *
-setlocale(int category, const char *locale)
+setlocale(int category, const char *locname)
{
- int i, j, saverr;
- const char *env, *r;
+ locale_t loc;
+ locale_t srch;
+ int mask;
- if (category < 0 || category >= NUM_CATS) {
+ if (category < 0 || category > LC_ALL) {
errno = EINVAL;
return (NULL);
}
- if (locale == NULL)
- return (category != LC_ALL ?
- current_categories[category] : currentlocale());
-
- /*
- * Default to the current locale for everything.
- */
- for (i = 0; i < NUM_CATS; ++i)
- (void) strcpy(new_categories[i], current_categories[i]);
-
- /*
- * Now go fill up new_categories from the locale argument
- */
- if (!*locale) {
- if (category == LC_ALL) {
- for (i = 0; i < NUM_CATS; ++i) {
- if (i == LC_ALL)
- continue;
- env = __get_locale_env(i);
- if (strlen(env) > ENCODING_LEN) {
- errno = EINVAL;
- return (NULL);
- }
- (void) strcpy(new_categories[i], env);
- }
- } else {
- env = __get_locale_env(category);
- if (strlen(env) > ENCODING_LEN) {
- errno = EINVAL;
- return (NULL);
- }
- (void) strcpy(new_categories[category], env);
- }
- } else if (category != LC_ALL) {
- if (strlen(locale) > ENCODING_LEN) {
- errno = EINVAL;
- return (NULL);
- }
- (void) strcpy(new_categories[category], locale);
- } else {
- if ((r = strchr(locale, '/')) == NULL) {
- if (strlen(locale) > ENCODING_LEN) {
- errno = EINVAL;
- return (NULL);
- }
- for (i = 0; i < NUM_CATS; ++i)
- (void) strcpy(new_categories[i], locale);
- } else {
- char *buf;
- char *save;
-
- buf = alloca(strlen(locale) + 1);
- (void) strcpy(buf, locale);
-
- save = NULL;
- r = strtok_r(buf, "/", &save);
- for (i = 0; i < NUM_CATS; i++) {
- if (i == LC_ALL)
- continue;
- if (r == NULL) {
- /*
- * Composite Locale is inadequately
- * specified! (Or with empty fields.)
- * The old code would fill fields
- * out from the last one, but I think
- * this is suboptimal.
- */
- errno = EINVAL;
- return (NULL);
- }
- (void) strlcpy(new_categories[i], r,
- ENCODING_LEN);
- r = strtok_r(NULL, "/", &save);
- }
- if (r != NULL) {
- /*
- * Too many components - we had left over
- * data in the LC_ALL. It is malformed.
- */
- errno = EINVAL;
- return (NULL);
- }
- }
- }
+ if (locname == NULL)
+ return (current_locale(___global_locale, category));
- if (category != LC_ALL)
- return (loadlocale(category));
+ mask = (category == LC_ALL ? LC_ALL_MASK : (1 << category));
- for (i = 0; i < NUM_CATS; ++i) {
- (void) strcpy(saved_categories[i], current_categories[i]);
- if (i == LC_ALL)
- continue;
- if (loadlocale(i) == NULL) {
- saverr = errno;
- for (j = 0; j < i; j++) {
- (void) strcpy(new_categories[j],
- saved_categories[j]);
- if (i == LC_ALL)
- continue;
- if (loadlocale(j) == NULL) {
- (void) strcpy(new_categories[j], "C");
- (void) loadlocale(j);
- }
- }
- errno = saverr;
- return (NULL);
- }
+ loc = newlocale(mask, locname, NULL);
+ if (loc == NULL) {
+ return (NULL);
}
- return (currentlocale());
-}
-static char *
-currentlocale(void)
-{
- int i;
- int composite = 0;
-
- /* Look to see if any category is different */
- for (i = 1; i < NUM_CATS; ++i) {
- if (i == LC_ALL)
- continue;
- if (strcmp(current_categories[0], current_categories[i])) {
- composite = 1;
+ /*
+ * This next logic looks to see if we have ever used the same locale
+ * settings before. If so, we reuse it. We avoid ever calling
+ * freelocale() on a locale setting built up by setlocale, this
+ * ensures that consumers (uselocale) will always be thread safe;
+ * the actual locale data objects are never freed, and unique
+ * locale objects are also never freed. We reuse to avoid leaking
+ * memory in applications that call setlocale repeatedly.
+ */
+ lmutex_lock(&setlocale_lock);
+ for (srch = setlocale_list; srch != NULL; srch = srch->next) {
+ if (strcmp(srch->locname, loc->locname) == 0) {
break;
}
}
- if (composite) {
- /*
- * Note ordering of these follows the numeric order,
- * if the order is changed, then setlocale() will need
- * to be changed as well.
- */
- (void) snprintf(current_locale_string,
- sizeof (current_locale_string),
- "%s/%s/%s/%s/%s/%s",
- current_categories[LC_CTYPE],
- current_categories[LC_NUMERIC],
- current_categories[LC_TIME],
- current_categories[LC_COLLATE],
- current_categories[LC_MONETARY],
- current_categories[LC_MESSAGES]);
+ if (srch == NULL) {
+ /* this is a new locale, save it for reuse later */
+ loc->next = setlocale_list;
+ loc->on_list = 1;
+ setlocale_list = loc;
} else {
- (void) strlcpy(current_locale_string, current_categories[0],
- sizeof (current_locale_string));
+ /* we already had it, toss the new, and use what we found */
+ freelocale(loc);
+ loc = srch;
}
- return (current_locale_string);
+ ___global_locale = loc;
+
+ install_legacy(loc, mask);
+ lmutex_unlock(&setlocale_lock);
+
+ return (current_locale(loc, category));
}
static char *
-loadlocale(int category)
+current_locale(locale_t loc, int cat)
{
- char *new = new_categories[category];
- char *old = current_categories[category];
- int (*func)(const char *);
-
- if ((new[0] == '.' &&
- (new[1] == '\0' || (new[1] == '.' && new[2] == '\0'))) ||
- strchr(new, '/') != NULL) {
- errno = EINVAL;
- return (NULL);
- }
-
- switch (category) {
+ switch (cat) {
case LC_CTYPE:
- func = __wrap_setrunelocale;
- break;
case LC_COLLATE:
- func = _collate_load_tables;
- break;
- case LC_TIME:
- func = __time_load_locale;
- break;
- case LC_NUMERIC:
- func = __numeric_load_locale;
- break;
- case LC_MONETARY:
- func = __monetary_load_locale;
- break;
case LC_MESSAGES:
- func = __messages_load_locale;
- break;
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ case LC_TIME:
+ return (loc->locdata[cat]->l_lname);
+ case LC_ALL:
+ return (loc->locname);
default:
- errno = EINVAL;
return (NULL);
}
-
- if (strcmp(new, old) == 0)
- return (old);
-
- if (func(new) != _LDP_ERROR) {
- (void) strcpy(old, new);
- return (old);
- }
-
- return (NULL);
}
-static const char *
-__get_locale_env(int category)
+static void
+install_legacy(locale_t loc, int mask)
{
- const char *env;
-
- /* 1. check LC_ALL. */
- env = getenv(categories[LC_ALL]);
-
- /* 2. check LC_* */
- if (env == NULL || !*env)
- env = getenv(categories[category]);
+ /*
+ * Update the legacy fixed variables that may be baked into
+ * legacy programs. This is really unfortunate, but we can't
+ * solve for them otherwise. Note that such legacy programs
+ * are only going to see the global locale settings, and cannot
+ * benefit from uselocale().
+ */
+ if (mask & LC_NUMERIC_MASK) {
+ struct lc_numeric *lnum;
+ lnum = loc->locdata[LC_NUMERIC]->l_data[0];
+ _numeric[0] = *lnum->decimal_point;
+ _numeric[1] = *lnum->thousands_sep;
+ }
- /* 3. check LANG */
- if (env == NULL || !*env)
- env = getenv("LANG");
+ if (mask & LC_CTYPE_MASK) {
+ struct lc_ctype *lct;
+ lct = loc->locdata[LC_CTYPE]->l_data[0];
+ for (int i = 0; i < _CACHED_RUNES; i++) {
+ /* ctype can only encode the lower 8 bits. */
+ __ctype[i+1] = lct->lc_ctype_mask[i] & 0xff;
+ __ctype_mask[i] = lct->lc_ctype_mask[i];
+ }
- /* 4. if none is set, fall to "C" */
- if (env == NULL || !*env)
- env = "C";
+ /* The bottom half is the toupper/lower array */
+ for (int i = 0; i < _CACHED_RUNES; i++) {
+ int u, l;
+ __ctype[258 + i] = i;
+ u = lct->lc_trans_upper[i];
+ l = lct->lc_trans_lower[i];
+ if (u && u != i)
+ __ctype[258+i] = u;
+ if (l && l != i)
+ __ctype[258+i] = l;
+
+ /* Don't forget these annoyances either! */
+ __trans_upper[i] = u;
+ __trans_lower[i] = l;
+ }
- return (env);
+ /* Maximum mblen, cswidth, weird legacy */
+ __ctype[520] = lct->lc_max_mblen;
+ }
}
diff --git a/usr/src/lib/libc/port/locale/setlocale.h b/usr/src/lib/libc/port/locale/setlocale.h
index ee27ed804a..79af54e8d4 100644
--- a/usr/src/lib/libc/port/locale/setlocale.h
+++ b/usr/src/lib/libc/port/locale/setlocale.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia.
* All rights reserved.
*
@@ -33,7 +34,4 @@
extern char *_PathLocale;
-int __detect_path_locale(void);
-int __wrap_setrunelocale(const char *);
-
#endif /* !_SETLOCALE_H_ */
diff --git a/usr/src/lib/libc/port/locale/setrunelocale.c b/usr/src/lib/libc/port/locale/setrunelocale.c
index d56c0029ac..7f6cabdc4a 100644
--- a/usr/src/lib/libc/port/locale/setrunelocale.c
+++ b/usr/src/lib/libc/port/locale/setrunelocale.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -45,208 +46,103 @@
#include "mblocal.h"
#include "setlocale.h"
#include "_ctype.h"
-#include "../i18n/_locale.h"
+#include "lctype.h"
+#include "localeimpl.h"
+
+extern _RuneLocale *_Read_RuneMagi(const char *);
+
+struct lc_ctype lc_ctype_posix = {
+ .lc_mbrtowc = __mbrtowc_ascii,
+ .lc_mbsinit = __mbsinit_ascii,
+ .lc_mbsnrtowcs = __mbsnrtowcs_ascii,
+ .lc_wcrtomb = __wcrtomb_ascii,
+ .lc_wcsnrtombs = __wcsnrtombs_ascii,
+ .lc_is_ascii = 1,
+ .lc_max_mblen = 1,
+ .lc_trans_upper = _DefaultRuneLocale.__mapupper,
+ .lc_trans_lower = _DefaultRuneLocale.__maplower,
+ .lc_ctype_mask = _DefaultRuneLocale.__runetype,
+};
+
+struct locdata __posix_ctype_locdata = {
+ .l_lname = "C",
+ .l_data = { &lc_ctype_posix, &_DefaultRuneLocale }
+};
-extern _RuneLocale *_Read_RuneMagi(FILE *);
-extern unsigned char __ctype_C[];
-static int __setrunelocale(const char *);
-
-static int
-__setrunelocale(const char *encoding)
+/*
+ * Table of initializers for encodings. When you add a new encoding type,
+ * this table should be updated.
+ */
+static struct {
+ const char *e_name;
+ void (*e_init)(struct lc_ctype *);
+} encodings[] = {
+ { "NONE", _none_init },
+ { "UTF-8", _UTF8_init },
+ { "EUC-CN", _EUC_CN_init },
+ { "EUC-JP", _EUC_JP_init },
+ { "EUC-KR", _EUC_KR_init },
+ { "EUC-TW", _EUC_TW_init },
+ { "GB18030", _GB18030_init },
+ { "GB2312", _GB2312_init },
+ { "GBK", _GBK_init },
+ { "BIG5", _BIG5_init },
+ { "MSKanji", _MSKanji_init },
+ { NULL, NULL }
+};
+
+
+struct locdata *
+__lc_ctype_load(const char *name)
{
- FILE *fp;
- char name[PATH_MAX];
+ struct locdata *ldata;
+ struct lc_ctype *lct;
_RuneLocale *rl;
- int saverr, ret;
- size_t (*old__mbrtowc)(wchar_t *_RESTRICT_KYWD,
- const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
- size_t (*old__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
- mbstate_t *_RESTRICT_KYWD);
- int (*old__mbsinit)(const mbstate_t *);
- size_t (*old__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
- const char **_RESTRICT_KYWD, size_t, size_t,
- mbstate_t *_RESTRICT_KYWD);
- size_t (*old__wcsnrtombs)(char *_RESTRICT_KYWD,
- const wchar_t **_RESTRICT_KYWD, size_t, size_t,
- mbstate_t *_RESTRICT_KYWD);
- static char ctype_encoding[ENCODING_LEN + 1];
- static _RuneLocale *CachedRuneLocale;
- static size_t (*Cached__mbrtowc)(wchar_t *_RESTRICT_KYWD,
- const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
- static size_t (*Cached__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
- mbstate_t *_RESTRICT_KYWD);
- static int (*Cached__mbsinit)(const mbstate_t *);
- static size_t (*Cached__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
- const char **_RESTRICT_KYWD, size_t, size_t,
- mbstate_t *_RESTRICT_KYWD);
- static size_t (*Cached__wcsnrtombs)(char *_RESTRICT_KYWD,
- const wchar_t **_RESTRICT_KYWD, size_t, size_t,
- mbstate_t *_RESTRICT_KYWD);
-
- /*
- * The "C" and "POSIX" locale are always here.
- */
- if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
- int i;
-
- (void) memcpy(__ctype, __ctype_C, SZ_TOTAL);
-
- for (i = 0; i < _CACHED_RUNES; i++) {
- __ctype_mask[i] = _DefaultRuneLocale.__runetype[i];
- __trans_upper[i] = _DefaultRuneLocale.__mapupper[i];
- __trans_lower[i] = _DefaultRuneLocale.__maplower[i];
- }
-
- (void) _none_init(&_DefaultRuneLocale);
- return (0);
- }
-
- /*
- * If the locale name is the same as our cache, use the cache.
- */
- if (CachedRuneLocale != NULL &&
- strcmp(encoding, ctype_encoding) == 0) {
- _CurrentRuneLocale = CachedRuneLocale;
- __mbrtowc = Cached__mbrtowc;
- __mbsinit = Cached__mbsinit;
- __mbsnrtowcs = Cached__mbsnrtowcs;
- __wcrtomb = Cached__wcrtomb;
- __wcsnrtombs = Cached__wcsnrtombs;
- return (0);
- }
+ int i;
+ char path[PATH_MAX];
+ if ((ldata = __locdata_alloc(name, sizeof (*lct))) == NULL)
+ return (NULL);
+ lct = ldata->l_data[0];
/*
* Slurp the locale file into the cache.
*/
- (void) snprintf(name, sizeof (name), "%s/%s/LC_CTYPE/LCL_DATA",
- _PathLocale, encoding);
-
- if ((fp = fopen(name, "r")) == NULL)
- return (errno == 0 ? ENOENT : errno);
+ (void) snprintf(path, sizeof (path), "%s/%s/LC_CTYPE/LCL_DATA",
+ _PathLocale, name);
- if ((rl = _Read_RuneMagi(fp)) == NULL) {
- saverr = (errno == 0 ? EINVAL : errno);
- (void) fclose(fp);
- return (saverr);
+ if ((rl = _Read_RuneMagi(path)) == NULL) {
+ __locdata_free(ldata);
+ errno = EINVAL;
+ return (NULL);
}
- (void) fclose(fp);
-
- old__mbrtowc = __mbrtowc;
- old__mbsinit = __mbsinit;
- old__mbsnrtowcs = __mbsnrtowcs;
- old__wcrtomb = __wcrtomb;
- old__wcsnrtombs = __wcsnrtombs;
-
- __mbrtowc = NULL;
- __mbsinit = NULL;
- __mbsnrtowcs = __mbsnrtowcs_std;
- __wcrtomb = NULL;
- __wcsnrtombs = __wcsnrtombs_std;
-
- if (strcmp(rl->__encoding, "NONE") == 0)
- ret = _none_init(rl);
- else if (strcmp(rl->__encoding, "UTF-8") == 0)
- ret = _UTF8_init(rl);
- else if (strcmp(rl->__encoding, "EUC-CN") == 0)
- ret = _EUC_CN_init(rl);
- else if (strcmp(rl->__encoding, "EUC-JP") == 0)
- ret = _EUC_JP_init(rl);
- else if (strcmp(rl->__encoding, "EUC-KR") == 0)
- ret = _EUC_KR_init(rl);
- else if (strcmp(rl->__encoding, "EUC-TW") == 0)
- ret = _EUC_TW_init(rl);
- else if (strcmp(rl->__encoding, "GB18030") == 0)
- ret = _GB18030_init(rl);
- else if (strcmp(rl->__encoding, "GB2312") == 0)
- ret = _GB2312_init(rl);
- else if (strcmp(rl->__encoding, "GBK") == 0)
- ret = _GBK_init(rl);
- else if (strcmp(rl->__encoding, "BIG5") == 0)
- ret = _BIG5_init(rl);
- else if (strcmp(rl->__encoding, "MSKanji") == 0)
- ret = _MSKanji_init(rl);
- else
- ret = EINVAL;
-
- if (ret == 0) {
- if (CachedRuneLocale != NULL) {
- free(CachedRuneLocale);
- }
- CachedRuneLocale = _CurrentRuneLocale;
- Cached__mbrtowc = __mbrtowc;
- Cached__mbsinit = __mbsinit;
- Cached__mbsnrtowcs = __mbsnrtowcs;
- Cached__wcrtomb = __wcrtomb;
- Cached__wcsnrtombs = __wcsnrtombs;
- (void) strcpy(ctype_encoding, encoding);
-
- /*
- * We need to overwrite the _ctype array. This requires
- * some finagling. This is because references to it may
- * have been baked into applications.
- *
- * Note that it is interesting that toupper/tolower only
- * produce defined results when the input is representable
- * as a byte.
- */
-
- /*
- * The top half is the type mask array. Because we
- * want to support both legacy Solaris code (which have
- * mask valeus baked in to them), and we want to be able
- * to import locale files from other sources (FreeBSD)
- * which probably uses different masks, we have to perform
- * a conversion here. Ugh. Note that the _CTYPE definitions
- * we use from FreeBSD are richer than the Solaris legacy.
- *
- * We have to cope with these limitations though, because the
- * inadequate Solaris definitions were baked into binaries.
- */
- for (int i = 0; i < _CACHED_RUNES; i++) {
- /* ctype can only encode the lower 8 bits. */
- __ctype[i+1] = rl->__runetype[i] & 0xff;
- __ctype_mask[i] = rl->__runetype[i];
- }
-
- /* The bottom half is the toupper/lower array */
- for (int i = 0; i < _CACHED_RUNES; i++) {
- __ctype[258 + i] = i;
- if (rl->__mapupper[i] && rl->__mapupper[i] != i)
- __ctype[258+i] = rl->__mapupper[i];
- if (rl->__maplower[i] && rl->__maplower[i] != i)
- __ctype[258+i] = rl->__maplower[i];
-
- /* Don't forget these annoyances either! */
- __trans_upper[i] = rl->__mapupper[i];
- __trans_lower[i] = rl->__maplower[i];
+ ldata->l_data[1] = rl;
+
+ lct->lc_mbrtowc = NULL;
+ lct->lc_mbsinit = NULL;
+ lct->lc_mbsnrtowcs = NULL;
+ lct->lc_wcrtomb = NULL;
+ lct->lc_wcsnrtombs = NULL;
+ lct->lc_ctype_mask = rl->__runetype;
+ lct->lc_trans_upper = rl->__mapupper;
+ lct->lc_trans_lower = rl->__maplower;
+
+ /* set up the function pointers */
+ for (i = 0; encodings[i].e_name != NULL; i++) {
+ int l = strlen(encodings[i].e_name);
+ if ((strncmp(rl->__encoding, encodings[i].e_name, l) == 0) &&
+ (rl->__encoding[l] == '\0' || rl->__encoding[l] == '@')) {
+ encodings[i].e_init(lct);
+ break;
}
-
- /*
- * Note that we expect the init code will have populated
- * the CSWIDTH array (__ctype[514-520]) properly.
- */
- } else {
- __mbrtowc = old__mbrtowc;
- __mbsinit = old__mbsinit;
- __mbsnrtowcs = old__mbsnrtowcs;
- __wcrtomb = old__wcrtomb;
- __wcsnrtombs = old__wcsnrtombs;
- free(rl);
+ }
+ if (encodings[i].e_name == NULL) {
+ __locdata_free(ldata);
+ errno = EINVAL;
+ return (NULL);
}
- return (ret);
-}
-
-int
-__wrap_setrunelocale(const char *locale)
-{
- int ret = __setrunelocale(locale);
- if (ret != 0) {
- errno = ret;
- return (_LDP_ERROR);
- }
- return (_LDP_LOADED);
+ return (ldata);
}
diff --git a/usr/src/lib/libc/port/i18n/strcasecmp.c b/usr/src/lib/libc/port/locale/strcasecmp.c
index 44bcf2c9e4..03da7cec5d 100644
--- a/usr/src/lib/libc/port/i18n/strcasecmp.c
+++ b/usr/src/lib/libc/port/locale/strcasecmp.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -35,24 +36,27 @@
#include <sys/types.h>
#include <strings.h>
#include <ctype.h>
+#include <locale.h>
+#include "localeimpl.h"
+#include "lctype.h"
int
-strcasecmp(const char *s1, const char *s2)
+strcasecmp_l(const char *s1, const char *s2, locale_t loc)
{
- extern int charset_is_ascii;
extern int ascii_strcasecmp(const char *s1, const char *s2);
- int *cm;
+ const int *cm;
const uchar_t *us1;
const uchar_t *us2;
+ const struct lc_ctype *lct = loc->ctype;
/*
* If we are in a locale that uses the ASCII character set
* (C or POSIX), use the fast ascii_strcasecmp() function.
*/
- if (charset_is_ascii)
+ if (lct->lc_is_ascii)
return (ascii_strcasecmp(s1, s2));
- cm = __trans_lower;
+ cm = lct->lc_trans_lower;
us1 = (const uchar_t *)s1;
us2 = (const uchar_t *)s2;
@@ -61,3 +65,10 @@ strcasecmp(const char *s1, const char *s2)
return (0);
return (cm[*us1] - cm[*(us2 - 1)]);
}
+
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ /* would be nice to avoid uselocale()... but I don't see how */
+ return (strcasecmp_l(s1, s2, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/i18n/strcasestr.c b/usr/src/lib/libc/port/locale/strcasestr.c
index a8f590263a..8791f44560 100644
--- a/usr/src/lib/libc/port/i18n/strcasestr.c
+++ b/usr/src/lib/libc/port/locale/strcasestr.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -30,6 +31,9 @@
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
+#include <locale.h>
+#include "lctype.h"
+#include "localeimpl.h"
/*
* strcasestr() locates the first occurrence in the string s1 of the
@@ -40,9 +44,9 @@
*/
char *
-strcasestr(const char *s1, const char *s2)
+strcasestr_l(const char *s1, const char *s2, locale_t loc)
{
- int *cm = __trans_lower;
+ const int *cm = loc->ctype->lc_trans_lower;
const uchar_t *us1 = (const uchar_t *)s1;
const uchar_t *us2 = (const uchar_t *)s2;
const uchar_t *tptr;
@@ -67,3 +71,9 @@ strcasestr(const char *s1, const char *s2)
return (NULL);
}
+
+char *
+strcasestr(const char *s1, const char *s2)
+{
+ return (strcasestr_l(s1, s2, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/strcoll.c b/usr/src/lib/libc/port/locale/strcoll.c
index be20f23e0b..55cf459215 100644
--- a/usr/src/lib/libc/port/locale/strcoll.c
+++ b/usr/src/lib/libc/port/locale/strcoll.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
@@ -33,6 +34,8 @@
#include <string.h>
#include <errno.h>
#include <wchar.h>
+#include <xlocale.h>
+#include "localeimpl.h"
#include "collate.h"
#define ALLOCA_LIMIT 16
@@ -44,15 +47,19 @@
* should check errno.
*/
int
-strcoll(const char *s1, const char *s2)
+strcoll_l(const char *s1, const char *s2, locale_t loc)
{
int ret;
wchar_t *t1 = NULL, *t2 = NULL;
wchar_t *w1 = NULL, *w2 = NULL;
size_t sz1, sz2;
+ const struct lc_collate *lcc = loc->collate;
- if (_collate_load_error)
- goto error;
+ mbstate_t mbs1 = { 0 }; /* initial states */
+ mbstate_t mbs2 = { 0 };
+
+ if (lcc->lc_is_posix)
+ return (strcmp(s1, s2));
sz1 = strlen(s1) + 1;
sz2 = strlen(s2) + 1;
@@ -82,13 +89,13 @@ strcoll(const char *s1, const char *s2)
goto error;
}
- if ((mbstowcs(w1, s1, sz1)) == (size_t)-1)
+ if ((mbsrtowcs_l(w1, &s1, sz1, &mbs1, loc)) == (size_t)-1)
goto error;
- if ((mbstowcs(w2, s2, sz2)) == (size_t)-1)
+ if ((mbsrtowcs_l(w2, &s2, sz2, &mbs2, loc)) == (size_t)-1)
goto error;
- ret = wcscoll(w1, w2);
+ ret = wcscoll_l(w1, w2, loc);
if (t1)
free(t1);
if (t2)
@@ -103,3 +110,9 @@ error:
free(t2);
return (strcmp(s1, s2));
}
+
+int
+strcoll(const char *s1, const char *s2)
+{
+ return (strcoll_l(s1, s2, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/strfmon.c b/usr/src/lib/libc/port/locale/strfmon.c
index 18ba631ddc..cc90ddf9f1 100644
--- a/usr/src/lib/libc/port/locale/strfmon.c
+++ b/usr/src/lib/libc/port/locale/strfmon.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
@@ -41,6 +42,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "localeimpl.h"
+#include "lmonetary.h"
+#include "lnumeric.h"
/* internal flags */
#define NEED_GROUPING 0x01 /* print digits grouped (default) */
@@ -60,7 +64,7 @@
}
#define PRINTS(STR) { \
- char *tmps = STR; \
+ const char *tmps = STR; \
while (*tmps != '\0') \
PRINT(*tmps++); \
}
@@ -87,22 +91,23 @@
}
#define GRPSEP { \
- *--bufend = thousands_sep; \
+ bufend -= thousands_len; \
+ (void) memcpy(bufend, thousands_sep, thousands_len); \
groups++; \
}
-static void __setup_vars(int, char *, char *, char *, char **);
-static int __calc_left_pad(int, char *);
-static char *__format_grouped_double(double, int *, int, int, int);
+static void setup_vars(const struct lc_monetary *, int, char *, char *, char *,
+ const char **);
+static int calc_left_pad(const struct lc_monetary *, int, const char *);
+static char *format_grouped_double(const struct lc_monetary *,
+ const struct lc_numeric *, double, int *, int, int, int);
ssize_t
-strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
- const char *_RESTRICT_KYWD format, ...)
+strfmon_impl(char *_RESTRICT_KYWD s, size_t maxsize, locale_t loc,
+ const char *_RESTRICT_KYWD format, va_list ap)
{
- va_list ap;
char *dst; /* output destination pointer */
const char *fmt; /* current format poistion pointer */
- struct lconv *lc; /* pointer to lconv structure */
char *asciivalue; /* formatted double pointer */
int flags; /* formatting options */
@@ -114,18 +119,20 @@ strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
double value; /* just value */
char space_char = ' '; /* space after currency */
- char cs_precedes; /* values gathered from struct lconv */
+ char cs_precedes; /* values from struct lc_monetary */
char sep_by_space;
char sign_posn;
- char *signstr;
- char *currency_symbol;
+ const char *signstr;
+ const char *currency_symbol;
char *tmpptr; /* temporary vars */
int sverrno;
+ const struct lc_monetary *lmon; /* monetary structure */
+ const struct lc_numeric *lnum; /* numeric structure */
- va_start(ap, format);
+ lmon = loc->monetary;
+ lnum = loc->numeric;
- lc = localeconv();
dst = s;
fmt = format;
asciivalue = NULL;
@@ -231,17 +238,13 @@ strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
goto format_error;
}
- if (currency_symbol != NULL)
- free(currency_symbol);
if (flags & USE_INTL_CURRENCY) {
- currency_symbol = strdup(lc->int_curr_symbol);
+ currency_symbol = lmon->int_curr_symbol;
+ /* by definition three letters followed by a space */
if (currency_symbol != NULL)
- space_char = *(currency_symbol+3);
+ space_char = currency_symbol[3];
} else
- currency_symbol = strdup(lc->currency_symbol);
-
- if (currency_symbol == NULL)
- goto end_error; /* ENOMEM. */
+ currency_symbol = lmon->currency_symbol;
/* value itself */
value = va_arg(ap, double);
@@ -254,24 +257,24 @@ strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
/* fill left_prec with amount of padding chars */
if (left_prec >= 0) {
- pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),
+ pad_size = calc_left_pad(lmon, (flags ^ IS_NEGATIVE),
currency_symbol) -
- __calc_left_pad(flags, currency_symbol);
+ calc_left_pad(lmon, flags, currency_symbol);
if (pad_size < 0)
pad_size = 0;
}
if (asciivalue != NULL)
free(asciivalue);
- asciivalue = __format_grouped_double(value, &flags,
+ asciivalue = format_grouped_double(lmon, lnum, value, &flags,
left_prec, right_prec, pad_char);
if (asciivalue == NULL)
goto end_error; /* errno already set */
/* to ENOMEM by malloc() */
/* set some variables for later use */
- __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn,
- &signstr);
+ setup_vars(lmon, flags, &cs_precedes, &sep_by_space,
+ &sign_posn, &signstr);
/*
* Description of some LC_MONETARY's values:
@@ -315,7 +318,7 @@ strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
if (cs_precedes == 1) {
if (sign_posn == 1 || sign_posn == 3) {
PRINTS(signstr);
- if (sep_by_space == 2) /* XXX: ? */
+ if (sep_by_space == 2)
PRINT(' ');
}
@@ -382,9 +385,7 @@ strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
}
PRINT('\0');
- va_end(ap);
free(asciivalue);
- free(currency_symbol);
return (dst - s - 1); /* size of put data except trailing '\0' */
e2big_error:
@@ -398,45 +399,66 @@ end_error:
sverrno = errno;
if (asciivalue != NULL)
free(asciivalue);
- if (currency_symbol != NULL)
- free(currency_symbol);
errno = sverrno;
- va_end(ap);
return (-1);
}
-static void
-__setup_vars(int flags, char *cs_precedes, char *sep_by_space,
- char *sign_posn, char **signstr)
+ssize_t
+strfmon(char *_RESTRICT_KYWD s, size_t maxsize,
+ const char *_RESTRICT_KYWD format, ...)
{
+ va_list ap;
+ ssize_t ret;
+
+ va_start(ap, format);
+ ret = strfmon_impl(s, maxsize, uselocale(NULL), format, ap);
+ va_end(ap);
+ return (ret);
+}
- struct lconv *lc = localeconv();
+ssize_t
+strfmon_l(char *_RESTRICT_KYWD s, size_t maxsize, locale_t loc,
+ const char *_RESTRICT_KYWD format, ...)
+{
+ ssize_t ret;
+ va_list ap;
+ va_start(ap, format);
+ ret = strfmon_impl(s, maxsize, loc, format, ap);
+ va_end(ap);
+ return (ret);
+}
+static void
+setup_vars(const struct lc_monetary *lmon, int flags, char *cs_precedes,
+ char *sep_by_space, char *sign_posn, const char **signstr)
+{
if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
- *cs_precedes = lc->int_n_cs_precedes;
- *sep_by_space = lc->int_n_sep_by_space;
- *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn;
- *signstr = (lc->negative_sign[0] == '\0') ? "-"
- : lc->negative_sign;
+ *cs_precedes = lmon->int_n_cs_precedes[0];
+ *sep_by_space = lmon->int_n_sep_by_space[0];
+ *sign_posn = (flags & PARENTH_POSN) ? 0 :
+ lmon->int_n_sign_posn[0];
+ *signstr = (lmon->negative_sign[0] == '\0') ? "-" :
+ lmon->negative_sign;
} else if (flags & USE_INTL_CURRENCY) {
- *cs_precedes = lc->int_p_cs_precedes;
- *sep_by_space = lc->int_p_sep_by_space;
- *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_p_sign_posn;
- *signstr = lc->positive_sign;
+ *cs_precedes = lmon->int_p_cs_precedes[0];
+ *sep_by_space = lmon->int_p_sep_by_space[0];
+ *sign_posn = (flags & PARENTH_POSN) ? 0 :
+ lmon->int_p_sign_posn[0];
+ *signstr = lmon->positive_sign;
} else if (flags & IS_NEGATIVE) {
- *cs_precedes = lc->n_cs_precedes;
- *sep_by_space = lc->n_sep_by_space;
- *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn;
- *signstr = (lc->negative_sign[0] == '\0') ? "-"
- : lc->negative_sign;
+ *cs_precedes = lmon->n_cs_precedes[0];
+ *sep_by_space = lmon->n_sep_by_space[0];
+ *sign_posn = (flags & PARENTH_POSN) ? 0 : lmon->n_sign_posn[0];
+ *signstr = (lmon->negative_sign[0] == '\0') ? "-" :
+ lmon->negative_sign;
} else {
- *cs_precedes = lc->p_cs_precedes;
- *sep_by_space = lc->p_sep_by_space;
- *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->p_sign_posn;
- *signstr = lc->positive_sign;
+ *cs_precedes = lmon->p_cs_precedes[0];
+ *sep_by_space = lmon->p_sep_by_space[0];
+ *sign_posn = (flags & PARENTH_POSN) ? 0 : lmon->p_sign_posn[0];
+ *signstr = lmon->positive_sign;
}
- /* Set defult values for unspecified information. */
+ /* Set default values for unspecified information. */
if (*cs_precedes != 0)
*cs_precedes = 1;
if (*sep_by_space == CHAR_MAX)
@@ -446,13 +468,14 @@ __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
}
static int
-__calc_left_pad(int flags, char *cur_symb)
+calc_left_pad(const struct lc_monetary *lmon, int flags, const char *cur_symb)
{
-
- char cs_precedes, sep_by_space, sign_posn, *signstr;
+ char cs_precedes, sep_by_space, sign_posn;
+ const char *signstr;
int left_chars = 0;
- __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
+ setup_vars(lmon, flags, &cs_precedes, &sep_by_space, &sign_posn,
+ &signstr);
if (cs_precedes != 0) {
left_chars += strlen(cur_symb);
@@ -473,7 +496,7 @@ __calc_left_pad(int flags, char *cur_symb)
}
static int
-get_groups(int size, char *grouping)
+get_groups(int size, const char *grouping)
{
int chars = 0;
@@ -498,8 +521,9 @@ get_groups(int size, char *grouping)
/* convert double to ASCII */
static char *
-__format_grouped_double(double value, int *flags,
- int left_prec, int right_prec, int pad_char)
+format_grouped_double(const struct lc_monetary *lmon,
+ const struct lc_numeric *lnum,
+ double value, int *flags, int left_prec, int right_prec, int pad_char)
{
char *rslt;
@@ -512,20 +536,24 @@ __format_grouped_double(double value, int *flags,
int padded;
- struct lconv *lc = localeconv();
- char *grouping;
- char decimal_point;
- char thousands_sep;
+ const char *grouping;
+ const char *decimal_point;
+ const char *thousands_sep;
+ int decimal_len;
+ int thousands_len;
int groups = 0;
- grouping = lc->mon_grouping;
- decimal_point = *lc->mon_decimal_point;
- if (decimal_point == '\0')
- decimal_point = *lc->decimal_point;
- thousands_sep = *lc->mon_thousands_sep;
- if (thousands_sep == '\0')
- thousands_sep = *lc->thousands_sep;
+ grouping = lmon->mon_grouping;
+ decimal_point = lmon->mon_decimal_point;
+ if (*decimal_point == '\0')
+ decimal_point = lnum->decimal_point;
+ thousands_sep = lmon->mon_thousands_sep;
+ if (*thousands_sep == '\0')
+ thousands_sep = lnum->thousands_sep;
+
+ decimal_len = strlen(decimal_point); /* usually 1 */
+ thousands_len = strlen(thousands_sep); /* 0 or 1 usually */
/* fill left_prec with default value */
if (left_prec == -1)
@@ -534,9 +562,9 @@ __format_grouped_double(double value, int *flags,
/* fill right_prec with default value */
if (right_prec == -1) {
if (*flags & USE_INTL_CURRENCY)
- right_prec = lc->int_frac_digits;
+ right_prec = lmon->int_frac_digits[0];
else
- right_prec = lc->frac_digits;
+ right_prec = lmon->frac_digits[0];
if (right_prec == CHAR_MAX) /* POSIX locale ? */
right_prec = 2;
@@ -552,7 +580,15 @@ __format_grouped_double(double value, int *flags,
if (avalue_size < 0)
return (NULL);
- /* make sure that we've enough space for result string */
+ /*
+ * Make sure that we've enough space for result string.
+ * This assumes that digits take up at least much space as
+ * grouping and radix characters. The worst case currently known
+ * is for Arabic, where two-byte UTF-8 sequences are used for both
+ * decimal and thousands seperators, and groups can be a small as two
+ * decimal digits. This will do no worse than doubling the storage
+ * requirement.
+ */
bufsize = strlen(avalue)*2+1;
rslt = calloc(1, bufsize);
if (rslt == NULL) {
@@ -561,7 +597,7 @@ __format_grouped_double(double value, int *flags,
}
bufend = rslt + bufsize - 1; /* reserve space for trailing '\0' */
- /* skip spaces at beggining */
+ /* skip spaces at beginning */
padded = 0;
while (avalue[padded] == ' ') {
padded++;
@@ -572,12 +608,13 @@ __format_grouped_double(double value, int *flags,
bufend -= right_prec;
(void) memcpy(bufend, avalue + avalue_size+padded-right_prec,
right_prec);
- *--bufend = decimal_point;
- avalue_size -= (right_prec + 1);
+ bufend -= decimal_len;
+ (void) memcpy(bufend, decimal_point, decimal_len);
+ avalue_size -= (right_prec + decimal_len);
}
if ((*flags & NEED_GROUPING) &&
- thousands_sep != '\0' && /* XXX: need investigation */
+ thousands_len != 0 &&
*grouping != CHAR_MAX &&
*grouping > 0) {
while (avalue_size > (int)*grouping) {
diff --git a/usr/src/lib/libc/port/locale/strftime.c b/usr/src/lib/libc/port/locale/strftime.c
index 9e8d4cbe56..b314151838 100644
--- a/usr/src/lib/libc/port/locale/strftime.c
+++ b/usr/src/lib/libc/port/locale/strftime.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
@@ -22,11 +23,14 @@
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
+#include <locale.h>
#include "timelocal.h"
+#include "localeimpl.h"
static char *_add(const char *, char *, const char *);
static char *_conv(int, const char *, char *, const char *);
-static char *_fmt(const char *, const struct tm *, char *, const char * const);
+static char *_fmt(locale_t, const char *, const struct tm *, char *,
+ const char * const);
static char *_yconv(int, int, int, int, char *, const char *);
extern char *tzname[];
@@ -62,24 +66,33 @@ static const char *fmt_padding[][4] = {
size_t
-strftime(char *_RESTRICT_KYWD s, size_t maxsize,
- const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
+strftime_l(char *_RESTRICT_KYWD s, size_t maxsize,
+ const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t,
+ locale_t loc)
{
char *p;
tzset();
- p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
+ p = _fmt(loc, ((format == NULL) ? "%c" : format), t, s, s + maxsize);
if (p == s + maxsize)
return (0);
*p = '\0';
return (p - s);
}
+size_t
+strftime(char *_RESTRICT_KYWD s, size_t maxsize,
+ const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
+{
+ return (strftime_l(s, maxsize, format, t, uselocale(NULL)));
+}
+
static char *
-_fmt(const char *format, const struct tm *t, char *pt, const char * const ptlim)
+_fmt(locale_t loc, const char *format, const struct tm *t, char *pt,
+ const char * const ptlim)
{
int Ealternative, Oalternative, PadIndex;
- struct lc_time_T *tptr = __get_current_time_locale();
+ const struct lc_time *tptr = loc->time;
#define PADDING(x) fmt_padding[x][PadIndex]
@@ -130,10 +143,10 @@ label:
pt, ptlim);
continue;
case 'c':
- pt = _fmt(tptr->c_fmt, t, pt, ptlim);
+ pt = _fmt(loc, tptr->c_fmt, t, pt, ptlim);
continue;
case 'D':
- pt = _fmt("%m/%d/%y", t, pt, ptlim);
+ pt = _fmt(loc, "%m/%d/%y", t, pt, ptlim);
continue;
case 'd':
pt = _conv(t->tm_mday,
@@ -163,7 +176,7 @@ label:
PADDING(PAD_FMT_SDAYOFMONTH), pt, ptlim);
continue;
case 'F':
- pt = _fmt("%Y-%m-%d", t, pt, ptlim);
+ pt = _fmt(loc, "%Y-%m-%d", t, pt, ptlim);
continue;
case 'H':
pt = _conv(t->tm_hour, PADDING(PAD_FMT_HMS),
@@ -223,10 +236,10 @@ label:
tptr->pm : tptr->am, pt, ptlim);
continue;
case 'R':
- pt = _fmt("%H:%M", t, pt, ptlim);
+ pt = _fmt(loc, "%H:%M", t, pt, ptlim);
continue;
case 'r':
- pt = _fmt(tptr->ampm_fmt, t, pt, ptlim);
+ pt = _fmt(loc, tptr->ampm_fmt, t, pt, ptlim);
continue;
case 'S':
pt = _conv(t->tm_sec, PADDING(PAD_FMT_HMS),
@@ -245,7 +258,7 @@ label:
}
case 'T':
- pt = _fmt("%H:%M:%S", t, pt, ptlim);
+ pt = _fmt(loc, "%H:%M:%S", t, pt, ptlim);
continue;
case 't':
pt = _add("\t", pt, ptlim);
@@ -357,7 +370,7 @@ label:
* "date as dd-bbb-YYYY"
* (ado, 1993-05-24)
*/
- pt = _fmt("%e-%b-%Y", t, pt, ptlim);
+ pt = _fmt(loc, "%e-%b-%Y", t, pt, ptlim);
continue;
case 'W':
pt = _conv((t->tm_yday + DAYSPERWEEK -
@@ -371,10 +384,10 @@ label:
pt = _conv(t->tm_wday, "%d", pt, ptlim);
continue;
case 'X':
- pt = _fmt(tptr->X_fmt, t, pt, ptlim);
+ pt = _fmt(loc, tptr->X_fmt, t, pt, ptlim);
continue;
case 'x':
- pt = _fmt(tptr->x_fmt, t, pt, ptlim);
+ pt = _fmt(loc, tptr->x_fmt, t, pt, ptlim);
continue;
case 'y':
pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
@@ -438,7 +451,7 @@ label:
}
continue;
case '+':
- pt = _fmt(tptr->date_fmt, t, pt, ptlim);
+ pt = _fmt(loc, tptr->date_fmt, t, pt, ptlim);
continue;
case '-':
if (PadIndex != PAD_DEFAULT)
diff --git a/usr/src/lib/libc/port/i18n/strncasecmp.c b/usr/src/lib/libc/port/locale/strncasecmp.c
index 67c6687e08..32ae17c8a2 100644
--- a/usr/src/lib/libc/port/i18n/strncasecmp.c
+++ b/usr/src/lib/libc/port/locale/strncasecmp.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -35,24 +36,27 @@
#include <sys/types.h>
#include <strings.h>
#include <ctype.h>
+#include <locale.h>
+#include "lctype.h"
+#include "localeimpl.h"
int
-strncasecmp(const char *s1, const char *s2, size_t n)
+strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t loc)
{
- extern int charset_is_ascii;
extern int ascii_strncasecmp(const char *s1, const char *s2, size_t n);
- int *cm;
+ const int *cm;
const uchar_t *us1;
const uchar_t *us2;
+ const struct lc_ctype *lct = loc->ctype;
/*
* If we are in a locale that uses the ASCII character set
* (C or POSIX), use the fast ascii_strncasecmp() function.
*/
- if (charset_is_ascii)
+ if (lct->lc_is_ascii)
return (ascii_strncasecmp(s1, s2, n));
- cm = __trans_lower;
+ cm = lct->lc_trans_lower;
us1 = (const uchar_t *)s1;
us2 = (const uchar_t *)s2;
@@ -63,3 +67,9 @@ strncasecmp(const char *s1, const char *s2, size_t n)
}
return (n == 0 ? 0 : cm[*us1] - cm[*(us2 - 1)]);
}
+
+int
+strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ return (strncasecmp_l(s1, s2, n, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/strptime.c b/usr/src/lib/libc/port/locale/strptime.c
index 90150e37e9..f5be4eba8c 100644
--- a/usr/src/lib/libc/port/locale/strptime.c
+++ b/usr/src/lib/libc/port/locale/strptime.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014 Gary Mills
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2011, Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1994 Powerdog Industries. All rights reserved.
*
@@ -40,31 +41,30 @@
#include <string.h>
#include <pthread.h>
#include <alloca.h>
+#include <locale.h>
#include "timelocal.h"
+#include "localeimpl.h"
#define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
#define F_GMT (1 << 0)
-#define F_ZERO (1 << 1)
#define F_RECURSE (1 << 2)
static char *
-__strptime(const char *buf, const char *fmt, struct tm *tm, int *flagsp)
+__strptime(const char *_RESTRICT_KYWD buf, const char *_RESTRICT_KYWD fmt,
+ struct tm *_RESTRICT_KYWD tm, int *_RESTRICT_KYWD flagsp,
+ locale_t _RESTRICT_KYWD loc)
{
char c;
const char *ptr;
int i, len, recurse = 0;
int Ealternative, Oalternative;
- struct lc_time_T *tptr = __get_current_time_locale();
+ const struct lc_time *tptr = loc->time;
if (*flagsp & F_RECURSE)
recurse = 1;
*flagsp |= F_RECURSE;
- if (*flagsp & F_ZERO)
- (void) memset(tm, 0, sizeof (*tm));
- *flagsp &= ~F_ZERO;
-
ptr = fmt;
while (*ptr != 0) {
if (*buf == 0)
@@ -93,7 +93,7 @@ label:
break;
case '+':
- buf = __strptime(buf, tptr->date_fmt, tm, flagsp);
+ buf = __strptime(buf, tptr->date_fmt, tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
@@ -116,13 +116,13 @@ label:
break;
case 'c':
- buf = __strptime(buf, tptr->c_fmt, tm, flagsp);
+ buf = __strptime(buf, tptr->c_fmt, tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'D':
- buf = __strptime(buf, "%m/%d/%y", tm, flagsp);
+ buf = __strptime(buf, "%m/%d/%y", tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
@@ -140,37 +140,37 @@ label:
goto label;
case 'F':
- buf = __strptime(buf, "%Y-%m-%d", tm, flagsp);
+ buf = __strptime(buf, "%Y-%m-%d", tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'R':
- buf = __strptime(buf, "%H:%M", tm, flagsp);
+ buf = __strptime(buf, "%H:%M", tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'r':
- buf = __strptime(buf, tptr->ampm_fmt, tm, flagsp);
+ buf = __strptime(buf, tptr->ampm_fmt, tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'T':
- buf = __strptime(buf, "%H:%M:%S", tm, flagsp);
+ buf = __strptime(buf, "%H:%M:%S", tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'X':
- buf = __strptime(buf, tptr->X_fmt, tm, flagsp);
+ buf = __strptime(buf, tptr->X_fmt, tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
case 'x':
- buf = __strptime(buf, tptr->x_fmt, tm, flagsp);
+ buf = __strptime(buf, tptr->x_fmt, tm, flagsp, loc);
if (buf == NULL)
return (NULL);
break;
@@ -519,11 +519,14 @@ label:
}
char *
-strptime(const char *buf, const char *fmt, struct tm *tm)
+strptime(const char *_RESTRICT_KYWD buf, const char *_RESTRICT_KYWD fmt,
+ struct tm *_RESTRICT_KYWD tm)
{
- int flags = F_ZERO;
+ int flags = 0;
+
+ (void) memset(tm, 0, sizeof (*tm));
- return (__strptime(buf, fmt, tm, &flags));
+ return (__strptime(buf, fmt, tm, &flags, uselocale(NULL)));
}
/*
@@ -531,9 +534,31 @@ strptime(const char *buf, const char *fmt, struct tm *tm)
* incoming tm. It is triggered by -D_STRPTIME_DONTZERO.
*/
char *
-__strptime_dontzero(const char *buf, const char *fmt, struct tm *tm)
+__strptime_dontzero(const char *_RESTRICT_KYWD buf,
+ const char *_RESTRICT_KYWD fmt, struct tm *_RESTRICT_KYWD tm)
{
int flags = 0;
- return (__strptime(buf, fmt, tm, &flags));
+ return (__strptime(buf, fmt, tm, &flags, uselocale(NULL)));
+}
+
+/*
+ * strptime_l is an extension that seems natural, and indeed, MacOS X
+ * includes it within their <xlocale.h> and it is part of GNU libc as well.
+ * For now we restrict it to the cases where strict namespaces are not
+ * included. We expect to see it in a future version of POSIX. locale_t is
+ * not a restrict, since the spec for it doesn't assume its a pointer. We
+ * therefore pass it analagously to the way strftime_l is specified.
+ *
+ * We are not providing a non-zeroing version at this time.
+ */
+char *
+strptime_l(const char *_RESTRICT_KYWD buf, const char *_RESTRICT_KYWD fmt,
+ struct tm *_RESTRICT_KYWD tm, locale_t loc)
+{
+ int flags = 0;
+
+ (void) memset(tm, 0, sizeof (*tm));
+
+ return (__strptime(buf, fmt, tm, &flags, loc));
}
diff --git a/usr/src/lib/libc/port/locale/strxfrm.c b/usr/src/lib/libc/port/locale/strxfrm.c
index 08366cef69..d617094add 100644
--- a/usr/src/lib/libc/port/locale/strxfrm.c
+++ b/usr/src/lib/libc/port/locale/strxfrm.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
@@ -32,10 +33,12 @@
#include <errno.h>
#include <wchar.h>
#include <assert.h>
+#include <xlocale.h>
#include "collate.h"
size_t
-strxfrm(char *_RESTRICT_KYWD xf, const char *_RESTRICT_KYWD src, size_t dlen)
+strxfrm_l(char *_RESTRICT_KYWD xf, const char *_RESTRICT_KYWD src,
+ size_t dlen, locale_t loc)
{
size_t slen;
size_t xlen;
@@ -54,16 +57,16 @@ strxfrm(char *_RESTRICT_KYWD xf, const char *_RESTRICT_KYWD src, size_t dlen)
*/
slen = strlen(src);
- if (_collate_load_error)
+ if (loc->collate->lc_is_posix)
goto error;
if ((wcs = malloc((slen + 1) * sizeof (wchar_t))) == NULL)
goto error;
- if (mbstowcs(wcs, src, slen + 1) == (size_t)-1)
+ if (mbstowcs_l(wcs, src, slen + 1, loc) == (size_t)-1)
goto error;
- if ((xlen = _collate_sxfrm(wcs, xf, dlen)) == (size_t)-1)
+ if ((xlen = _collate_sxfrm(wcs, xf, dlen, loc)) == (size_t)-1)
goto error;
if (wcs)
@@ -85,3 +88,9 @@ error:
return (slen);
}
+
+size_t
+strxfrm(char *_RESTRICT_KYWD xf, const char *_RESTRICT_KYWD src, size_t dlen)
+{
+ return (strxfrm_l(xf, src, dlen, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/table.c b/usr/src/lib/libc/port/locale/table.c
index c48c51062b..272e3d18d2 100644
--- a/usr/src/lib/libc/port/locale/table.c
+++ b/usr/src/lib/libc/port/locale/table.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -260,16 +261,8 @@ _RuneLocale _DefaultRuneLocale = {
/* END CSTYLED */
};
-_RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale;
-
/* Taken from former _ctype.c */
unsigned int *__ctype_mask = _DefaultRuneLocale.__runetype;
int *__trans_lower = _DefaultRuneLocale.__maplower;
int *__trans_upper = _DefaultRuneLocale.__mapupper;
-
-/*
- * Used in various string routines to conditionalize versions optimized for
- * the ASCII case
- */
-int charset_is_ascii = 1;
diff --git a/usr/src/lib/libc/port/locale/timelocal.c b/usr/src/lib/libc/port/locale/timelocal.c
index 98af393f48..4dba212af3 100644
--- a/usr/src/lib/libc/port/locale/timelocal.c
+++ b/usr/src/lib/libc/port/locale/timelocal.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* Copyright (c) 1997 FreeBSD Inc.
@@ -28,16 +29,14 @@
#include "lint.h"
#include <stddef.h>
+#include <errno.h>
#include "ldpart.h"
#include "timelocal.h"
+#include "localeimpl.h"
-static struct lc_time_T _time_locale;
-static int _time_using_locale;
-static char *time_locale_buf;
+#define LCTIME_SIZE (sizeof (struct lc_time) / sizeof (char *))
-#define LCTIME_SIZE (sizeof (struct lc_time_T) / sizeof (char *))
-
-static const struct lc_time_T _C_time_locale = {
+struct lc_time lc_time_posix = {
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
@@ -84,17 +83,32 @@ static const struct lc_time_T _C_time_locale = {
"%I:%M:%S %p"
};
-struct lc_time_T *
-__get_current_time_locale(void)
-{
- return (_time_using_locale ? &_time_locale :
- (struct lc_time_T *)&_C_time_locale);
-}
+struct locdata __posix_time_locdata = {
+ .l_lname = "C",
+ .l_data = { &lc_time_posix }
+};
-int
-__time_load_locale(const char *name)
+struct locdata *
+__lc_time_load(const char *name)
{
- return (__part_load_locale(name, &_time_using_locale,
- &time_locale_buf, "LC_TIME", LCTIME_SIZE, LCTIME_SIZE,
- (const char **)&_time_locale));
+ struct locdata *ldata;
+ struct lc_time *ltime;
+ int ret;
+
+ if ((ldata = __locdata_alloc(name, sizeof (*ltime))) == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ ltime = ldata->l_data[0];
+
+ ret = __part_load_locale(name, (char **)&ldata->l_data[1],
+ "LC_TIME", LCTIME_SIZE, LCTIME_SIZE, (const char **)ltime);
+
+ if (ret != _LDP_LOADED) {
+ __locdata_free(ldata);
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ return (ldata);
}
diff --git a/usr/src/lib/libc/port/locale/timelocal.h b/usr/src/lib/libc/port/locale/timelocal.h
index e0c89945a1..6f49a89b97 100644
--- a/usr/src/lib/libc/port/locale/timelocal.h
+++ b/usr/src/lib/libc/port/locale/timelocal.h
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1997-2002 FreeBSD Project.
* All rights reserved.
@@ -32,7 +33,7 @@
* Private header file for the strftime and strptime localization
* stuff.
*/
-struct lc_time_T {
+struct lc_time {
const char *mon[12];
const char *month[12];
const char *wday[7];
@@ -46,7 +47,7 @@ struct lc_time_T {
const char *ampm_fmt;
};
-struct lc_time_T *__get_current_time_locale(void);
+struct lc_time *__get_current_time_locale(void);
int __time_load_locale(const char *);
#endif /* !_TIMELOCAL_H_ */
diff --git a/usr/src/lib/libc/port/locale/tolower.c b/usr/src/lib/libc/port/locale/tolower.c
index 52bcf162f2..59fb6ec673 100644
--- a/usr/src/lib/libc/port/locale/tolower.c
+++ b/usr/src/lib/libc/port/locale/tolower.c
@@ -10,22 +10,40 @@
*/
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
#include "lint.h"
#include <ctype.h>
+#include <locale.h>
+#include "localeimpl.h"
+#include "lctype.h"
#pragma weak _tolower = tolower
#pragma weak _toupper = toupper
int
+tolower_l(int c, locale_t loc)
+{
+ return (((unsigned)c > 255) ? c : loc->ctype->lc_trans_lower[c]);
+}
+
+int
+toupper_l(int c, locale_t loc)
+{
+ return (((unsigned)c > 255) ? c : loc->ctype->lc_trans_upper[c]);
+}
+
+#undef tolower
+int
tolower(int c)
{
- return (((unsigned)c > 255) ? c : __trans_lower[c]);
+ return (isascii(c) ? __trans_lower[c] : tolower_l(c, uselocale(NULL)));
}
+#undef toupper
int
toupper(int c)
{
- return (((unsigned)c > 255) ? c : __trans_upper[c]);
+ return (isascii(c) ? __trans_upper[c] : toupper_l(c, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/towlower.c b/usr/src/lib/libc/port/locale/towlower.c
index 13a20100d9..a40825d3c3 100644
--- a/usr/src/lib/libc/port/locale/towlower.c
+++ b/usr/src/lib/libc/port/locale/towlower.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -39,21 +40,23 @@
#include "lint.h"
#include <wctype.h>
#include <stdio.h>
+#include "localeimpl.h"
+#include "lctype.h"
#include "runetype.h"
static wint_t
-__change_case_ext(wint_t c, int lower)
+change_case_ext(locale_t loc, wint_t c, int lower)
{
+ const _RuneLocale *rl;
+ const _RuneRange *rr;
+ const _RuneEntry *base, *re;
size_t lim;
- _RuneRange *rr;
- _RuneEntry *base, *re;
if (c < 0 || c == EOF)
return (c);
- rr = lower ?
- &_CurrentRuneLocale->__maplower_ext :
- &_CurrentRuneLocale->__mapupper_ext;
+ rl = loc->runelocale;
+ rr = lower ? &rl->__maplower_ext : &rl->__mapupper_ext;
/* Binary search -- see bsearch.c for explanation. */
base = rr->__ranges;
for (lim = rr->__nranges; lim != 0; lim >>= 1) {
@@ -69,20 +72,40 @@ __change_case_ext(wint_t c, int lower)
return (c);
}
+wint_t
+towlower_l(wint_t wc, locale_t loc)
+{
+ return (iswascii(wc) ? __trans_lower[wc] :
+ (wc < 0 || wc >= _CACHED_RUNES) ?
+ change_case_ext(loc, wc, 1) :
+ loc->runelocale->__maplower[wc]);
+}
+
#undef towlower
wint_t
towlower(wint_t wc)
{
- return ((wc < 0 || wc >= _CACHED_RUNES) ?
- __change_case_ext(wc, 1) :
- _CurrentRuneLocale->__maplower[wc]);
+ return (iswascii(wc) ? __trans_lower[wc] :
+ (wc < 0 || wc >= _CACHED_RUNES) ?
+ change_case_ext(uselocale(NULL), wc, 1) :
+ uselocale(NULL)->runelocale->__maplower[wc]);
+}
+
+wint_t
+towupper_l(wint_t wc, locale_t loc)
+{
+ return (iswascii(wc) ? __trans_upper[wc] :
+ (wc < 0 || wc >= _CACHED_RUNES) ?
+ change_case_ext(loc, wc, 0) :
+ loc->runelocale->__mapupper[wc]);
}
#undef towupper
wint_t
towupper(wint_t wc)
{
- return ((wc < 0 || wc >= _CACHED_RUNES) ?
- __change_case_ext(wc, 0) :
- _CurrentRuneLocale->__mapupper[wc]);
+ return (iswascii(wc) ? __trans_upper[wc] :
+ (wc < 0 || wc >= _CACHED_RUNES) ?
+ change_case_ext(uselocale(NULL), wc, 0) :
+ uselocale(NULL)->runelocale->__mapupper[wc]);
}
diff --git a/usr/src/lib/libc/port/locale/utf8.c b/usr/src/lib/libc/port/locale/utf8.c
index af25ff39bb..e919b9dd4a 100644
--- a/usr/src/lib/libc/port/locale/utf8.c
+++ b/usr/src/lib/libc/port/locale/utf8.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins
* All rights reserved.
@@ -28,11 +29,11 @@
#include "lint.h"
#include <errno.h>
#include <limits.h>
-#include "runetype.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
+#include "lctype.h"
static size_t _UTF8_mbrtowc(wchar_t *_RESTRICT_KYWD,
const char *_RESTRICT_KYWD,
@@ -53,29 +54,16 @@ typedef struct {
wchar_t lbound;
} _UTF8State;
-int
-_UTF8_init(_RuneLocale *rl)
+void
+_UTF8_init(struct lc_ctype *lct)
{
- __mbrtowc = _UTF8_mbrtowc;
- __wcrtomb = _UTF8_wcrtomb;
- __mbsinit = _UTF8_mbsinit;
- __mbsnrtowcs = _UTF8_mbsnrtowcs;
- __wcsnrtombs = _UTF8_wcsnrtombs;
- _CurrentRuneLocale = rl;
-
- charset_is_ascii = 0;
-
- /*
- * In theory up to 6 bytes can be used for the encoding,
- * but only encodings with more than 4 bytes are illegal.
- */
- __ctype[520] = 4;
- /*
- * Note that the other CSWIDTH members are nonsensical for this
- * this coding. They only are valid with EUC codings.
- */
-
- return (0);
+ lct->lc_mbrtowc = _UTF8_mbrtowc;
+ lct->lc_wcrtomb = _UTF8_wcrtomb;
+ lct->lc_mbsinit = _UTF8_mbsinit;
+ lct->lc_mbsnrtowcs = _UTF8_mbsnrtowcs;
+ lct->lc_wcsnrtombs = _UTF8_wcsnrtombs;
+ lct->lc_is_ascii = 0;
+ lct->lc_max_mblen = 4;
}
static int
diff --git a/usr/src/lib/libc/port/locale/wcrtomb.c b/usr/src/lib/libc/port/locale/wcrtomb.c
index a3fa0d3d4a..cc2ec60756 100644
--- a/usr/src/lib/libc/port/locale/wcrtomb.c
+++ b/usr/src/lib/libc/port/locale/wcrtomb.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -27,14 +28,25 @@
#include "lint.h"
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
+#include "localeimpl.h"
+#include "lctype.h"
#include "mblocal.h"
size_t
-wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc, mbstate_t *_RESTRICT_KYWD ps)
+wcrtomb_l(char *_RESTRICT_KYWD s, wchar_t wc, mbstate_t *_RESTRICT_KYWD ps,
+ locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__wcrtomb(s, wc, ps));
+ return (loc->ctype->lc_wcrtomb(s, wc, ps));
+}
+
+size_t
+wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (wcrtomb_l(s, wc, ps, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/i18n/wsncasecmp.c b/usr/src/lib/libc/port/locale/wcscasecmp.c
index ee4fbb6028..ef0b734435 100644
--- a/usr/src/lib/libc/port/i18n/wsncasecmp.c
+++ b/usr/src/lib/libc/port/locale/wcscasecmp.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
*/
/*
@@ -29,28 +30,54 @@
* All letters are converted to the lowercase and compared.
*/
-#pragma weak _wsncasecmp = wsncasecmp
-
#include "lint.h"
#include <stdlib.h>
-#include <widec.h>
+#include <wchar.h>
+#include <locale.h>
#include "libc.h"
+/* Legacy Sun interfaces */
+#pragma weak wscasecmp = wcscasecmp
+#pragma weak wsncasecmp = wcsncasecmp
+
int
-wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+wcscasecmp_l(const wchar_t *s1, const wchar_t *s2, locale_t loc)
+{
+ if (s1 == s2)
+ return (0);
+
+ while (towlower_l(*s1, loc) == towlower_l(*s2, loc)) {
+ if (*s1 == 0)
+ return (0);
+ s1++;
+ s2++;
+ }
+ return (towlower_l(*s1, loc) - towlower_l(*s2, loc));
+}
+
+int
+wcscasecmp(const wchar_t *s1, const wchar_t *s2)
+{
+ return (wcscasecmp_l(s1, s2, uselocale(NULL)));
+}
+
+int
+wcsncasecmp_l(const wchar_t *s1, const wchar_t *s2, size_t n, locale_t loc)
{
if (s1 == s2)
return (0);
- n++;
- while (--n > 0 && towlower(*s1) == towlower(*s2++))
- if (*s1++ == 0)
+ while ((towlower_l(*s1, loc) == towlower_l(*s2, loc)) && n--) {
+ if (*s1 == 0)
return (0);
- return ((n == 0) ? 0 : (towlower(*s1) - towlower(*(s2 - 1))));
+ s1++;
+ s2++;
+ }
+ return (towlower_l(*s1, loc) - towlower_l(*s2, loc));
}
int
-wsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
{
- return (wcsncasecmp(s1, s2, n));
+ return (wcsncasecmp_l(s1, s2, n, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/wcscoll.c b/usr/src/lib/libc/port/locale/wcscoll.c
index ac4218c356..4bf32ff010 100644
--- a/usr/src/lib/libc/port/locale/wcscoll.c
+++ b/usr/src/lib/libc/port/locale/wcscoll.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002 Tim J. Robbins
* All rights reserved.
@@ -32,17 +33,17 @@
#include <wchar.h>
#include <assert.h>
#include "collate.h"
+#include "localeimpl.h"
int
-wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc)
{
int len1, len2, pri1, pri2, ret;
wchar_t *tr1 = NULL, *tr2 = NULL;
int direc, pass;
+ const struct lc_collate *lcc = loc->collate;
- collate_info_t *info = _collate_info;
-
- if (_collate_load_error)
+ if (lcc->lc_is_posix)
/*
* Locale has no special collating order or could not be
* loaded, do a fast binary comparison.
@@ -63,18 +64,18 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
* Note that we do one final extra pass at the end to pick
* up UNDEFINED elements. There is special handling for them.
*/
- for (pass = 0; pass <= info->directive_count; pass++) {
+ for (pass = 0; pass <= lcc->lc_directive_count; pass++) {
- int32_t *st1 = NULL;
- int32_t *st2 = NULL;
+ const int32_t *st1 = NULL;
+ const int32_t *st2 = NULL;
const wchar_t *w1 = ws1;
const wchar_t *w2 = ws2;
/* special pass for UNDEFINED */
- if (pass == info->directive_count) {
+ if (pass == lcc->lc_directive_count) {
direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED;
} else {
- direc = info->directive[pass];
+ direc = lcc->lc_directive[pass];
}
if (direc & DIRECTIVE_BACKWARD) {
@@ -104,7 +105,8 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
if (direc & DIRECTIVE_POSITION) {
while ((*w1 || st1) && (*w2 || st2)) {
pri1 = pri2 = 0;
- _collate_lookup(w1, &len1, &pri1, pass, &st1);
+ _collate_lookup(lcc, w1, &len1, &pri1, pass,
+ &st1);
if (pri1 <= 0) {
if (pri1 < 0) {
errno = EINVAL;
@@ -112,7 +114,8 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
}
pri1 = COLLATE_MAX_PRIORITY;
}
- _collate_lookup(w2, &len2, &pri2, pass, &st2);
+ _collate_lookup(lcc, w2, &len2, &pri2, pass,
+ &st2);
if (pri2 <= 0) {
if (pri2 < 0) {
errno = EINVAL;
@@ -131,7 +134,7 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
while ((*w1 || st1) && (*w2 || st2)) {
pri1 = pri2 = 0;
while (*w1) {
- _collate_lookup(w1, &len1,
+ _collate_lookup(lcc, w1, &len1,
&pri1, pass, &st1);
if (pri1 > 0)
break;
@@ -142,7 +145,7 @@ wcscoll(const wchar_t *ws1, const wchar_t *ws2)
w1 += len1;
}
while (*w2) {
- _collate_lookup(w2, &len2,
+ _collate_lookup(lcc, w2, &len2,
&pri2, pass, &st2);
if (pri2 > 0)
break;
@@ -186,3 +189,10 @@ fail:
ret = wcscmp(ws1, ws2);
goto end;
}
+
+
+int
+wcscoll(const wchar_t *ws1, const wchar_t *ws2)
+{
+ return (wcscoll_l(ws1, ws2, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wcsnrtombs.c b/usr/src/lib/libc/port/locale/wcsnrtombs.c
index ecf7b641c4..a2f467956f 100644
--- a/usr/src/lib/libc/port/locale/wcsnrtombs.c
+++ b/usr/src/lib/libc/port/locale/wcsnrtombs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -29,24 +30,35 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
+#include <locale.h>
#include <wchar.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
size_t
-wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
- size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
+wcsnrtombs_l(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__wcsnrtombs(dst, src, nwc, len, ps));
+ return (loc->ctype->lc_wcsnrtombs(dst, src, nwc, len, ps));
}
size_t
-__wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+wcsnrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps)
{
+ return (wcsnrtombs_l(dst, src, nwc, len, ps, uselocale(NULL)));
+}
+
+size_t
+__wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t nwc, size_t len, mbstate_t *_RESTRICT_KYWD ps,
+ wcrtomb_pfn_t pwcrtomb)
+{
mbstate_t mbsbak;
char buf[MB_LEN_MAX];
const wchar_t *s;
@@ -58,7 +70,7 @@ __wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
if (dst == NULL) {
while (nwc-- > 0) {
- if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1)
+ if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1)
/* Invalid character - wcrtomb() sets errno. */
return ((size_t)-1);
else if (*s == L'\0')
@@ -72,7 +84,7 @@ __wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
while (len > 0 && nwc-- > 0) {
if (len > (size_t)MB_CUR_MAX) {
/* Enough space to translate in-place. */
- if ((nb = __wcrtomb(dst, *s, ps)) == (size_t)-1) {
+ if ((nb = pwcrtomb(dst, *s, ps)) == (size_t)-1) {
*src = s;
return ((size_t)-1);
}
@@ -85,7 +97,7 @@ __wcsnrtombs_std(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
* character is too long for the buffer.
*/
mbsbak = *ps;
- if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) {
+ if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1) {
*src = s;
return ((size_t)-1);
}
diff --git a/usr/src/lib/libc/port/locale/wcsrtombs.c b/usr/src/lib/libc/port/locale/wcsrtombs.c
index 8250e6302e..61a37d976a 100644
--- a/usr/src/lib/libc/port/locale/wcsrtombs.c
+++ b/usr/src/lib/libc/port/locale/wcsrtombs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -30,15 +31,24 @@
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
+#include "localeimpl.h"
+#include "lctype.h"
#include "mblocal.h"
size_t
-wcsrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
- size_t len, mbstate_t *_RESTRICT_KYWD ps)
+wcsrtombs_l(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t len, mbstate_t *_RESTRICT_KYWD ps, locale_t loc)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
- return (__wcsnrtombs(dst, src, ULONG_MAX, len, ps));
+ return (loc->ctype->lc_wcsnrtombs(dst, src, ULONG_MAX, len, ps));
+}
+
+size_t
+wcsrtombs(char *_RESTRICT_KYWD dst, const wchar_t **_RESTRICT_KYWD src,
+ size_t len, mbstate_t *_RESTRICT_KYWD ps)
+{
+ return (wcsrtombs_l(dst, src, len, ps, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/wcstombs.c b/usr/src/lib/libc/port/locale/wcstombs.c
index 28f31799d2..cc48ac47f9 100644
--- a/usr/src/lib/libc/port/locale/wcstombs.c
+++ b/usr/src/lib/libc/port/locale/wcstombs.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -30,9 +31,12 @@
#include <stdlib.h>
#include <wchar.h>
#include "mblocal.h"
+#include "localeimpl.h"
+#include "lctype.h"
size_t
-wcstombs(char *_RESTRICT_KYWD s, const wchar_t *_RESTRICT_KYWD pwcs, size_t n)
+wcstombs_l(char *_RESTRICT_KYWD s, const wchar_t *_RESTRICT_KYWD pwcs,
+ size_t n, locale_t loc)
{
static const mbstate_t initial = { 0 };
mbstate_t mbs;
@@ -40,5 +44,11 @@ wcstombs(char *_RESTRICT_KYWD s, const wchar_t *_RESTRICT_KYWD pwcs, size_t n)
mbs = initial;
pwcsp = pwcs;
- return (__wcsnrtombs(s, &pwcsp, ULONG_MAX, n, &mbs));
+ return (loc->ctype->lc_wcsnrtombs(s, &pwcsp, ULONG_MAX, n, &mbs));
+}
+
+size_t
+wcstombs(char *_RESTRICT_KYWD s, const wchar_t *_RESTRICT_KYWD pwcs, size_t n)
+{
+ return (wcstombs_l(s, pwcs, n, uselocale(NULL)));
}
diff --git a/usr/src/lib/libc/port/locale/wcswidth.c b/usr/src/lib/libc/port/locale/wcswidth.c
index e6d98488d1..31e7c0e1d6 100644
--- a/usr/src/lib/libc/port/locale/wcswidth.c
+++ b/usr/src/lib/libc/port/locale/wcswidth.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,19 +38,27 @@
*/
#include "lint.h"
+#include <locale.h>
#include <wchar.h>
+#include <xlocale.h>
int
-wcswidth(const wchar_t *pwcs, size_t n)
+wcswidth_l(const wchar_t *pwcs, size_t n, locale_t loc)
{
wchar_t wc;
int len, l;
len = 0;
while (n-- > 0 && (wc = *pwcs++) != L'\0') {
- if ((l = wcwidth(wc)) < 0)
+ if ((l = wcwidth_l(wc, loc)) < 0)
return (-1);
len += l;
}
return (len);
}
+
+int
+wcswidth(const wchar_t *pwcs, size_t n)
+{
+ return (wcswidth_l(pwcs, n, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wcsxfrm.c b/usr/src/lib/libc/port/locale/wcsxfrm.c
index 6c21db391f..7001637b7e 100644
--- a/usr/src/lib/libc/port/locale/wcsxfrm.c
+++ b/usr/src/lib/libc/port/locale/wcsxfrm.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
* at Electronni Visti IA, Kiev, Ukraine.
@@ -36,10 +37,11 @@
#define WCS_XFRM_OFFSET 1
size_t
-wcsxfrm(wchar_t *_RESTRICT_KYWD dest,
- const wchar_t *_RESTRICT_KYWD src, size_t len)
+wcsxfrm_l(wchar_t *_RESTRICT_KYWD dest,
+ const wchar_t *_RESTRICT_KYWD src, size_t len, locale_t loc)
{
size_t slen;
+ const struct lc_collate *lcc = loc->collate;
if (*src == L'\0') {
if (len != 0)
@@ -47,8 +49,8 @@ wcsxfrm(wchar_t *_RESTRICT_KYWD dest,
return (0);
}
- if ((_collate_load_error) ||
- ((slen = _collate_wxfrm(src, dest, len)) == (size_t)-1)) {
+ if ((lcc->lc_is_posix) ||
+ ((slen = _collate_wxfrm(lcc, src, dest, len)) == (size_t)-1)) {
goto error;
}
@@ -71,3 +73,10 @@ error:
}
return (slen);
}
+
+size_t
+wcsxfrm(wchar_t *_RESTRICT_KYWD dest,
+ const wchar_t *_RESTRICT_KYWD src, size_t len)
+{
+ return (wcsxfrm_l(dest, src, len, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wctob.c b/usr/src/lib/libc/port/locale/wctob.c
index c44c10fbb7..62a07a0bb9 100644
--- a/usr/src/lib/libc/port/locale/wctob.c
+++ b/usr/src/lib/libc/port/locale/wctob.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -29,16 +30,24 @@
#include <limits.h>
#include <stdio.h>
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
int
-wctob(wint_t c)
+wctob_l(wint_t c, locale_t loc)
{
static const mbstate_t initial = { 0 };
mbstate_t mbs = initial;
char buf[MB_LEN_MAX];
- if (c == WEOF || __wcrtomb(buf, c, &mbs) != 1)
+ if (c == WEOF || wcrtomb_l(buf, c, &mbs, loc) != 1)
return (EOF);
return ((unsigned char)*buf);
}
+
+int
+wctob(wint_t c)
+{
+ return (wctob_l(c, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wctomb.c b/usr/src/lib/libc/port/locale/wctomb.c
index 2c6bd77a61..b65444c97f 100644
--- a/usr/src/lib/libc/port/locale/wctomb.c
+++ b/usr/src/lib/libc/port/locale/wctomb.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
@@ -28,21 +29,27 @@
#include "lint.h"
#include <stdlib.h>
#include <wchar.h>
+#include <locale.h>
+#include <xlocale.h>
#include "mblocal.h"
int
-wctomb(char *s, wchar_t wchar)
+wctomb_l(char *s, wchar_t wchar, locale_t loc)
{
- static const mbstate_t initial = { 0 };
- static mbstate_t mbs;
+ mbstate_t mbs = { 0 };
size_t rval;
if (s == NULL) {
/* No support for state dependent encodings. */
- mbs = initial;
return (0);
}
- if ((rval = __wcrtomb(s, wchar, &mbs)) == (size_t)-1)
+ if ((rval = wcrtomb_l(s, wchar, &mbs, loc)) == (size_t)-1)
return (-1);
return ((int)rval);
}
+
+int
+wctomb(char *s, wchar_t wchar)
+{
+ return (wctomb_l(s, wchar, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wctrans.c b/usr/src/lib/libc/port/locale/wctrans.c
index c7f6fb597f..7c808d8e15 100644
--- a/usr/src/lib/libc/port/locale/wctrans.c
+++ b/usr/src/lib/libc/port/locale/wctrans.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
@@ -26,9 +27,11 @@
*/
#include "lint.h"
+#include <note.h>
#include <errno.h>
#include <string.h>
#include <wctype.h>
+#include <locale.h>
enum {
_WCT_ERROR = 0,
@@ -37,15 +40,14 @@ enum {
};
wint_t
-towctrans(wint_t wc, wctrans_t desc)
+towctrans_l(wint_t wc, wctrans_t desc, locale_t loc)
{
-
switch (desc) {
case _WCT_TOLOWER:
- wc = towlower(wc);
+ wc = towlower_l(wc, loc);
break;
case _WCT_TOUPPER:
- wc = towupper(wc);
+ wc = towupper_l(wc, loc);
break;
case _WCT_ERROR:
default:
@@ -56,8 +58,18 @@ towctrans(wint_t wc, wctrans_t desc)
return (wc);
}
+wint_t
+towctrans(wint_t wc, wctrans_t desc)
+{
+ return (towctrans_l(wc, desc, uselocale(NULL)));
+}
+
+/*
+ * For *now* we don't support locale sensitive transforms besides toupper
+ * and tolower.
+ */
wctrans_t
-wctrans(const char *charclass)
+wctrans_l(const char *charclass, locale_t loc)
{
struct {
const char *name;
@@ -68,6 +80,7 @@ wctrans(const char *charclass)
{ NULL, _WCT_ERROR }, /* Default */
};
int i;
+ _NOTE(ARGUNUSED(loc));
i = 0;
while (ccls[i].name != NULL && strcmp(ccls[i].name, charclass) != 0)
@@ -77,3 +90,9 @@ wctrans(const char *charclass)
errno = EINVAL;
return (ccls[i].trans);
}
+
+wctrans_t
+wctrans(const char *charclass)
+{
+ return (wctrans_l(charclass, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wctype.c b/usr/src/lib/libc/port/locale/wctype.c
index 62a37ad794..3acc3b2d90 100644
--- a/usr/src/lib/libc/port/locale/wctype.c
+++ b/usr/src/lib/libc/port/locale/wctype.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2002 Tim J. Robbins.
* All rights reserved.
@@ -29,10 +30,17 @@
#include <ctype.h>
#include <string.h>
#include <wctype.h>
+#include <note.h>
+#include <locale.h>
#include "_ctype.h"
+/*
+ * For now, we don't support locale specific character classes. This is
+ * a capability that needs to be added (locales should be able to define
+ * their own character classes.)
+ */
wctype_t
-wctype(const char *property)
+wctype_l(const char *property, locale_t loc)
{
static const struct {
const char *name;
@@ -57,6 +65,7 @@ wctype(const char *property)
{ NULL, 0 }, /* Default */
};
int i;
+ _NOTE(ARGUNUSED(loc));
i = 0;
while (props[i].name != NULL && strcmp(props[i].name, property) != 0)
@@ -64,3 +73,9 @@ wctype(const char *property)
return (props[i].mask);
}
+
+wctype_t
+wctype(const char *property)
+{
+ return (wctype_l(property, uselocale(NULL)));
+}
diff --git a/usr/src/lib/libc/port/locale/wcwidth.c b/usr/src/lib/libc/port/locale/wcwidth.c
index a6ff73b357..5151f84951 100644
--- a/usr/src/lib/libc/port/locale/wcwidth.c
+++ b/usr/src/lib/libc/port/locale/wcwidth.c
@@ -1,4 +1,5 @@
/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
@@ -44,25 +45,33 @@
#include <wchar.h>
#include "_ctype.h"
#include "runetype.h"
+#include "localeimpl.h"
#undef wcwidth
int
-wcwidth(wchar_t wc)
+wcwidth_l(wchar_t wc, locale_t loc)
{
unsigned int x;
+ const _RuneLocale *rl = loc->runelocale;
if (wc == 0)
return (0);
- x = ((wc < 0 || wc >= _CACHED_RUNES) ? ___runetype(wc) :
- _CurrentRuneLocale->__runetype[wc]) & (_CTYPE_SWM|_CTYPE_R);
+ x = ((wc < 0 || wc >= _CACHED_RUNES) ? __runetype(rl, wc) :
+ rl->__runetype[wc]) & (_CTYPE_SWM|_CTYPE_R);
if ((x & _CTYPE_SWM) != 0)
return ((x & _CTYPE_SWM) >> _CTYPE_SWS);
return ((x & _CTYPE_R) != 0 ? 1 : -1);
}
+int
+wcwidth(wchar_t wc)
+{
+ return (wcwidth_l(wc, uselocale(NULL)));
+}
+
#pragma weak _scrwidth = scrwidth
/*
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 1882a337d5..c07a40aaf5 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -28,7 +28,7 @@
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright (c) 2013 Gary Mills
-#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
#
# MAPFILE HEADER START
@@ -93,6 +93,88 @@ $if _x86 && _ELF64
$add amd64
$endif
+SYMBOL_VERSION ILLUMOS_0.8 { # POSIX 2008 newlocale and friends
+ protected:
+ __global_locale;
+ __mb_cur_max;
+ __mb_cur_max_l;
+ btowc_l;
+ duplocale;
+ fgetwc_l;
+ freelocale;
+ getwc_l;
+ isalnum_l;
+ isalpha_l;
+ isblank_l;
+ iscntrl_l;
+ isdigit_l;
+ isgraph_l;
+ islower_l;
+ isprint_l;
+ ispunct_l;
+ isspace_l;
+ isupper_l;
+ iswideogram;
+ iswideogram_l;
+ iswnumber;
+ iswnumber_l;
+ iswhexnumber;
+ iswhexnumber_l;
+ iswphonogram;
+ iswphonogram_l;
+ iswspecial;
+ iswspecial_l;
+ iswalnum_l;
+ iswalpha_l;
+ iswblank_l;
+ iswcntrl_l;
+ iswctype_l;
+ iswdigit_l;
+ iswgraph_l;
+ iswlower_l;
+ iswprint_l;
+ iswpunct_l;
+ iswspace_l;
+ iswupper_l;
+ mblen_l;
+ mbrlen_l;
+ mbsinit_l;
+ mbsnrtowcs;
+ mbsnrtowcs_l;
+ mbsrtowcs_l;
+ mbstowcs_l;
+ mbtowc_l;
+ newlocale;
+ nl_langinfo_l;
+ strcasecmp_l;
+ strcasestr_l;
+ strcoll_l;
+ strfmon_l;
+ strftime_l;
+ strncasecmp_l;
+ strptime_l;
+ strxfrm_l;
+ tolower_l;
+ toupper_l;
+ towlower_l;
+ towupper_l;
+ towctrans_l;
+ uselocale;
+ wcrtomb_l;
+ wcscasecmp_l;
+ wcscoll_l;
+ wcsncasecmp_l;
+ wcsrtombs_l;
+ wcstombs_l;
+ wcswidth_l;
+ wcsxfrm_l;
+ wctob_l;
+ wctomb_l;
+ wctrans_l;
+ wctype_l;
+ wcwidth_l;
+} ILLUMOS_0.7;
+
SYMBOL_VERSION ILLUMOS_0.7 { # Illumos additions
protected:
_glob_ext;
diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com
index 25482d7324..15c5c2b092 100644
--- a/usr/src/lib/libc/sparc/Makefile.com
+++ b/usr/src/lib/libc/sparc/Makefile.com
@@ -22,6 +22,7 @@
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2013 Garrett D'Amore <garrett@damore.org>
#
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -732,16 +733,12 @@ PORTI18N= \
getwchar.o \
putwchar.o \
putws.o \
- strcasecmp.o \
- strcasestr.o \
- strncasecmp.o \
strtows.o \
wcsnlen.o \
wcstoimax.o \
wcstol.o \
wcstoul.o \
wcswcs.o \
- wscasecmp.o \
wscat.o \
wschr.o \
wscmp.o \
@@ -749,7 +746,6 @@ PORTI18N= \
wscspn.o \
wsdup.o \
wslen.o \
- wsncasecmp.o \
wsncat.o \
wsncmp.o \
wsncpy.o \
@@ -777,7 +773,6 @@ PORTI18N= \
wdresolve.o \
_ctype.o \
isascii.o \
- isdigit.o \
toascii.o
PORTI18N_COND= \
@@ -801,11 +796,13 @@ PORTLOCALE= \
gb2312.o \
gbk.o \
getdate.o \
+ isdigit.o \
iswctype.o \
ldpart.o \
lmessages.o \
lnumeric.o \
lmonetary.o \
+ localeimpl.o \
localeconv.o \
mbftowc.o \
mblen.o \
@@ -828,9 +825,12 @@ PORTLOCALE= \
runetype.o \
setlocale.o \
setrunelocale.o \
+ strcasecmp.o \
+ strcasestr.o \
strcoll.o \
strfmon.o \
strftime.o \
+ strncasecmp.o \
strptime.o \
strxfrm.o \
table.o \
@@ -840,6 +840,7 @@ PORTLOCALE= \
ungetwc.o \
utf8.o \
wcrtomb.o \
+ wcscasecmp.o \
wcscoll.o \
wcsftime.o \
wcsnrtombs.o \
diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com
index fe6844273e..0c3f0a2e32 100644
--- a/usr/src/lib/libc/sparcv9/Makefile.com
+++ b/usr/src/lib/libc/sparcv9/Makefile.com
@@ -22,6 +22,7 @@
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2013 Garrett D'Amore <garrett@damore.org>
#
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -679,16 +680,12 @@ PORTI18N= \
getwchar.o \
putwchar.o \
putws.o \
- strcasecmp.o \
- strcasestr.o \
- strncasecmp.o \
strtows.o \
wcsnlen.o \
wcstoimax.o \
wcstol.o \
wcstoul.o \
wcswcs.o \
- wscasecmp.o \
wscat.o \
wschr.o \
wscmp.o \
@@ -696,7 +693,6 @@ PORTI18N= \
wscspn.o \
wsdup.o \
wslen.o \
- wsncasecmp.o \
wsncat.o \
wsncmp.o \
wsncpy.o \
@@ -724,7 +720,6 @@ PORTI18N= \
wdresolve.o \
_ctype.o \
isascii.o \
- isdigit.o \
toascii.o
PORTI18N_COND= \
@@ -748,12 +743,14 @@ PORTLOCALE= \
gb2312.o \
gbk.o \
getdate.o \
+ isdigit.o \
iswctype.o \
ldpart.o \
lmessages.o \
lnumeric.o \
lmonetary.o \
localeconv.o \
+ localeimpl.o \
mbftowc.o \
mblen.o \
mbrlen.o \
@@ -775,9 +772,12 @@ PORTLOCALE= \
runetype.o \
setlocale.o \
setrunelocale.o \
+ strcasecmp.o \
+ strcasestr.o \
strcoll.o \
strfmon.o \
strftime.o \
+ strncasecmp.o \
strptime.o \
strxfrm.o \
table.o \
@@ -787,6 +787,7 @@ PORTLOCALE= \
ungetwc.o \
utf8.o \
wcrtomb.o \
+ wcscasecmp.o \
wcscoll.o \
wcsftime.o \
wcsnrtombs.o \
diff --git a/usr/src/lib/libumem/common/stub_stand.c b/usr/src/lib/libumem/common/stub_stand.c
index 2c82364ef1..7a26ea8b7f 100644
--- a/usr/src/lib/libumem/common/stub_stand.c
+++ b/usr/src/lib/libumem/common/stub_stand.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -146,3 +147,18 @@ void
_tmem_set_cleanup(void (*f)(int, void *))
{
}
+
+int
+isspace(int c)
+{
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f':
+ case '\v':
+ return (1);
+ }
+ return (0);
+}
diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile
index f3b6f18a7f..7e6a965ce8 100644
--- a/usr/src/man/man3c/Makefile
+++ b/usr/src/man/man3c/Makefile
@@ -13,6 +13,7 @@
# Copyright 2011, Richard Lowe
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
# Copyright 2013, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
#
include $(SRC)/Makefile.master
@@ -239,6 +240,7 @@ MANFILES= __fbufsize.3c \
mutex_init.3c \
nanosleep.3c \
ndbm.3c \
+ newlocale.3c \
nl_langinfo.3c \
offsetof.3c \
opendir.3c \
@@ -410,6 +412,7 @@ MANFILES= __fbufsize.3c \
str2sig.3c \
strcoll.3c \
strerror.3c \
+ strfmon.3c \
strftime.3c \
string.3c \
string_to_decimal.3c \
@@ -461,6 +464,8 @@ MANFILES= __fbufsize.3c \
toascii.3c \
tolower.3c \
toupper.3c \
+ towlower.3c \
+ towupper.3c \
truncate.3c \
tsearch.3c \
ttyname.3c \
@@ -475,6 +480,7 @@ MANFILES= __fbufsize.3c \
ungetwc.3c \
unlockpt.3c \
unsetenv.3c \
+ uselocale.3c \
usleep.3c \
vfwprintf.3c \
vlfmt.3c \
@@ -499,6 +505,7 @@ MANFILES= __fbufsize.3c \
wcsxfrm.3c \
wctob.3c \
wctomb.3c \
+ wctrans.3c \
wctype.3c \
wcwidth.3c \
wmemchr.3c \
@@ -654,6 +661,7 @@ MANLINKS= FD_CLR.3c \
bcopy.3c \
bind_textdomain_codeset.3c \
bindtextdomain.3c \
+ btowc_l.3c \
bzero.3c \
calloc.3c \
catclose.3c \
@@ -698,6 +706,7 @@ MANLINKS= FD_CLR.3c \
door_unbind.3c \
double_to_decimal.3c \
dup3.3c \
+ duplocale.3c \
edata.3c \
endgrent.3c \
endnetgrent.3c \
@@ -725,6 +734,7 @@ MANLINKS= FD_CLR.3c \
fgets.3c \
fgetspent.3c \
fgetspent_r.3c \
+ fgetwc_l.3c \
fgetws.3c \
file_to_decimal.3c \
fileno.3c \
@@ -738,6 +748,7 @@ MANLINKS= FD_CLR.3c \
fpsetsticky.3c \
fputs.3c \
free.3c \
+ freelocale.3c \
fscanf.3c \
fseeko.3c \
fsetattr.3c \
@@ -784,6 +795,8 @@ MANLINKS= FD_CLR.3c \
getvfsfile.3c \
getvfsspec.3c \
getw.3c \
+ getwc_l.3c \
+ getwchar_l.3c \
getzoneidbyname.3c \
getzonenamebyid.3c \
globfree.3c \
@@ -796,36 +809,71 @@ MANLINKS= FD_CLR.3c \
initstate.3c \
innetgr.3c \
isalnum.3c \
+ isalnum_l.3c \
isalpha.3c \
+ isalpha_l.3c \
isascii.3c \
isblank.3c \
+ isblank_l.3c \
iscntrl.3c \
+ iscntrl_l.3c \
isdigit.3c \
+ isdigit_l.3c \
isenglish.3c \
isgraph.3c \
+ isgraph_l.3c \
isideogram.3c \
islower.3c \
+ islower_l.3c \
isnanf.3c \
isnumber.3c \
isphonogram.3c \
isprint.3c \
+ isprint_l.3c \
ispunct.3c \
+ ispunct_l.3c \
isspace.3c \
+ isspace_l.3c \
isspecial.3c \
isupper.3c \
+ isupper_l.3c \
iswalnum.3c \
+ iswalnum_l.3c \
+ iswalpha_l.3c \
iswascii.3c \
iswblank.3c \
+ iswblank_l.3c \
iswcntrl.3c \
+ iswcntrl_l.3c \
+ iswctype_l.3c \
iswdigit.3c \
+ iswdigit_l.3c \
iswgraph.3c \
+ iswgraph_l.3c \
+ iswideogram.3c \
+ iswideogram_l.3c \
+ iswhexnumber.3c \
+ iswhexnumber_l.3c \
iswlower.3c \
+ iswlower_l.3c \
+ iswnumber.3c \
+ iswnumber_l.3c \
+ iswphonogram.3c \
+ iswphonogram_l.3c \
iswprint.3c \
+ iswprint_l.3c \
iswpunct.3c \
+ iswpunct_l.3c \
iswspace.3c \
+ iswspace_l.3c \
+ iswspecial.3c \
+ iswspecial_l.3c \
iswupper.3c \
+ iswupper_l.3c \
iswxdigit.3c \
+ iswxdigit_l.3c \
isxdigit.3c \
+ isxdigit_l.3c \
jrand48.3c \
l64a.3c \
labs.3c \
@@ -840,6 +888,16 @@ MANLINKS= FD_CLR.3c \
longjmp.3c \
lrand48.3c \
major.3c \
+ mblen_l.3c \
+ mbrlen_l.3c \
+ mbrtowc_l.3c \
+ mbsinit_l.3c \
+ mbsnrtowcs.3c \
+ mbsnrtowcs_l.3c \
+ mbsrtowcs_l.3c \
+ mbstowcs.3c \
+ mbstowcs_l.3c \
+ mbtowc_l.3c \
memalign.3c \
membar_consumer.3c \
membar_enter.3c \
@@ -868,6 +926,7 @@ MANLINKS= FD_CLR.3c \
mutex_lock.3c \
mutex_trylock.3c \
mutex_unlock.3c \
+ nl_langinfo_l.3c \
nftw.3c \
ngettext.3c \
nrand48.3c \
@@ -1057,22 +1116,28 @@ MANLINKS= FD_CLR.3c \
stdin.3c \
stdout.3c \
strcasecmp.3c \
+ strcasecmp_l.3c \
strcat.3c \
strchr.3c \
strcmp.3c \
+ strcoll_l.3c \
strcpy.3c \
strcspn.3c \
strdup.3c \
strerror_r.3c \
+ strfmon_l.3c \
+ strftime_l.3c \
strlcat.3c \
strlcpy.3c \
strlen.3c \
strncasecmp.3c \
+ strncasecmp_l.3c \
strncat.3c \
strncmp.3c \
strncpy.3c \
strnlen.3c \
strpbrk.3c \
+ strptime_l.3c \
strrchr.3c \
strsep.3c \
strspn.3c \
@@ -1084,6 +1149,7 @@ MANLINKS= FD_CLR.3c \
strtoll.3c \
strtoull.3c \
strtoumax.3c \
+ strxfrm_l.3c \
swapcontext.3c \
swprintf.3c \
swscanf.3c \
@@ -1104,6 +1170,12 @@ MANLINKS= FD_CLR.3c \
timerisset.3c \
timersub.3c \
tmpnam_r.3c \
+ tolower_l.3c \
+ toupper_l.3c \
+ towctrans.3c \
+ towctrans_l.3c \
+ towlower_l.3c \
+ towupper_l.3c \
ttyname_r.3c \
twalk.3c \
tzset.3c \
@@ -1158,9 +1230,11 @@ MANLINKS= FD_CLR.3c \
watoi.3c \
watol.3c \
watoll.3c \
+ wcrtomb_l.3c \
wcscat.3c \
wcschr.3c \
wcscmp.3c \
+ wcscoll_l.3c \
wcscpy.3c \
wcscspn.3c \
wcsetno.3c \
@@ -1178,6 +1252,12 @@ MANLINKS= FD_CLR.3c \
wcstoull.3c \
wcstoumax.3c \
wcswcs.3c \
+ wcswidth_l.3c \
+ wctob_l.3c \
+ wctomb_l.3c \
+ wctrans_l.3c \
+ wctype_l.3c \
+ wcwidth_l.3c \
windex.3c \
wordfree.3c \
wprintf.3c \
@@ -1342,6 +1422,8 @@ bcmp.3c := LINKSRC = bstring.3c
bcopy.3c := LINKSRC = bstring.3c
bzero.3c := LINKSRC = bstring.3c
+btowc_l.3c := LINKSRC = btowc.3c
+
catclose.3c := LINKSRC = catopen.3c
cfgetospeed.3c := LINKSRC = cfgetispeed.3c
@@ -1377,18 +1459,30 @@ localtime_r.3c := LINKSRC = ctime.3c
tzset.3c := LINKSRC = ctime.3c
isalnum.3c := LINKSRC = ctype.3c
+isalnum_l.3c := LINKSRC = ctype.3c
isalpha.3c := LINKSRC = ctype.3c
+isalpha_l.3c := LINKSRC = ctype.3c
isascii.3c := LINKSRC = ctype.3c
isblank.3c := LINKSRC = ctype.3c
+isblank_l.3c := LINKSRC = ctype.3c
iscntrl.3c := LINKSRC = ctype.3c
+iscntrl_l.3c := LINKSRC = ctype.3c
isdigit.3c := LINKSRC = ctype.3c
+isdigit_l.3c := LINKSRC = ctype.3c
isgraph.3c := LINKSRC = ctype.3c
+isgraph_l.3c := LINKSRC = ctype.3c
islower.3c := LINKSRC = ctype.3c
+islower_l.3c := LINKSRC = ctype.3c
isprint.3c := LINKSRC = ctype.3c
+isprint_l.3c := LINKSRC = ctype.3c
ispunct.3c := LINKSRC = ctype.3c
+ispunct_l.3c := LINKSRC = ctype.3c
isspace.3c := LINKSRC = ctype.3c
+isspace_l.3c := LINKSRC = ctype.3c
isupper.3c := LINKSRC = ctype.3c
+isupper_l.3c := LINKSRC = ctype.3c
isxdigit.3c := LINKSRC = ctype.3c
+isxdigit_l.3c := LINKSRC = ctype.3c
decimal_to_double.3c := LINKSRC = decimal_to_floating.3c
decimal_to_extended.3c := LINKSRC = decimal_to_floating.3c
@@ -1462,6 +1556,8 @@ getchar.3c := LINKSRC = fgetc.3c
getchar_unlocked.3c := LINKSRC = fgetc.3c
getw.3c := LINKSRC = fgetc.3c
+fgetwc_l.3c := LINKSRC = fgetwc.3c
+
double_to_decimal.3c := LINKSRC = floating_to_decimal.3c
extended_to_decimal.3c := LINKSRC = floating_to_decimal.3c
quadruple_to_decimal.3c := LINKSRC = floating_to_decimal.3c
@@ -1591,6 +1687,10 @@ getvfsany.3c := LINKSRC = getvfsent.3c
getvfsfile.3c := LINKSRC = getvfsent.3c
getvfsspec.3c := LINKSRC = getvfsent.3c
+getwc_l.3c := LINKSRC = getwc.3c
+
+getwchar_l.3c := LINKSRC = getwchar.3c
+
fgetws.3c := LINKSRC = getws.3c
getzoneidbyname.3c := LINKSRC = getzoneid.3c
@@ -1616,17 +1716,41 @@ isnumber.3c := LINKSRC = iswalpha.3c
isphonogram.3c := LINKSRC = iswalpha.3c
isspecial.3c := LINKSRC = iswalpha.3c
iswalnum.3c := LINKSRC = iswalpha.3c
+iswalnum_l.3c := LINKSRC = iswalpha.3c
+iswalpha_l.3c := LINKSRC = iswalpha.3c
iswascii.3c := LINKSRC = iswalpha.3c
iswblank.3c := LINKSRC = iswalpha.3c
+iswblank_l.3c := LINKSRC = iswalpha.3c
iswcntrl.3c := LINKSRC = iswalpha.3c
+iswcntrl_l.3c := LINKSRC = iswalpha.3c
iswdigit.3c := LINKSRC = iswalpha.3c
+iswdigit_l.3c := LINKSRC = iswalpha.3c
iswgraph.3c := LINKSRC = iswalpha.3c
+iswgraph_l.3c := LINKSRC = iswalpha.3c
+iswhexnumber.3c := LINKSRC = iswalpha.3c
+iswhexnumber_l.3c := LINKSRC = iswalpha.3c
+iswideogram.3c := LINKSRC = iswalpha.3c
+iswideogram_l.3c := LINKSRC = iswalpha.3c
iswlower.3c := LINKSRC = iswalpha.3c
+iswlower_l.3c := LINKSRC = iswalpha.3c
+iswnumber.3c := LINKSRC = iswalpha.3c
+iswnumber_l.3c := LINKSRC = iswalpha.3c
+iswphonogram.3c := LINKSRC = iswalpha.3c
+iswphonogram_l.3c := LINKSRC = iswalpha.3c
iswprint.3c := LINKSRC = iswalpha.3c
+iswprint_l.3c := LINKSRC = iswalpha.3c
iswpunct.3c := LINKSRC = iswalpha.3c
+iswpunct_l.3c := LINKSRC = iswalpha.3c
iswspace.3c := LINKSRC = iswalpha.3c
+iswspace_l.3c := LINKSRC = iswalpha.3c
+iswspecial.3c := LINKSRC = iswalpha.3c
+iswspecial_l.3c := LINKSRC = iswalpha.3c
iswupper.3c := LINKSRC = iswalpha.3c
+iswupper_l.3c := LINKSRC = iswalpha.3c
iswxdigit.3c := LINKSRC = iswalpha.3c
+iswxdigit_l.3c := LINKSRC = iswalpha.3c
+
+iswctype_l.3c := LINKSRC = iswctype.3c
ulckpwdf.3c := LINKSRC = lckpwdf.3c
@@ -1644,6 +1768,22 @@ memalign.3c := LINKSRC = malloc.3c
realloc.3c := LINKSRC = malloc.3c
valloc.3c := LINKSRC = malloc.3c
+mblen_l.3c := LINKSRC = mblen.3c
+
+mbrlen_l.3c := LINKSRC = mbrlen.3c
+
+mbrtowc_l.3c := LINKSRC = mbrtowc.3c
+
+mbsinit_l.3c := LINKSRC = mbsinit.3c
+
+mbsnrtowcs.3c := LINKSRC = mbsrtowcs.3c
+mbsnrtowcs_l.3c := LINKSRC = mbsrtowcs.3c
+mbsrtowcs_l.3c := LINKSRC = mbsrtowcs.3c
+mbstowcs.3c := LINKSRC = mbsrtowcs.3c
+mbstowcs_l.3c := LINKSRC = mbsrtowcs.3c
+
+mbtowc_l.3c := LINKSRC = mbtowc.3c
+
membar_consumer.3c := LINKSRC = membar_ops.3c
membar_enter.3c := LINKSRC = membar_ops.3c
membar_exit.3c := LINKSRC = membar_ops.3c
@@ -1687,6 +1827,11 @@ dbm_nextkey.3c := LINKSRC = ndbm.3c
dbm_open.3c := LINKSRC = ndbm.3c
dbm_store.3c := LINKSRC = ndbm.3c
+duplocale.3c := LINKSRC = newlocale.3c
+freelocale.3c := LINKSRC = newlocale.3c
+
+nl_langinfo_l.3c := LINKSRC = nl_langinfo.3c
+
fdopendir.3c := LINKSRC = opendir.3c
errno.3c := LINKSRC = perror.3c
@@ -1938,12 +2083,18 @@ stdout.3c := LINKSRC = stdio.3c
sig2str.3c := LINKSRC = str2sig.3c
+strcoll_l.3c := LINKSRC = strcoll.3c
+
strerror_r.3c := LINKSRC = strerror.3c
+strfmon_l.3c := LINKSRC = strfmon.3c
+
ascftime.3c := LINKSRC = strftime.3c
cftime.3c := LINKSRC = strftime.3c
+strftime_l.3c := LINKSRC = strftime.3c
strcasecmp.3c := LINKSRC = string.3c
+strcasecmp_l.3c := LINKSRC = string.3c
strcat.3c := LINKSRC = string.3c
strchr.3c := LINKSRC = string.3c
strcmp.3c := LINKSRC = string.3c
@@ -1954,6 +2105,7 @@ strlcat.3c := LINKSRC = string.3c
strlcpy.3c := LINKSRC = string.3c
strlen.3c := LINKSRC = string.3c
strncasecmp.3c := LINKSRC = string.3c
+strncasecmp_l.3c := LINKSRC = string.3c
strncat.3c := LINKSRC = string.3c
strncmp.3c := LINKSRC = string.3c
strncpy.3c := LINKSRC = string.3c
@@ -1969,6 +2121,8 @@ strtok_r.3c := LINKSRC = string.3c
file_to_decimal.3c := LINKSRC = string_to_decimal.3c
func_to_decimal.3c := LINKSRC = string_to_decimal.3c
+strptime_l.3c := LINKSRC = strptime.3c
+
atof.3c := LINKSRC = strtod.3c
strtof.3c := LINKSRC = strtod.3c
strtold.3c := LINKSRC = strtod.3c
@@ -1983,8 +2137,11 @@ strtoll.3c := LINKSRC = strtol.3c
ulltostr.3c := LINKSRC = strtol.3c
strtoull.3c := LINKSRC = strtoul.3c
+
wstostr.3c := LINKSRC = strtows.3c
+strxfrm_l.3c := LINKSRC = strxfrm.3c
+
closelog.3c := LINKSRC = syslog.3c
openlog.3c := LINKSRC = syslog.3c
setlogmask.3c := LINKSRC = syslog.3c
@@ -2010,6 +2167,14 @@ timersub.3c := LINKSRC = timeradd.3c
tempnam.3c := LINKSRC = tmpnam.3c
tmpnam_r.3c := LINKSRC = tmpnam.3c
+tolower_l.3c := LINKSRC = tolower.3c
+
+toupper_l.3c := LINKSRC = toupper.3c
+
+towlower_l.3c := LINKSRC = towlower.3c
+
+towupper_l.3c := LINKSRC = towupper.3c
+
ftruncate.3c := LINKSRC = truncate.3c
tdelete.3c := LINKSRC = tsearch.3c
@@ -2056,6 +2221,9 @@ backtrace_symbols.3c := LINKSRC = walkcontext.3c
backtrace_symbols_fd.3c := LINKSRC = walkcontext.3c
printstack.3c := LINKSRC = walkcontext.3c
+wcrtomb_l.3c := LINKSRC = wcrtomb.3c
+
+wcscoll_l.3c := LINKSRC = wcscoll.3c
wscoll.3c := LINKSRC = wcscoll.3c
watof.3c := LINKSRC = wcstod.3c
@@ -2102,16 +2270,29 @@ wspbrk.3c := LINKSRC = wcstring.3c
wsrchr.3c := LINKSRC = wcstring.3c
wsspn.3c := LINKSRC = wcstring.3c
wstok.3c := LINKSRC = wcstring.3c
-
-wsxfrm.3c := LINKSRC = wcsxfrm.3c
-
-wordfree.3c := LINKSRC = wordexp.3c
-
wscasecmp.3c := LINKSRC = wstring.3c
wscol.3c := LINKSRC = wstring.3c
wsdup.3c := LINKSRC = wstring.3c
wsncasecmp.3c := LINKSRC = wstring.3c
+wcswidth_l.3c := LINKSRC = wcswidth.3c
+
+wsxfrm.3c := LINKSRC = wcsxfrm.3c
+
+wctob_l.3c := LINKSRC = wctob.3c
+
+wctomb_l.3c := LINKSRC = wctomb.3c
+
+towctrans.3c := LINKSRC = wctrans.3c
+towctrans_l.3c := LINKSRC = wctrans.3c
+wctrans_l.3c := LINKSRC = wctrans.3c
+
+wctype_l.3c := LINKSRC = wctype.3c
+
+wcwidth_l.3c := LINKSRC = wcwidth.3c
+
+wordfree.3c := LINKSRC = wordexp.3c
+
.KEEP_STATE:
include $(SRC)/man/Makefile.man
diff --git a/usr/src/man/man3c/btowc.3c b/usr/src/man/man3c/btowc.3c
index ad5c197974..56dc9e19a2 100644
--- a/usr/src/man/man3c/btowc.3c
+++ b/usr/src/man/man3c/btowc.3c
@@ -1,5 +1,6 @@
'\" te
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
.\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between these versions and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH BTOWC 3C "Jul 24, 2002"
+.TH BTOWC 3C "Jun 27, 2014"
.SH NAME
-btowc \- single-byte to wide-character conversion
+btowc, btowc_l \- single-byte to wide-character conversion
.SH SYNOPSIS
.LP
.nf
@@ -18,52 +19,55 @@ btowc \- single-byte to wide-character conversion
\fBwint_t\fR \fBbtowc\fR(\fBint\fR \fIc\fR);
.fi
+.LP
+.nf
+#include <stdio.h>
+#include <wchar.h>
+#include <xlocale.h>
+\fBwint_t\fR \fBbtowc_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-The \fBbtowc()\fR function determines whether \fIc\fR constitutes a valid
-(one-byte) character in the initial shift state.
-.sp
+The \fBbtowc()\fR and \fBbtowc_l\fR()functions determines whether
+\fIc\fR constitutes a valid (one-byte) character in the initial shift
+state.
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The behavior of \fBbtowc()\fR is affected by the \fBLC_CTYPE\fR category of the
+current locale. See \fBenviron\fR(5). The function \fBbtowc_l()\fR does
+not use the current locale, and instead operates on the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
The \fBbtowc()\fR function returns \fBWEOF\fR if \fIc\fR has the value
\fBEOF\fR or if \fB(unsigned char)\fR\fIc\fR does not constitute a valid
(one-byte) character in the initial shift state. Otherwise, it returns the
wide-character representation of that character.
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBwctob\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5),
-\fBstandards\fR(5)
-.SH NOTES
+The
+.B btowc()
+function is Standard. The
+.B btowc_l()
+function is Uncommitted.
+.SH SEE ALSO
.sp
.LP
-The \fBbtowc()\fR function can be used safely in multithreaded applications, as
-long as \fBsetlocale\fR(3C) is not being called to change the locale.
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C), \fBwctob\fR(3C),
+\fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/ctype.3c b/usr/src/man/man3c/ctype.3c
index e9849003cc..5d5435f221 100644
--- a/usr/src/man/man3c/ctype.3c
+++ b/usr/src/man/man3c/ctype.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright 1989 AT&T. Copyright (c) 1992, X/Open Company Limited All Rights Reserved. Portions Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,10 +8,12 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH CTYPE 3C "Jan 28, 2005"
+.TH CTYPE 3C "Jun 27, 2014"
.SH NAME
-ctype, isalpha, isalnum, isascii, isblank, iscntrl, isdigit, islower, isprint,
-isspace, isupper, ispunct, isgraph, isxdigit \- character handling
+ctype, isalpha, isalnum, isascii, isblank, iscntrl, isdigit, islower,
+isprint, isspace, isupper, ispunct, isgraph, isxdigit, isalpha_l,
+isalnum_l, isblank_l, iscntrl_l, isdigit_l, islower_l, isprint_l,
+isspace_l, isupper_l, ispunct_l, isgraph_l \- character handling
.SH SYNOPSIS
.LP
.nf
@@ -18,106 +21,123 @@ isspace, isupper, ispunct, isgraph, isxdigit \- character handling
\fBint\fR \fBisalpha\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisalnum\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisascii\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisblank\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiscntrl\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisdigit\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisgraph\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBislower\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisprint\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBispunct\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisspace\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisupper\fR(\fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisxdigit\fR(\fBint\fR \fIc\fR);
.fi
-
+.LP
+.nf
+\fBint\fR \fBisalpha_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisalnum_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisblank_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiscntrl_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisdigit_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisgraph_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBislower_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisprint_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBispunct_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisspace_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBisupper_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-These macros classify character-coded integer values. Each is a predicate
-returning non-zero for true, \fB0\fR for false. The behavior of these macros,
-except \fBisascii()\fR, is affected by the current locale (see
-\fBsetlocale\fR(3C)). To modify the behavior, change the \fBLC_TYPE\fR category
-in \fBsetlocale()\fR, that is, \fBsetlocale(\fR\fBLC_CTYPE\fR,
-\fInewlocale\fR). In the "C" locale, or in a locale where character type
-information is not defined, characters are classified according to the rules of
-the \fBUS-ASCII\fR 7-bit coded character set.
-.sp
+These functions classify character-coded integer values. Each is a
+predicate returning non-zero for true, \fB0\fR for false. The behavior
+of these macros, except \fBisascii()\fR, is affected by the current
+locale (see \fBsetlocale\fR(3C) and \fBuselocale\fR(3C)). To modify
+the behavior, change the \fBLC_TYPE\fR category in \fBsetlocale()\fR, that is,
+\fBsetlocale(\fR\fBLC_CTYPE\fR, \fInewlocale\fR). In the "C" locale,
+or in a locale where character type information is not defined,
+characters are classified according to the rules of the \fBUS-ASCII\fR
+7-bit coded character set.
+.LP
+The functions \fBisalnum_l()\fR, \fBisalpha_l()\fR, \fBisblank_l()\fR,
+\fBiscntrl_l\fR, \fBisdigit_l()\fR, \fBislower_l()\fR,
+\fBisprint_l()\fR, \fBispunct_l()\fR, \fBisspace_l()\fR,
+\fBisupper_l()\fR, all behave identically to their counterparts without
+the '\fB_l\fR' prefix, except that instead of acting on the current
+locale, that perform the test on the locale specified in the argument
+\fIloc\fR.
.LP
The \fBisascii()\fR macro is defined on all integer values. The rest are
defined only where the argument is an \fBint\fR, the value of which is
representable as an \fBunsigned char\fR, or \fBEOF\fR, which is defined by the
<\fBstdio.h\fR> header and represents end-of-file.
.sp
-.LP
-Functions exist for all the macros defined below. To get the function form, the
-macro name must be undefined (for example, \fB#undef isdigit\fR).
-.sp
-.LP
-For macros described with \fBDefault\fR and \fBStandard conforming\fR versions,
-standard-conforming behavior is provided for standard-conforming applications
-(see \fBstandards\fR(5)) and for applications that define
-\fB__XPG4_CHAR_CLASS__\fR before including <\fBctype.h\fR>.
-.SS "Default"
-.sp
-.ne 2
-.na
-\fB\fBisalpha()\fR\fR
-.ad
-.RS 13n
-Tests for any character for which \fBisupper()\fR or \fBislower()\fR is true.
-.RE
-
-.SS "Standard conforming"
-.sp
.ne 2
.na
\fB\fBisalpha()\fR\fR
@@ -178,18 +198,6 @@ Tests for any ``control character'' as defined by the character set.
Tests for any decimal-digit character.
.RE
-.SS "Default"
-.sp
-.ne 2
-.na
-\fB\fBisgraph()\fR\fR
-.ad
-.RS 13n
-Tests for any character for which \fBispunct()\fR, \fBisupper()\fR,
-\fBislower()\fR, and \fBisdigit()\fR is true.
-.RE
-
-.SS "Standard conforming"
.sp
.ne 2
.na
@@ -214,18 +222,6 @@ In the "C" locale, \fBislower()\fR returns true only for the characters defined
as lower-case \fBASCII\fR characters.
.RE
-.SS "Default"
-.sp
-.ne 2
-.na
-\fB\fBisprint()\fR\fR
-.ad
-.RS 13n
-Tests for any character for which \fBispunct()\fR, \fBisupper()\fR,
-\fBislower()\fR, \fBisdigit()\fR, and the space character ("\|") is true.
-.RE
-
-.SS "Standard conforming"
.sp
.ne 2
.na
@@ -272,18 +268,6 @@ In the "C" locale, \fBisupper()\fR returns true only for the characters defined
as upper-case \fBASCII\fR characters.
.RE
-.SS "Default"
-.sp
-.ne 2
-.na
-\fB\fBisxdigit()\fR\fR
-.ad
-.RS 14n
-Tests for any hexadecimal-digit character (\fB[0\(mi9]\fR, \fB[A\(miF]\fR, or
-\fB[a\(mif]\fR).
-.RE
-
-.SS "Standard conforming"
.sp
.ne 2
.na
@@ -304,36 +288,30 @@ are included.
.RE
.SH RETURN VALUES
-.sp
.LP
If the argument to any of the character handling macros is not in the domain of
the function, the result is undefined. Otherwise, the macro or function returns
non-zero if the classification is \fBTRUE\fR and \fB0\fR if the classification
is \fBFALSE\fR.
-.SH USAGE
-.sp
-.LP
-These macros or functions can be used safely in multithreaded applications, as
-long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH ATTRIBUTES
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
-l l
-l l .
+c | c
+l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
CSI Enabled
+_
Interface Stability Standard
-MT-Level MT-Safe with exceptions
+_
+MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBstdio\fR(3C), \fBascii\fR(5), \fBenviron\fR(5),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBstdio\fR(3C), \fBascii\fR(5), \fBenviron\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/fgetwc.3c b/usr/src/man/man3c/fgetwc.3c
index 4e9302bdcf..8b75c6cc55 100644
--- a/usr/src/man/man3c/fgetwc.3c
+++ b/usr/src/man/man3c/fgetwc.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2003, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 1996, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,32 +8,41 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH FGETWC 3C "Oct 15, 2003"
+.TH FGETWC 3C "Jun 24, 2014"
.SH NAME
-fgetwc \- get a wide-character code from a stream
+fgetwc, fgetwc_l \- get a wide-character code from a stream
.SH SYNOPSIS
.LP
.nf
#include <stdio.h>
#include <wchar.h>
-\fBwint_t\fR \fBfgetwc\fR(\fBFILE*\fR\fIstream\fR);
+\fBwint_t\fR \fBfgetwc\fR(\fBFILE *\fR\fIstream\fR);
+.fi
+.LP
+.nf
+#include <stdio.h>
+#include <wchar.h>
+#include <xlocale.h>
+
+\fBwint_t\fR \fBfgetwc_l\fR(\fBFILE *\fR\fIstream\fR, \fBlocale_t\fR, \fIloc\fR);
.fi
.SH DESCRIPTION
.sp
.LP
-The \fBfgetwc()\fR function obtains the next character (if present) from the
-input stream pointed to by \fIstream\fR, converts that to the corresponding
-wide-character code and advances the associated file position indicator for the
-stream (if defined).
-.sp
+The \fBfgetwc()\fR and \fBfgetwc_l()\fR functions obtain the next
+character (if present) from the input stream pointed to by \fIstream\fR,
+convert that to the corresponding wide-character code and advance the
+associated file position indicator for the stream (if defined).
+Whereas \fBfgetwc()\fR uses the current locale, \fBfgetwc_l()\fR uses the
+locale specified by \fIloc\R.
.LP
If an error occurs, the resulting value of the file position indicator for the
stream is indeterminate.
-.sp
.LP
-The \fBfgetwc()\fR function may mark the \fBst_atime\fR field of the file
+The \fBfgetwc()\fR and \fBfgetwc_l()\fR functions may mark the \fBst_atime\fR
+field of the file
associated with \fIstream\fR for update. The \fBst_atime\fR field will be
marked for update by the first successful execution of \fBfgetwc()\fR,
\fBfgetc\fR(3C), \fBfgets\fR(3C), \fBfgetws\fR(3C), \fBfread\fR(3C),
@@ -40,112 +50,62 @@ marked for update by the first successful execution of \fBfgetwc()\fR,
\fBscanf\fR(3C) using \fIstream\fR that returns data not supplied by a prior
call to \fBungetc\fR(3C) or \fBungetwc\fR(3C).
.SH RETURN VALUES
-.sp
.LP
-Upon successful completion the \fBfgetwc()\fR function returns the
+Upon successful completion both functions return the
wide-character code of the character read from the input stream pointed to by
\fIstream\fR converted to a type \fBwint_t\fR.
-.sp
.LP
For standard-conforming (see \fBstandards\fR(5)) applications, if the
-end-of-file indicator for the stream is set, \fBfgetwc()\fR returns \fBWEOF\fR
-whether or not the stream is at end-of-file.
-.sp
+end-of-file indicator for the stream is set, \fBfgetwc()\fR and
+\fBfgetwc_l()\fR return \fBWEOF\fR whether or not the stream is at
+end-of-file.
.LP
If a read error occurs, the error indicator for the stream is set,
-\fBfgetwc()\fR returns \fBWEOF\fR and sets \fBerrno\fR to indicate the error.
-.sp
+\fBfgetwc()\fR and \fBfgetwc_l()\fR returns \fBWEOF\fR and sets
+\fBerrno\fR to indicate the error.
.LP
If an encoding error occurs, the error indicator for the stream is set,
-\fBfgetwc()\fR returns \fBWEOF\fR, and \fBerrno\fR is set to indicate the
-error.
+\fBfgetwc()\fR and \fBfgetwc_l()\fR return \fBWEOF\fR, and \fBerrno\fR is
+set to indicate the error.
.SH ERRORS
-.sp
.LP
-The \fBfgetwc()\fR function will fail if data needs to be read and:
-.sp
-.ne 2
-.na
-\fB\fBEAGAIN\fR\fR
-.ad
-.RS 14n
+The \fBfgetwc()\fR and \fBfgetwc_l()\fR functions will fail if data needs to be
+read and:
+.TP
+.B EAGAIN
The \fBO_NONBLOCK\fR flag is set for the file descriptor underlying
-\fIstream\fR and the process would be delayed in the \fBfgetwc()\fR operation.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEBADF\fR\fR
-.ad
-.RS 14n
+\fIstream\fR and the process would be delayed in the \fBfgetwc()\fR or
+\fBfgetwc_l()\fR operation.
+.TP
+.B EBADF
The file descriptor underlying \fIstream\fR is not a valid file descriptor open
for reading.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEINTR\fR\fR
-.ad
-.RS 14n
+.TP
+.B EINTR
The read operation was terminated due to the receipt of a signal, and no data
was transferred.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEIO\fR\fR
-.ad
-.RS 14n
+.TP
+.B EIO
A physical I/O error has occurred, or the process is in a background process
group attempting to read from its controlling terminal and either the process
is ignoring or blocking the \fBSIGTTIN\fR signal or the process group is
orphaned.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEOVERFLOW\fR \fR
-.ad
-.RS 14n
+.TP
+.B EOVERFLOW
The file is a regular file and an attempt was made to read at or beyond the
offset maximum associated with the corresponding \fIstream\fR.
-.RE
-
-.sp
.LP
-The \fBfgetwc()\fR function may fail if:
-.sp
-.ne 2
-.na
-\fB\fBENOMEM\fR\fR
-.ad
-.RS 10n
-Insufficient storage space is available.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBENXIO\fR\fR
-.ad
-.RS 10n
+The \fBfgetwc()\fR and \fBfgetwc_l()\fR functions may fail if:
+.TP
+.B ENOMEM
+Insufficient memory is available.
+.TP
+.B ENXIO
A request was made of a non-existent device, or the request was outside the
capabilities of the device.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEILSEQ\fR\fR
-.ad
-.RS 10n
+.TP
+.B EILSEQ
The data obtained from the input stream does not form a valid character.
-.RE
-
.SH USAGE
.sp
.LP
@@ -155,27 +115,30 @@ between an error condition and an end-of-file condition.
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
-l | l
+c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The
+.B fgetwc()
+function is Standard. The
+.B fgetwc_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
\fBfeof\fR(3C), \fBferror\fR(3C), \fBfgetc\fR(3C), \fBfgets\fR(3C),
\fBfgetws\fR(3C), \fBfopen\fR(3C), \fBfread\fR(3C), \fBfscanf\fR(3C),
\fBgetc\fR(3C), \fBgetchar\fR(3C), \fBgets\fR(3C), \fBscanf\fR(3C),
-\fBsetlocale\fR(3C), \fBungetc\fR(3C), \fBungetwc\fR(3C), \fBattributes\fR(5),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBungetc\fR(3C), \fBungetwc\fR(3C),
+\fBuselocale\fR(3C), \fBattributes\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/getwc.3c b/usr/src/man/man3c/getwc.3c
index 132d00f099..900f8e8080 100644
--- a/usr/src/man/man3c/getwc.3c
+++ b/usr/src/man/man3c/getwc.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH GETWC 3C "Jul 24, 2002"
+.TH GETWC 3C "Jul 11, 2014"
.SH NAME
-getwc \- get wide character from a stream
+getwc, getwc_l \- get wide character from a stream
.SH SYNOPSIS
.LP
.nf
@@ -18,6 +19,14 @@ getwc \- get wide character from a stream
\fBwint_t\fR \fBgetwc\fR(\fBFILE\fR \fI*stream\fR);
.fi
+.LP
+.nf
+#include <stdio.h>
+#include <wchar.h>
+#include <xlocale.h>
+
+\fBwint_t\fR \fBgetwc_l\fR(\fBFILE\fR \fI*stream\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
.sp
@@ -25,44 +34,46 @@ getwc \- get wide character from a stream
The \fBgetwc()\fR function is equivalent to \fBfgetwc\fR(3C), except that if it
is implemented as a macro it may evaluate \fIstream\fR more than once, so the
argument should never be an expression with side effects.
+.LP
+The \fBgetwc_l()\fR function is similar to \fBgetwc()\fR, except instead of
+acting on the current locale, it uses the locale specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
Refer to \fBfgetwc\fR(3C).
.SH ERRORS
-.sp
.LP
Refer to \fBfgetwc\fR(3C).
.SH USAGE
-.sp
.LP
This interface is provided to align with some current implementations and with
possible future \fBISO\fR standards.
-.sp
.LP
-Because it may be implemented as a macro, \fBgetwc()\fR may treat incorrectly a
-\fIstream\fR argument with side effects. In particular,
-\fBgetwc\fR(*\fIf\fR\|++) may not work as expected. Therefore, use of this
-function is not recommended; \fBfgetwc\fR(3C) should be used instead.
+Because they may be implemented as macros, these functions may treat incorrectly
+a \fIstream\fR argument with side effects. In particular,
+\fBgetwc\fR(*\fIf\fR\|++) may not work as expected. Therefore, use of these
+functions is not recommended; \fBfgetwc\fR(3C) and \fBfgetwc_l\fR(3C)
+should be used instead.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
MT-Level MT-Safe
.TE
+.LP
+The
+.B getwc()
+function is Standard. The
+.B getwc_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBfgetwc\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
+\fBfgetwc\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/getwchar.3c b/usr/src/man/man3c/getwchar.3c
index 8aa26f269c..2c20fb27b1 100644
--- a/usr/src/man/man3c/getwchar.3c
+++ b/usr/src/man/man3c/getwchar.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -17,45 +18,47 @@ getwchar \- get wide character from stdin stream
\fBwint_t\fR \fBgetwchar\fR(void)
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBwint_t\fR \fBgetwchar_l\fR(locale_t loc)
+.fi
.SH DESCRIPTION
-.sp
.LP
-The \fBgetwchar()\fR function is equivalent to \fBgetwc(stdin)\fR.
+The \fBgetwchar()\fR function is equivalent to \fBgetwc\fR(\fBstdin\fR).
+.LP
+The\fBgetwchar_l()\fR function is equivalent to \fBgetwc\fR(\fBstdin\fR, \fIloc\fR).
.SH RETURN VALUES
-.sp
.LP
Refer to \fBfgetwc\fR(3C).
.SH ERRORS
-.sp
.LP
Refer to \fBfgetwc\fR(3C).
.SH USAGE
-.sp
.LP
If the \fBwint_t\fR value returned by \fBgetwchar()\fR is stored into a
variable of type \fBwchar_t\fR and then compared against the \fBwint_t\fR macro
\fBWEOF\fR, the comparison may never succeed because \fBwchar_t\fR is defined
as unsigned.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
MT-Level MT-Safe
.TE
+.LP
+The \fBgetwchar()\fR function is Standard. The \fBgetwchar_l()\fR function
+is Uncommitted.
.SH SEE ALSO
-.sp
.LP
\fBfgetwc\fR(3C), \fBgetwc\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/iswalpha.3c b/usr/src/man/man3c/iswalpha.3c
index e109525594..916aad0ffc 100644
--- a/usr/src/man/man3c/iswalpha.3c
+++ b/usr/src/man/man3c/iswalpha.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,11 +8,17 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH ISWALPHA 3C "Apr 19, 2004"
+.TH ISWALPHA 3C "Jun 23, 2014"
.SH NAME
-iswalpha, isenglish, isideogram, isnumber, isphonogram, isspecial, iswalnum,
-iswascii, iswblank, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct,
-iswspace, iswupper, iswxdigit \- wide-character code classification functions
+iswalpha, isenglish, isideogram, iswideogram, isnumber, iswnumber,
+isphonogram, iswphonogram, isspecial, iswspecial, iswalnum, iswascii,
+iswblank, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct,
+iswspace, iswupper, iswxdigit, iswhexnumber, iswalpha_l, iswideogram_l,
+iswnumber_l, iswphonogram_l, iswspecial_l, iswalnum_l, iswascii_l,
+iswblank_l, iswcntrl_l, iswdigit_l, iswgraph_l, iswlower_l, iswprint_l,
+iswpunct_l, iswspace_l, iswupper_l, iswhexnumber_l \- wide-character
+code classification functions
+
.SH SYNOPSIS
.LP
.nf
@@ -20,99 +27,187 @@ iswspace, iswupper, iswxdigit \- wide-character code classification functions
\fBint\fR \fBiswalpha\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisenglish\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisideogram\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisnumber\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisphonogram\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBisspecial\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswalnum\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswascii\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswblank\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswcntrl\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswdigit\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswgraph\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswlower\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswprint\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswpunct\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswspace\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswupper\fR(\fBwint_t\fR \fIwc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBiswxdigit\fR(\fBwint_t\fR \fIwc\fR);
.fi
+.LP
+.nf
+\fBint\fR \fBiswhexnumber\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswideogram\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswnumber\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswphonogram\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswspecial\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswalpha_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswideogram_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswnumber_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswphonogram_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswspecial_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswalnum_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswascii_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswblank_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswcntrl_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswdigit_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswgraph_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswlower_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswprint_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswpunct_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswspace_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswupper\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBint\fR \fBiswxdigit\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+#include <xlocale.h>
+
+\fBint\fR \fBiswhexnumber\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
These functions test whether \fIwc\fR is a wide-character code representing a
character of a particular class defined in the \fBLC_CTYPE\fR category of the
-current locale.
-.sp
+current locale or the locale specified by \fIloc\fR.
+.LP
+The functions \fBiswalpha_l()\fR, \fBiswideogram_l()\fR, \fBiswnumber_l()\fR,
+\fBiswphonogram_l()\fR, \fBiswspecial_l()\fR, \fBiswalnum_l()\fR,
+\fBiswascii_l()\fR, \fBiswblank_l()\fR, \fBiswcntrl_l()\fR, \fBiswdigit_l()\fR,
+\fBiswgraph_l()\fR, \fBiswlower_l()\fR, \fBiswprint_l()\fR, \fBiswpunct_l()\fR,
+\fBiswspace_l()\fR, \fBiswupper_l()\fR, all behave identically to their
+counterparts without the '\fB_l\fR' suffix, but instead of operating on the
+current locale, they operate on the locale specified by \fIloc\fR.
+.LP
+The functions, \fBiswideogram()\fR, \fBiswnumber()\fR, \fBiswphonogram()\fR,
+\fBiswspecial()\fR, and \fBiswhexnumber()\fR, are respectively identical to
+\fBisideogram()\fR, \fBisnumber()\fR, \fBisphonogram()\fR, \fBisspecial()\fR,
+\fBiswxdigit()\fR respectively. They are provided for compatability purposes.
.LP
In all cases, \fIwc\fR is a \fBwint_t\fR, the value of which must be a
wide-character code corresponding to a valid character in the current locale or
@@ -303,30 +398,31 @@ class "xdigit" in the program's current locale.
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
-l | l
+c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability See below.
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.sp
.LP
The \fBiswalpha()\fR, \fBiswalnum()\fR, \fBiswblank()\fR, \fBiswcntrl()\fR,
\fBiswdigit()\fR, \fBiswgraph()\fR, \fBiswlower()\fR, \fBiswprint()\fR,
\fBiswpunct()\fR, \fBiswspace()\fR, \fBiswupper()\fR, and \fBiswxdigit()\fR
functions are Standard.
+.LP
+The \fBiswalpha_l()\fR, \fBiswalnum_l()\fR, \fBiswblank_l()\fR, \fBiswcntrl_l()\fR,
+\fBiswdigit_l()\fR, \fBiswgraph_l()\fR, \fBiswlower_l()\fR, \fBiswprint_l()\fR,
+\fBiswpunct_l()\fR, \fBiswspace_l()\fR, and \fBiswupper_l()\fR
+functions are Standard.
.SH SEE ALSO
-.sp
.LP
-\fBlocaledef\fR(1), \fBsetlocale\fR(3C), \fBstdio\fR(3C), \fBascii\fR(5),
-\fBattributes\fR(5), \fBstandards\fR(5)
+\fBlocaledef\fR(1), \fBnewlocale\fR(3C),
+\fBsetlocale\fR(3C), \fBstdio\fR(3C), \fBuselocale\fR(3C),
+\fBascii\fR(5), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/iswctype.3c b/usr/src/man/man3c/iswctype.3c
index a925f4b07b..9da9eef82a 100644
--- a/usr/src/man/man3c/iswctype.3c
+++ b/usr/src/man/man3c/iswctype.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,7 +8,7 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH ISWCTYPE 3C "Jul 24, 2002"
+.TH ISWCTYPE 3C "Jul 26, 2014"
.SH NAME
iswctype \- test character for specified class
.SH SYNOPSIS
@@ -17,33 +18,61 @@ iswctype \- test character for specified class
\fBint\fR \fBiswctype\fR(\fBwint_t\fR \fIwc\fR, \fBwctype_t\fR \fIcharclass\fR);
.fi
+.LP
+.nf
+\fBint\fR \fBiswctype\fR(\fBwint_t\fR \fIwc\fR, \fBwctype_t\fR \fIcharclass\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-The \fBiswctype()\fR function determines whether the wide-character code
-\fIwc\fR has the character class \fIcharclass\fR, returning \fBTRUE\fR or
-\fBFALSE\fR. The \fBiswctype()\fR function is defined on \fBWEOF\fR and
-wide-character codes corresponding to the valid character encodings in the
-current locale. If the \fIwc\fR argument is not in the domain of the function,
-the result is undefined. If the value of \fIcharclass\fR is invalid (that is,
-not obtained by a call to \fBwctype\fR(3C) or \fIcharclass \fR is invalidated
-by a subsequent call to \fBsetlocale\fR(3C) that has affected category
-\fBLC_CTYPE\fR), the result is indeterminate.
+The
+.B iswctype()
+and
+.B iswctype_l()
+functions determine whether the wide-character code
+.I wc
+is a member of the character class
+.IR charclass ,
+returning
+.B TRUE
+or
+.BR FALSE .
+These functions are defined on
+.B WEOF
+and wide-character codes corresponding to the valid character encodings in the
+current locale (or
+.I loc
+for
+.BR iswctype_l() .)
+If the
+.I wc
+argument is not in the domain of the function,
+the result is undefined. If the value of
+.I charclass
+is invalid (that is,
+not obtained by a call to
+.B wctype (3C)
+or obtained from a different locale), the result is indeterminate.
+.LP
+Whereas
+.B iswctype()
+operates in the current locale,
+.B iswctype_l()
+operates in the locale specified with
+.IR loc .
.SH RETURN VALUES
-.sp
.LP
-The \fBiswctype()\fR function returns \fB0\fR for \fBFALSE\fR and non-zero for
-\fBTRUE\fR.
+These functions return
+.B 0
+for
+.B FALSE
+and non-zero for
+.BR TRUE .
.SH USAGE
-.sp
.LP
There are twelve strings that are reserved for the standard character classes:
-.sp
-
-.sp
.TS
-l | l | l
+box;
l | l | l .
"alnum" "alpha" "blank"
_
@@ -54,45 +83,36 @@ _
"space" "upper" "xdigit"
.TE
-.sp
.LP
In the table below, the functions in the left column are equivalent to the
functions in the right column.
-.sp
-
-.sp
.TS
-l l
-l l .
-\fBiswalnum(\fR\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"alnum"\fB))\fR
-iswalpha(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"alpha"\fB))\fR
-iswcntrl(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"cntrl"\fB))\fR
-iswdigit(\fI wc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"digit"\fB))\fR
-iswgraph(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"graph"\fB))\fR
-iswlower(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"lower"\fB))\fR
-iswprint(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"print"\fB))\fR
-iswpunct(\fIwc\fR\fB)\fR iswctype(\fI wc,\fR\fB wctype(\fR"punct"\fB))\fR
-iswspace(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"space"\fB))\fR
-iswupper(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"upper"\fB))\fR
-iswxdigit(\fIwc\fR\fB)\fR iswctype(\fIwc,\fR\fB wctype(\fR"xdigit"\fB))\fR
+box;
+l | l .
+\fBiswalnum\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("alnum"))
+\fBiswalpha\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("alpha"))
+\fBiswcntrl\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("cntrl"))
+\fBiswdigit\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("digit"))
+\fBiswgraph\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("graph"))
+\fBiswlower\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("lower"))
+\fBiswprint\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("print"))
+\fBiswpunct\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("punct"))
+\fBiswspace\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("space"))
+\fBiswupper\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("upper"))
+\fBiswxdigit\fR(\fIwc\fR) \fBiswctype\fR(\fIwc\fR, \fBwctype\fR("xdigit"))
.TE
-.sp
.LP
The call
-.sp
.LP
-\fBiswctype(\fR\fIwc,\fR\fB wctype(\fR"blank"\fB))\fR
-.sp
+\fBiswctype\fR(\fIwc\fR, \fBwctype\fR("blank"))
.LP
-does not have an equivalent \fBisw*(\|)\fR function.
+does not have an equivalent \fBisw*(\|)\fR function.
.SH ATTRIBUTES
-.sp
.LP
-See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
+See
+.BR attributes (5)
+for descriptions of the following attributes:
.TS
box;
c | c
@@ -103,11 +123,15 @@ CSI Enabled
_
Interface Stability Standard
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fBiswalpha\fR(3C), \fBsetlocale\fR(3C), \fBwctype\fR(3C), \fBattributes\fR(5),
-\fBenviron\fR(5), \fBstandards\fR(5)
+.BR iswalpha (3C),
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR wctype (3C),
+.BR attributes (5),
+.BR standards (5)
diff --git a/usr/src/man/man3c/mblen.3c b/usr/src/man/man3c/mblen.3c
index 4051e28a52..ef4d8d60cd 100644
--- a/usr/src/man/man3c/mblen.3c
+++ b/usr/src/man/man3c/mblen.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright 1989 AT&T Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBLEN 3C "Jul 24, 2002"
+.TH MBLEN 3C "Jun 24, 2014"
.SH NAME
-mblen \- get number of bytes in a character
+mblen, mblen_l \- get number of bytes in a character
.SH SYNOPSIS
.LP
.nf
@@ -17,25 +18,37 @@ mblen \- get number of bytes in a character
\fBint\fR \fBmblen\fR(\fBconst char *\fR\fIs\fR, \fBsize_t\fR \fIn\fR);
.fi
+.LP
+.nf
+#include <stdlib.h>
+#include <xlocale.h>
+
+\fBint\fR \fBmblen_l\fR(\fBconst char *\fR\fIs\fR, \fBsize_t\fR \fIn\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
.sp
.LP
-If \fIs\fR is not a null pointer, \fBmblen()\fR determines the number of bytes
-constituting the character pointed to by \fIs\fR. It is equivalent to:
-.sp
+If \fIs\fR is not a null pointer, \fBmblen()\fR and \fBmblen_l()\fR
+determine the number of bytes constituting the character pointed to by
+\fIs\fR. The call
+.IP
+\fBmblen(\fIs\fR, \fIn\fR)\fR;
.LP
-\fBmbtowc((wchar_t *)0, \fR\fIs\fR, \fIn\fR);
-.sp
+is equivalent to:
+.IP
+\fBmbtowc\fR((\fBwchar_t\fR *)0, \fIs\fR, \fIn\fR);
.LP
A call with \fIs\fR as a null pointer causes this function to return \fB0\fR.
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale.
+.LP
+Whereas the behavior of the \fBmblen()\fR function is affected by the
+\fBLC_CTYPE\fR category of the current locale, the behavior of
+\fBmblen_l()\fR is affected by the \fBLC_CTYPE\fR category of the
+locale specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-If \fIs\fR is a null pointer, \fBmblen()\fR returns \fB0\fR. It \fIs\fR is not
-a null pointer, \fBmblen()\fR returns \fB0\fR (if \fIs\fR points to the null
+If \fIs\fR is a null pointer, \fBmblen()\fR and \fBmblen_l()\fR returns \fB0\fR. It \fIs\fR is not
+a null pointer, \fBmblen()\fR and \fBmblen_l()\fR returns \fB0\fR (if \fIs\fR points to the null
byte), the number of bytes that constitute the character (if the next \fIn\fR
or fewer bytes form a valid character), or \fB\(mi1\fR (if they do not form a
valid character) and may set \fBerrno\fR to indicate the error. In no case will
@@ -44,7 +57,7 @@ macro.
.SH ERRORS
.sp
.LP
-The \fBmblen()\fR function may fail if:
+The \fBmblen()\fR and \fBmblen_l()\fR functions may fail if:
.sp
.ne 2
.na
@@ -53,12 +66,6 @@ The \fBmblen()\fR function may fail if:
.RS 10n
Invalid character sequence is detected.
.RE
-
-.SH USAGE
-.sp
-.LP
-The \fBmblen()\fR function can be used safely in multithreaded applications, as
-long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH ATTRIBUTES
.sp
.LP
@@ -74,13 +81,19 @@ ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The
+.B mblen()
+function is Standard. The
+.B mblen_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBmbstowcs\fR(3C), \fBmbtowc\fR(3C), \fBsetlocale\fR(3C), \fBwcstombs\fR(3C),
-\fBwctomb\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
+\fBmbstowcs\fR(3C), \fBmbtowc\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBwcstombs\fR(3C), \fBwctomb\fR(3C), \fBuselocale\fR(3C) \fBattributes\fR(5),
+\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/mbrlen.3c b/usr/src/man/man3c/mbrlen.3c
index 8570fc53ce..1f55b8edf0 100644
--- a/usr/src/man/man3c/mbrlen.3c
+++ b/usr/src/man/man3c/mbrlen.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBRLEN 3C "Nov 1, 2003"
+.TH MBRLEN 3C "Jun 21, 2014"
.SH NAME
-mbrlen \- get number of bytes in a character (restartable)
+mbrlen, mbrlen_l \- get number of bytes in a character (restartable)
.SH SYNOPSIS
.LP
.nf
@@ -17,36 +18,46 @@ mbrlen \- get number of bytes in a character (restartable)
\fBsize_t\fR \fBmbrlen\fR(\fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR, \fBmbstate_t *restrict\fR \fIps\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBsize_t\fR \fBmbrlen_l\fR(\fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR, \fBmbstate_t *restrict\fR \fIps\fR,
+ \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-If \fIs\fR is not a null pointer, \fBmbrlen()\fR determines the number of
-bytes constituting the character pointed to by \fIs\fR. It is equivalent to:
-.sp
-.in +2
+If \fIs\fR is not a null pointer, \fBmbrlen()\fR and \fBmbrlen_l()\fR determine
+the number of bytes constituting the character pointed to by \fIs\fR.
+The call
.nf
+.IP
+\fBmbrlen\fR(\fIs\fR, \fIn\fR, \fIps\fR);
+.fi
+.LP
+is equivalent to:
+.nf
+.IP
mbstate_t internal;
-mbrtowc(NULL, s, n, ps != NULL ? ps : &internal);
+\fBmbrtowc\fR(NULL, \fIs\fR, \fIn\fR, \fIps\fR != NULL ? \fIps\fR : &internal);
.fi
-.in -2
-
-.sp
.LP
-If \fIps\fR is a null pointer, the \fBmbrlen()\fR function uses its own
+If \fIps\fR is a null pointer, the \fBmbrlen()\fR and \fBmbrlen_l()\fR
+functions use their own
internal \fBmbstate_t\fR object, which is initialized at program startup to the
initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to
by \fIps\fR is used to completely describe the current conversion state of the
-associated character sequence. Solaris will behave as if no function defined in
-the Solaris Reference Manual calls \fBmbrlen()\fR.
-.sp
+associated character sequence. The implemenation will behave as if no function
+defined in the Reference Manual calls \fBmbrlen()\fR.
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The behavior of \fBmbrlen()\fR is affected by the \fBLC_CTYPE\fR category of the
+current locale. See \fBenviron\fR(5). The behavior of \fBmbrlen_l()\fR does not
+use the current enivronment and instead uses the locale specified by \fBloc\fR.
.SH RETURN VALUES
-.sp
.LP
-The \fBmbrlen()\fR function returns the first of the following that applies:
+The \fBmbrlen()\fR and \fBmbrlen_l()\fR functions return the first of the
+following that applies:
.sp
.ne 2
.na
@@ -92,9 +103,8 @@ is stored in \fBerrno\fR and the conversion state is undefined.
.RE
.SH ERRORS
-.sp
.LP
-The \fBmbrlen()\fR function may fail if:
+The \fBmbrlen()\fR and \fBmbrlen_l()\fR functions may fail if:
.sp
.ne 2
.na
@@ -115,27 +125,29 @@ Invalid character sequence is detected.
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level See NOTES below
+MT-Level MT-Safe
.TE
+.LP
+The
+.B mbrlen()
+function is Standard. The
+.B mbrlen_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBmbrtowc\fR(3C), \fBmbsinit\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
+\fBmbrtowc\fR(3C), \fBmbsinit\fR(3C), \fBnewlocale\fR(3C),
+\fBsetlocale\fR(3C), \fBattributes\fR(5),
\fBenviron\fR(5), \fBstandards\fR(5)
.SH NOTES
.sp
@@ -143,6 +155,7 @@ MT-Level See NOTES below
If \fIps\fR is not a null pointer, \fBmbrlen()\fR uses the \fBmbstate_t\fR
object pointed to by \fIps\fR and the function can be used safely in
multithreaded applications, as long as \fBsetlocale\fR(3C) is not being called
-to change the locale. If \fIps\fR is a null pointer, \fBmbrlen()\fR uses its
-internal \fBmbstate_t\fR object and the function is Unsafe in multithreaded
-applications.
+to change the locale or a per-thread locale has been installed on the calling
+thread with \fBuselocale\fR(3C). If \fIps\fR is a null pointer, \fBmbrlen()\fR
+uses its internal \fBmbstate_t\fR object and the function is Unsafe in
+multithreaded applications.
diff --git a/usr/src/man/man3c/mbrtowc.3c b/usr/src/man/man3c/mbrtowc.3c
index 353d216616..55e053570e 100644
--- a/usr/src/man/man3c/mbrtowc.3c
+++ b/usr/src/man/man3c/mbrtowc.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBRTOWC 3C "Nov 1, 2003"
+.TH MBRTOWC 3C "Jun 23, 2014"
.SH NAME
-mbrtowc \- convert a character to a wide-character code (restartable)
+mbrtowc, mbrtowc_l \- convert a character to a wide-character code (restartable)
.SH SYNOPSIS
.LP
.nf
@@ -18,146 +19,177 @@ mbrtowc \- convert a character to a wide-character code (restartable)
\fBsize_t\fR \fBmbrtowc\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR,
\fBmbstate_t *restrict\fR \fIps\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBsize_t\fR \fBmbrtowc_l\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR,
+ \fBmbstate_t *restrict\fR \fIps\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-If \fIs\fR is a null pointer, the \fBmbrtowc()\fR function is equivalent to the
-call:
+If
+.I s
+is a null pointer, the
+.B mbrtowc()
+function is equivalent to the call:
.sp
.in +2
.nf
-mbrtowc(NULL, ``'', 1, ps)
+\fBmbrtowc\fR(NULL, "", 1, \fIps\fR)
.fi
.in -2
-
-.sp
.LP
-In this case, the values of the arguments \fIpwc\fR and \fIn\fR are ignored.
+Likewise, if
+.I s
+is a null pointer, the
+.B mbrtowc_l()
+function is equivalent to the call:
.sp
+.in +2
+.nf
+\fBmbrtowc_l\fR(NULL, "", 1, \fIps\fR, \fIloc\fR);
+.fi
+.in -2
+.LP
+In these cases, the values of the arguments
+.I pwc
+and
+.I n
+are ignored.
.LP
-If \fIs\fR is not a null pointer, the \fBmbrtowc()\fR function inspects at most
-\fIn\fR bytes beginning at the byte pointed to by \fIs\fR to determine the
-number of bytes needed to complete the next character (including any shift
-sequences). If the function determines that the next character is completed,
-it determines the value of the corresponding wide-character and then, if
-\fIpwc\fR is not a null pointer, stores that value in the object pointed to by
-\fIpwc\fR. If the corresponding wide-character is the null wide-character, the
+If
+.I s
+is not a null pointer, these functions inspect at most
+.I n
+bytes beginning at the byte pointed to by
+.I s
+to determine the number of bytes needed to complete the next character
+(including any shift sequences). If the functions determine that the next
+character is completed,
+they determine the value of the corresponding wide-character and then, if
+.I pwc
+is not a null pointer, stores that value in the object pointed to by
+.IR pwc .
+If the corresponding wide-character is the null wide-character, the
resulting state described is the initial conversion state.
-.sp
.LP
-If \fIps\fR is a null pointer, the \fBmbrtowc()\fR function uses its own
-internal \fBmbstate_t\fR object, which is initialized at program startup to the
-initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to
-by \fIps\fR is used to completely describe the current conversion state of the
-associated character sequence. Solaris will behave as if no function defined in
-the Solaris Reference Manual calls \fBmbrtowc()\fR.
-.sp
+If
+.I ps
+is a null pointer, these functions use their own
+internal
+.B mbstate_t
+object, which is initialized at program startup to the
+initial conversion state. Otherwise, the
+.B mbstate_t
+object pointed to by
+.I ps
+is used to completely describe the current conversion state of the
+associated character sequence. The system will behave as if no function defined
+in the Reference Manual calls
+.B mbrtowc()
+or
+.BR Bmbrtowc_l() .
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The behavior of
+.B mbrtowc()
+is affected by the
+.B LC_CTYPE
+category of the current locale. The
+.B mbrtowc_l()
+function is affected by the
+.B LC_CTYPE
+category of the specified
+.I loc
+locale object. See
+.B environ (5).
.SH RETURN VALUES
-.sp
.LP
-The \fBmbrtowc()\fR function returns the first of the following that applies:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 17n
-If the next \fIn\fR or fewer bytes complete the character that corresponds to
+The
+.B mbrtowc()
+and
+.B mbrtowc_l()
+functions return the first of the following that applies:
+.IP \fB0\fR
+If the next
+.I n
+or fewer bytes complete the character that corresponds to
the null wide-character (which is the value stored).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBpositive\fR\fR
-.ad
-.RS 17n
-If the next \fIn\fR or fewer bytes complete a valid character (which is the
+.IP \fBpositive\fR
+If the next
+.I n
+or fewer bytes complete a valid character (which is the
value stored); the value returned is the number of bytes that complete the
character.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB(size_t)\(mi2\fR\fR
-.ad
-.RS 17n
-If the next \fIn\fR bytes contribute to an incomplete but potentially valid
-character, and all \fIn\fR bytes have been processed (no value is stored).
-When \fIn\fR has at least the value of the \fBMB_CUR_MAX\fR macro, this case
-can only occur if \fIs\fR points at a sequence of redundant shift sequences
+.IP \fB(size_t)\(mi2\fR
+If the next
+.I n
+bytes contribute to an incomplete but potentially valid
+character, and all
+.I n
+bytes have been processed (no value is stored).
+When
+.I n
+has at least the value of the
+.B MB_CUR_MAX
+macro, this case can only occur if
+.I s
+points at a sequence of redundant shift sequences
(for implementations with state-dependent encodings).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB(size_t)\(mi1\fR\fR
-.ad
-.RS 17n
+.IP \fB(size_t)\(mi1\fR
If an encoding error occurs, in which case the next \fIn\fR or fewer bytes do
not contribute to a complete and valid character (no value is stored). In
-this case, \fBEILSEQ\fR is stored in \fBerrno\fR and the conversion state is
-undefined.
-.RE
-
+this case,
+.B EILSEQ
+is stored in
+.B errno
+and the conversion state is undefined.
.SH ERRORS
-.sp
.LP
-The \fBmbrtowc()\fR function may fail if:
-.sp
-.ne 2
-.na
-\fB\fBEINVAL\fR\fR
-.ad
-.RS 10n
-The \fIps\fR argument points to an object that contains an invalid conversion
+The
+.B mbrtowc()
+and
+.B mbrtowc_l()
+functions may fail if:
+.IP \fBEINVAL\fR
+The
+.I ps
+argument points to an object that contains an invalid conversion
state.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEILSEQ\fR\fR
-.ad
-.RS 10n
+.IP \fBEILSEQ\fR
Invalid character sequence is detected.
-.RE
-
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level See NOTES below
+MT-Level See below.
.TE
-.SH SEE ALSO
-.sp
.LP
-\fBmbsinit\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5),
-\fBstandards\fR(5)
-.SH NOTES
-.sp
+The
+.B mbrtowc()
+function is Standard. The
+.B mbrtowc_l()
+function is Uncommitted.
+.LP
+If
+.I ps
+is a null pointer, these functions are Unsafe for use in
+multithreaded applications. Otherwise they are MT-Safe.
+.SH SEE ALSO
.LP
-If \fIps\fR is not a null pointer, \fBmbrtowc()\fR uses the \fBmbstate_t\fR
-object pointed to by \fIps\fR and the function can be used safely in
-multithreaded applications, as long as \fBsetlocale\fR(3C) is not being called
-to change the locale. If \fIps\fR is a null pointer, \fBmbrtowc()\fR uses its
-internal \fBmbstate_t\fR object and the function is Unsafe in multithreaded
-applications.
+.BR mbsinit (3C),
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR attributes (5),
+.BR environ (5),
+.BR standards (5)
diff --git a/usr/src/man/man3c/mbsinit.3c b/usr/src/man/man3c/mbsinit.3c
index b4331cd866..66ebcd5c7a 100644
--- a/usr/src/man/man3c/mbsinit.3c
+++ b/usr/src/man/man3c/mbsinit.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBSINIT 3C "Jul 24, 2002"
+.TH MBSINIT 3C "Jun 23, 2014"
.SH NAME
-mbsinit \- determine conversion object status
+mbsinit,mbsinit_l \- determine conversion object status
.SH SYNOPSIS
.LP
.nf
@@ -17,20 +18,25 @@ mbsinit \- determine conversion object status
\fBint\fR \fBmbsinit\fR(\fBconst mbstate_t *\fR\fIps\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBint\fR \fBmbsinit_l\fR(\fBconst mbstate_t *\fR\fIps\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
If \fBps\fR is not a null pointer, the \fBmbsinit()\fR function determines
-whether the object pointed to by \fBps\fR describes an initial conversion
-state.
+whether the object pointed to by \fBps\fR describes an initial conversion state.
+.LP
+The function \fBmbsinit_l()\fR behaves identically to \fBmbsinit()\fR except the
+current locale is ignored and the locale \fIloc\fR is used instead.
.SH RETURN VALUES
-.sp
.LP
The \fBmbsinit()\fR function returns non-zero if \fBps\fR is a null pointer,
or if the pointed-to object describes an initial conversion state; otherwise,
it returns \fB0\fR.
-.sp
.LP
If an \fBmbstate_t\fR object is altered by any of the functions described as
"restartable", and is then used with a different character sequence, or in the
@@ -38,17 +44,14 @@ other conversion direction, or with a different \fBLC_CTYPE\fR category setting
than on earlier function calls, the behavior is undefined. See
\fBenviron\fR(5).
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH USAGE
-.sp
.LP
The \fBmbstate_t\fR object is used to describe the current conversion state
from a particular character sequence to a wide-character sequence (or vice
versa) under the rules of a particular setting of the \fBLC_CTYPE\fR category
of the current locale.
-.sp
.LP
The initial conversion state corresponds, for a conversion in either direction,
to the beginning of a new character sequence in the initial shift state. A
@@ -57,31 +60,28 @@ conversion state. A zero-valued \fBmbstate_t\fR object can be used to initiate
conversion involving any character sequence, in any \fBLC_CTYPE\fR category
setting.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The
+.B mbsinit()
+function is Standard. The
+.B mbsinit_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBmbrlen\fR(3C), \fBmbrtowc\fR(3C), \fBmbsrtowcs\fR(3C), \fBsetlocale\fR(3C),
-\fBwcrtomb\fR(3C), \fBwcsrtombs\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5),
+\fBmbrlen\fR(3C), \fBmbrtowc\fR(3C), \fBmbsrtowcs\fR(3C),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBwcrtomb\fR(3C), \fBwcsrtombs\fR(3C), \fBuselocale\fR(), \fBattributes\fR(5), \fBenviron\fR(5),
\fBstandards\fR(5)
-.SH NOTES
-.sp
-.LP
-The \fBmbsinit()\fR function can be used safely in multithreaded applications,
-as long as \fBsetlocale\fR(3C) is not being called to change the locale.
diff --git a/usr/src/man/man3c/mbsrtowcs.3c b/usr/src/man/man3c/mbsrtowcs.3c
index f23284f6de..b645fe4942 100644
--- a/usr/src/man/man3c/mbsrtowcs.3c
+++ b/usr/src/man/man3c/mbsrtowcs.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,27 +8,43 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBSRTOWCS 3C "Nov 1, 2003"
+.TH MBSRTOWCS 3C "Jun 28, 2014"
.SH NAME
-mbsrtowcs \- convert a character string to a wide-character string
-(restartable)
+mbsnrtwocs, mbsnrtowcs_l, mbsrtowcs, mbsrtowcs_l \- convert a character string
+to a wide-character string (restartable)
.SH SYNOPSIS
.LP
.nf
#include <wchar.h>
+\fBsize_t\fR \fBmbsnrtowcs\fR(\fBwchar_t *restrict\fR \fIdst\fR, \fBconst char **restrict\fR \fIsrc\fR,
+ \fBsize_t\fR \fInms\fR, \fBsize_t\fR \fIlen\fR, \fBmbstate_t *restrict\fR \fIps\fR);
+.fi
+.LP
+.nf
\fBsize_t\fR \fBmbsrtowcs\fR(\fBwchar_t *restrict\fR \fIdst\fR, \fBconst char **restrict\fR \fIsrc\fR,
\fBsize_t\fR \fIlen\fR, \fBmbstate_t *restrict\fR \fIps\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBsize_t\fR \fBmbsnrtowcs_l\fR(\fBwchar_t *restrict\fR \fIdst\fR, \fBconst char **restrict\fR \fIsrc\fR,
+ \fBsize_t\fR \fInms\fR, \fBsize_t\fR \fIlen\fR, \fBmbstate_t *restrict\fR \fIps\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBsize_t\fR \fBmbsrtowcs_l\fR(\fBwchar_t *restrict\fR \fIdst\fR, \fBconst char **restrict\fR \fIsrc\fR,
+ \fBsize_t\fR \fIlen\fR, \fBmbstate_t *restrict\fR \fIps\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
-The \fBmbsrtowcs()\fR function converts a sequence of characters, beginning in
+These function converts a sequence of characters, beginning in
the conversion state described by the object pointed to by \fIps\fR, from the
array indirectly pointed to by \fIsrc\fR into a sequence of corresponding
wide-characters. If \fIdst\fR is not a null pointer, the converted characters
-are stored into the array pointed to by \fIdst\fR. Conversion continues up to
+are stored into the array pointed to by \fIdst\fR. Conversion continues up to
and including a terminating null character, which is also stored. Conversion
stops early in either of the following cases:
.RS +4
@@ -43,10 +60,8 @@ When a sequence of bytes is encountered that does not form a valid character.
When \fIlen\fR codes have been stored into the array pointed to by \fIdst\fR
(and \fIdst\fR is not a null pointer).
.RE
-.sp
.LP
Each conversion takes place as if by a call to the \fBmbrtowc()\fR function.
-.sp
.LP
If \fIdst\fR is not a null pointer, the pointer object pointed to by \fIsrc\fR
is assigned either a null pointer (if conversion stopped due to reaching a
@@ -54,31 +69,35 @@ terminating null character) or the address just past the last character
converted (if any). If conversion stopped due to reaching a terminating null
character, and if \fIdst\fR is not a null pointer, the resulting state
described is the initial conversion state.
-.sp
.LP
-If \fIps\fR is a null pointer, the \fBmbsrtowcs()\fR function uses its own
+If \fIps\fR is a null pointer, these functions uses their own
internal \fBmbstate_t\fR object, which is initialized at program startup to the
-initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to by
+initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to by
\fIps\fR is used to completely describe the current conversion state of the
-associated character sequence. Solaris will behave as if no function defined in
-the Solaris Reference Manual calls \fBmbsrtowcs()\fR.
-.sp
+associated character sequence. The system will behave as if no function defined
+in the Reference Manual calls any of these functions.
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The function \fBmbsnrtowcs()\fR behaves identically to \fBmbsrtowcs()\fR,
+except the conversion stops after reading \fInms\fR bytes from the
+buffer pointed to by \fIsrc\fR.
+.LP
+The behavior of \fBmbnrtowcs()\fR and \fBmbsrtowcs()\fR functions are
+affected by the \fBLC_CTYPE\fR category of the
+current locale. See \fBenviron\fR(5). The functions \fBmbsrtowcs_l()\fR and
+\fBmbsnrtowcs_l()\fR behave identically to \fBmbsrtowcs()\fR and
+\fBmbsnrtowcs()\fR, except that instead of using the current locale, they use
+the locale specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
If the input conversion encounters a sequence of bytes that do not form a valid
-character, an encoding error occurs. In this case, the \fBmbsrtowcs()\fR
-function stores the value of the macro \fBEILSEQ\fR in \fBerrno\fR and returns
-\fB(size_t)\(mi1\fR; the conversion state is undefined. Otherwise, it returns
+character, an encoding error occurs. In this case, these
+functions store the value of the macro \fBEILSEQ\fR in \fBerrno\fR and return
+\fB(size_t)\(mi1\fR; the conversion state is undefined. Otherwise, they return
the number of characters successfully converted, not including the terminating
null (if any).
.SH ERRORS
-.sp
.LP
-The \fBmbsrtowcs()\fR function may fail if:
+Theses functions may fail if:
.sp
.ne 2
.na
@@ -97,36 +116,38 @@ state.
.RS 10n
Invalid character sequence is detected.
.RE
-
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level See NOTES below
+MT-Level See below.
.TE
-.SH SEE ALSO
-.sp
.LP
-\fBmbrtowc\fR(3C), \fBmbsinit\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
-\fBenviron\fR(5), \fBstandards\fR(5)
-.SH NOTES
-.sp
+The
+.B mbsnrtowcs()
+and
+.B mbsrtowcs()
+functions are Standard. The
+.B mbsnrtowcs_l()
+and
+.B mbsrtowcs_l()
+functions are Uncommitted.
.LP
-If \fIps\fR is not a null pointer, \fBmbsrtowcs()\fR uses the \fBmbstate_t\fR
-object pointed to by \fIps\fR and the function can be used safely in
-multithreaded applications, as long as \fBsetlocale\fR(3C) is not being called
-to change the locale. If \fIps\fR is a null pointer, \fBmbsrtowcs()\fR uses its
-internal \fBmbstate_t\fR object and the function is Unsafe in multithreaded
+If \fIps\fR is not a null pointer, these functions use the \fBmbstate_t\fR
+object pointed to by \fIps\fR and can be used safely in
+multithreaded applications, otherwise they use an
+internal \fBmbstate_t\fR object and are Unsafe in multithreaded
applications.
+.SH SEE ALSO
+.LP
+\fBmbrtowc\fR(3C), \fBmbsinit\fR(3C), \fBnewlocale\fR(3C),
+\fBsetlocale\fR(3C), \fBuselocale()\fR, \fBattributes\fR(5),
+\fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/mbtowc.3c b/usr/src/man/man3c/mbtowc.3c
index 8e2749e0af..c15c7de518 100644
--- a/usr/src/man/man3c/mbtowc.3c
+++ b/usr/src/man/man3c/mbtowc.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH MBTOWC 3C "Nov 1, 2003"
+.TH MBTOWC 3C "Jun 23, 2014"
.SH NAME
-mbtowc \- convert a character to a wide-character code
+mbtowc, mbtowc_l \- convert a character to a wide-character code
.SH SYNOPSIS
.LP
.nf
@@ -17,9 +18,15 @@ mbtowc \- convert a character to a wide-character code
\fBint\fR \fBmbtowc\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR);
.fi
+.LP
+.nf
+#include <stdlib.h>
+#include <xlocale.h>
+\fBint\fR \fBmbtowc_l\fR(\fBwchar_t *restrict\fR \fIpwc\fR, \fBconst char *restrict\fR \fIs\fR, \fBsize_t\fR \fIn\fR,
+ \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
If \fIs\fR is not a null pointer, \fBmbtowc()\fR determines the number of the
bytes that constitute the character pointed to by \fIs\fR. It then determines
@@ -28,28 +35,28 @@ that character. (The value of the wide-character code corresponding to the null
byte is 0.) If the character is valid and \fIpwc\fR is not a null pointer,
\fBmbtowc()\fR stores the wide-character code in the object pointed to by
\fIpwc\fR.
-.sp
.LP
A call with \fIs\fR as a null pointer causes this function to return \fB0\fR.
The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
current locale. At most \fIn\fR bytes of the array pointed to by \fIs\fR will
be examined.
+.LP
+The function \fBmbtowc_l()\fR behaves identically to \fBmbtowc()\fR, except
+instead of using the current locale, it uses the locale as specified by
+\fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-If \fIs\fR is a null pointer, \fBmbtowc()\fR returns \fB0\fR. If \fIs\fR is not
-a null pointer, \fBmbtowc()\fR returns \fB0\fR (if \fIs\fR points to the null
+If \fIs\fR is a null pointer, these functions return \fB0\fR. If \fIs\fR is not
+a null pointer, they return \fB0\fR (if \fIs\fR points to the null
byte), the number of bytes that constitute the converted character (if the next
\fIn\fR or fewer bytes form a valid character), or \fB\(mi1\fR and may set
\fBerrno\fR to indicate the error (if they do not form a valid character).
-.sp
.LP
In no case will the value returned be greater than \fIn\fR or the value of the
\fBMB_CUR_MAX\fR macro.
.SH ERRORS
-.sp
.LP
-The \fBmbtowc()\fR function may fail if:
+The \fBmbtowc()\fR and \fBmbtowc_l()\fR functions may fail if:
.sp
.ne 2
.na
@@ -58,34 +65,30 @@ The \fBmbtowc()\fR function may fail if:
.RS 10n
Invalid character sequence is detected.
.RE
-
-.SH USAGE
-.sp
-.LP
-The \fBmbtowc()\fR function can be used safely in multithreaded applications,
-as long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
-l | l
+c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The
+.B mbtowc()
+function is Standard. The
+.B mbtowc_l()
+function is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBmblen\fR(3C), \fBmbstowcs\fR(3C), \fBsetlocale\fR(3C), \fBwcstombs\fR(3C),
-\fBwctomb\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
+\fBmblen\fR(3C), \fBmbstowcs\fR(3C),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBwcstombs\fR(3C), \fBwctomb\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/newlocale.3c b/usr/src/man/man3c/newlocale.3c
new file mode 100644
index 0000000000..7fa9048211
--- /dev/null
+++ b/usr/src/man/man3c/newlocale.3c
@@ -0,0 +1,191 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2014 Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH NEWLOCALE 3C "Jun 23, 2014"
+.SH NAME
+duplocale, freelocale, newlocale \- create, duplicate, and destroy locale objects
+.SH SYNOPSIS
+.LP
+.nf
+#include <locale.h>
+
+\fBlocale_t\fR \fBnewlocale\fR(\fBint\fR \fIcategory_mask\fR, \fBconst char *\fR \fIlocale\fR,
+ \fBlocale_t\fR \fIbase\fR);
+.fi
+.LP
+.nf
+\fBlocale_t\fR \fBduplocale\fR(\fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBvoid\fR \fBfreelocale\fR(\fBlocale_t\fR \fIloc\fR);
+.fi
+.SH DESCRIPTION
+.LP
+These functions manipulate locale objects that can be used
+.BR uselocale (3C)
+and functions that take arguments of type
+.BR locale_t .
+.LP
+The function
+.B newlocale()
+can be used to create a new locale object. It can also be used to modify an
+existing locale object, the new locale object will be a replacement for the
+modified locale object. To create a new locale, the argument
+.I base
+should be passed the special argument
+.RB ( locale_t )0.
+This will use a copy of the current global locale as a starting point. To modify
+an existing locale object, it should be passed in as the argument
+.IR base .
+The new locale object is constructed by taking the categories specified in
+.I category_mask
+from the locale specified by the string
+.IR locale ,
+and filling in the remaining categories from the locale
+.IR base .
+When
+.B newlocale()
+returns, callers must no longer use
+.IR base
+and assume that
+.BR freelocale (3C)
+has been called on it. In addition to locales defined on the system, the
+following three locales may always be passed in as the string
+.IR locale :
+.TP
+"C"
+Specifies the traditional UNIX system behavior.
+.TP
+"POSIX"
+An alternate name fo the locale "C".
+.TP
+""
+Indicates that the locale should be processed based in the values in the
+environment. See
+.BR setlocale (3C)
+and
+.BR environ (5)
+for more information.
+.LP
+The value of
+.I category_mask
+is a bitwise-inclusive or of the following macros which correspond to categories
+as defined in
+.BR locale (5)
+and
+.BR environ (5):
+.TP
+.B LC_CTYPE_MASK
+Character classification and case conversion.
+.TP
+.B LC_NUMERIC_MASK
+Numeric formatting.
+.TP
+.B LC_TIME_MASK
+Date and time formatting.
+.TP
+.B LC_COLLATE_MASK
+Collation order.
+.TP
+.B LC_MONETARY_MASK
+Monetary formatting.
+.TP
+.B LC_MESSAGES_MASK
+Formats of informative and diagnostic messages and interactive responses.
+.TP
+.B LC_ALL_MASK
+Mask of all categories.
+.LP
+The function
+.B duplocale()
+duplicates the locale object specified by
+.IR loc .
+If the locale object passed is
+.BR LC_GLOBAL_LOCALE ,
+.B duplocale()
+creates a copy of the current global locale as defined through calls to
+.BR setlocale (3C).
+.LP
+The function
+.B freelocale()
+removes and releases all resources associated with the locale object
+.IR loc .
+Programs must not call
+.B freelocale()
+on
+.BR LC_GLOBAL_LOCALE .
+.SH RETURN VALUES
+.LP
+On success, the functions
+.B newlocale()
+and
+.B duplocale()
+return a new locale object that can be used with functions that take a
+.BR locale_t .
+Locale objects created this way should be freed with
+.BR freelocale() .
+On error, the functions
+.B newlocale()
+and
+.B duplocale()
+return
+.BR (locale_t) 0
+and
+.B errno
+is set to indicate the error. The
+.B freelocale()
+function does not set
+.B errno.
+.SH ERRORS
+.LP
+The
+.B newlocale()
+and
+.B duplocale()
+functions will fail if:
+.TP
+.B ENOMEM
+Insufficient memory was available to create the locale object or to load the
+requested locale data.
+.LP
+The
+.B newlocale()
+function will fail if:
+.TP
+.B EINVAL
+An unknown bit is specified in
+.IR category_mask .
+.TP
+.B ENOENT
+Locale data was not found for a category specified in
+.SH ATTRIBUTES
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Standard
+_
+MT-Level Safe
+.TE
+
+.SH SEE ALSO
+.BR locale (1),
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR environ (5),
+.BR locale (5)
diff --git a/usr/src/man/man3c/nl_langinfo.3c b/usr/src/man/man3c/nl_langinfo.3c
index b735a034df..d3ac6e961e 100644
--- a/usr/src/man/man3c/nl_langinfo.3c
+++ b/usr/src/man/man3c/nl_langinfo.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright 1989 AT&T Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved Portions Copyright (c) 1992, X/Open Company Limited All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH NL_LANGINFO 3C "Jul 24, 2002"
+.TH NL_LANGINFO 3C "Jun 24, 2014"
.SH NAME
-nl_langinfo \- language information
+nl_langinfo, nl_langinfo_l \- language information
.SH SYNOPSIS
.LP
.nf
@@ -17,43 +18,36 @@ nl_langinfo \- language information
\fBchar *\fR\fBnl_langinfo\fR(\fBnl_item\fR \fIitem\fR);
.fi
-
+.LP
+.nf
+\fBchar *\fR\fBnl_langinfo_l\fR(\fBnl_item\fR \fIitem\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBnl_langinfo()\fR function returns a pointer to a null-terminated string
containing information relevant to a particular language or cultural area
defined in the programs locale. The manifest constant names and values of
\fIitem\fR are defined by <\fBlanginfo.h\fR>. For example:
-.sp
-.LP
-\fBnl_langinfo (ABDAY_1);\fR
-.sp
+.IP
+\fBnl_langinfo\fR(\fBABDAY_1\fR);
.LP
would return a pointer to the string "\fBDim\fR" if the identified language was
French and a French locale was correctly installed; or "\fBSun\fR" if the
identified language was English.
+.LP
+The function \fBnl_langinfo_l()\fR behaves identically to \fBnl_langinfo()\fR,
+except instead of acting in the current locale, it instead acts in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-If \fBsetlocale\fR(3C) has not been called successfully, or if data for a
+If the locale has not been set or is invalid, or if data for a
supported language is either not available, or if \fIitem\fR is not defined
-therein, then \fBnl_langinfo()\fR returns a pointer to the corresponding string
-in the C locale. In all locales, \fBnl_langinfo()\fR returns a pointer to an
+therein, then these functions return a pointer to the corresponding string
+in the C locale. In all locales, they return a pointer to an
empty string if \fIitem\fR contains an invalid setting.
-.SH USAGE
-.sp
-.LP
-The \fBnl_langinfo()\fR function can be used safely in multithreaded
-applications, as long as \fBsetlocale\fR(3C) is not being called to change the
-locale.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -64,16 +58,15 @@ CSI Enabled
_
Interface Stability Standard
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBlanginfo.h\fR(3HEAD), \fBnl_types.h\fR(3HEAD),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBlanginfo.h\fR(3HEAD), \fBnl_types.h\fR(3HEAD),
\fBattributes\fR(5), \fBstandards\fR(5)
.SH WARNINGS
-.sp
.LP
The array pointed to by the return value should not be modified by the program.
-Subsequent calls to \fBnl_langinfo()\fR may overwrite the array.
+Subsequent calls to these functions may overwrite the array.
diff --git a/usr/src/man/man3c/strcoll.3c b/usr/src/man/man3c/strcoll.3c
index b79c41af17..d1a3de385b 100644
--- a/usr/src/man/man3c/strcoll.3c
+++ b/usr/src/man/man3c/strcoll.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 1989 AT&T
.\" Portions Copyright (c) 2001, the Institute of Electrical and Electronics Engineers, Inc. and The Open Group. All Rights Reserved.
@@ -9,9 +10,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STRCOLL 3C "Nov 1, 2003"
+.TH STRCOLL 3C "Jun 23, 2014"
.SH NAME
-strcoll \- string collation
+strcoll, strcoll_l \- string collation
.SH SYNOPSIS
.LP
.nf
@@ -19,40 +20,43 @@ strcoll \- string collation
\fBint\fR \fBstrcoll\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
+.LP
+.nf
+\fBint\fR \fBstrcoll_l\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
Both \fBstrcoll()\fR and \fBstrxfrm\fR(3C) provide for locale-specific string
sorting. \fBstrcoll()\fR is intended for applications in which the number of
comparisons per string is small. When strings are to be compared a number of
times, \fBstrxfrm\fR(3C) is a more appropriate function because the
transformation process occurs only once.
-.sp
+.LP
+The \fBstrcoll_l()\fR function behaves
+identically to \fBstrcoll()\fR, except instead of operating in the current
+locale, it operates in the locale specified by \fIloc\fR.
.LP
The \fBstrcoll()\fR function does not change the setting of \fBerrno\fR if
successful.
-.sp
.LP
Since no return value is reserved to indicate an error, an application wishing
to check for error situations should set \fBerrno\fR to 0, then call
\fBstrcoll()\fR, then check \fBerrno\fR.
.SH RETURN VALUES
-.sp
.LP
Upon successful completion, \fBstrcoll()\fR returns an integer greater than,
equal to, or less than zero in direct correlation to whether string \fIs1\fR is
greater than, equal to, or less than the string \fIs2\fR. The comparison is
-based on strings interpreted as appropriate to the program's locale for
+based on strings interpreted as appropriate to the locale
category \fBLC_COLLATE\fR (see \fBsetlocale\fR(3C)).
-.sp
.LP
On error, \fBstrcoll()\fR may set \fBerrno\fR, but no return value is reserved
to indicate an error.
.SH ERRORS
.sp
.LP
-The \fBstrcoll()\fR function may fail if:
+The \fBstrcoll()\fR and \fBstrcoll_l()\fR functions may fail if:
.sp
.ne 2
.na
@@ -62,25 +66,14 @@ The \fBstrcoll()\fR function may fail if:
The \fIs1\fR or \fIs2\fR arguments contain characters outside the domain of the
collating sequence.
.RE
-
.SH FILES
-.sp
-.ne 2
-.na
-\fB\fB/usr/lib/locale/\fIlocale\fR/\fIlocale\fR.so.*\fR\fR
-.ad
-.sp .6
-.RS 4n
-\fBLC_COLLATE\fR database for \fIlocale\fR
+.IP \fB/usr/lib/locale/\fR\fIlocale\fR\fB/LC_COLLATE/*\fR
+collation database for \fIlocale\fR
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -91,15 +84,12 @@ CSI Enabled
_
Interface Stability Standard
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.sp
-.LP
-The \fBstrcoll()\fR function can be used safely in multithreaded applications,
-as long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH SEE ALSO
.sp
.LP
-\fBlocaledef\fR(1), \fBsetlocale\fR(3C), \fBstring\fR(3C), \fBstrxfrm\fR(3C),
+\fBlocaledef\fR(1), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBstring\fR(3C),
+\fBstrxfrm\fR(3C), \fBuselocale\fR(3C),
\fBwsxfrm\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/strfmon.3c b/usr/src/man/man3c/strfmon.3c
new file mode 100644
index 0000000000..04eb03d384
--- /dev/null
+++ b/usr/src/man/man3c/strfmon.3c
@@ -0,0 +1,164 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH STRFMON 3C "Jun 23, 2014"
+.SH NAME
+strfmon, strfmon_l \- convert monetary values to string
+.SH SYNOPSIS
+.LP
+.nf
+#include <monetary.h>
+
+\fBssize_t\fR \fBstrfmon\fR(\fBchar *restrict\fR \fIs\fR, \fBsize_t\fR \fImaxsize\fR,
+ \fBconst char *restrict\fR \fIformat\fR, ...);
+.fi
+.LP
+.nf
+\fBssize_t\fR \fBstrfmon_l\fR(\fBchar *restrict\fR \fIs\fR, \fBsize_t\fR \fImaxsize\fR,
+ \fBlocale_t\fR \fIloc\fR, \fBconst char *restrict\fR \fIformat\fR, ...);
+.fi
+.SH DESCRIPTION
+These functions are used to format strings containing numeric quantities using
+rules that are specific to a given locale. For example, in the United States,
+currencies are formatted using the dollar sign
+.RB ( $ )
+and include two decimal digits (cents).
+.LP
+Each character from the
+.I format
+is copied to the output buffer supplied by
+.IR s .
+Furthermore, when a percent
+.RB ( % )
+character is encountered, this triggers an expansion, as follows:
+.LP
+Immediately following the
+.B %
+character there shall be zero or more flags, as indicated below:
+.TP
+.BI = f
+An equals sign followed by a character
+.I f
+is the numeric fill
+character, which must be a single byte. The default fill character is <space>.
+.TP
+.B ^
+The carat suppresses the use of grouping characters, even if the
+locale indicates their use.
+.TP
+.B +
+The plus sign indicates that positive and negative numbers should use the
+locale's positive and negative signs. This may not be used with the open
+parenthesis. This behavior is default.
+.TP
+.B (
+The open parenthesis indicates that negative numbers should be enclosed
+within parenthesis, and no special formatting should be applied to positive
+values. This may not be supplied with the plus sign flag.
+.TP
+.B !
+The exclamation point suppresses the output of any currency symbol.
+.TP
+.B -
+The dash specifies that numeric values should be left-justified
+within a field width, if a field width is specified.
+.LP
+Next there may appear an optional minimum field width, specified as a string of
+decimal digits, indicating a minimum width in bytes of this fields.
+.LP
+Next there may appear a left precision, as
+.RI # p ,
+indicating the maximum
+number of digits expected to appear left of the radix character. (If a numeric
+value does not require this many places, including grouping separators, then
+the numeric fill character is used to pad the value to this many places.)
+.LP
+Next there may appear a right precision, as
+.RI . p ,
+indicating the minimum
+number of digits to appear to to the right of the radix character. If the
+value of
+.I p
+is zero, then the radix character is also suppressed.
+.LP
+Finally there shall appear one of the following conversion specifier
+characters:
+.TP
+.B i
+The next available argument (assumed to be
+.BR double )
+is formatted, using
+the locale's international currency format. For example, in the United States,
+the output might look like "USD 1,234.56".
+.TP
+.B n
+The next available argument (assumed to be
+.BR double )
+is formatted, using
+the locale's national currency format. For example, in the United States, the
+output might look like "$1,234.56".
+.TP
+.B %
+A single percent character is emitted. In this case, the entire specifier
+shall be
+.BR %% .
+.LP
+Whereas the
+.B strfmon()
+function uses the current locale, the
+.B strfmon_l()
+function uses the supplied locale
+.IR loc .
+.SH RETURN VALUES
+.LP
+If the conversion was successfully performed, and the entire result (including
+the terminating null character) fits in
+.I maxsize
+bytes, then the number of
+bytes placed in the buffer (excluding the terminating null character) is
+returned.
+.LP
+If the result of expansion exceeds
+.I maxsize
+bytes, then the value \(mi1 is returned, and
+.I errno
+is set to
+.BR E2BIG .
+.SH NOTES
+The result of formatting a value that is not a rational number (e.g. +NaN) is
+unspecified.
+.SH ATTRIBUTES
+.LP
+See
+.BR attributes (5)
+for descriptions of the following attributes:
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+CSI Enabled
+_
+Interface Stability Standard
+_
+MT-Level MT-Safe
+.TE
+
+.SH SEE ALSO
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR locale (3HEAD),
+.BR attributes (5),
+.BR standards (5)
+
diff --git a/usr/src/man/man3c/strftime.3c b/usr/src/man/man3c/strftime.3c
index f2b8eff328..83e1fce77a 100644
--- a/usr/src/man/man3c/strftime.3c
+++ b/usr/src/man/man3c/strftime.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2014 Gary Mills
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 1989 AT&T
@@ -10,9 +11,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STRFTIME 3C "Jan 3, 2014"
+.TH STRFTIME 3C "Jun 24, 2014"
.SH NAME
-strftime, cftime, ascftime \- convert date and time to string
+strftime, strftime_l cftime, ascftime \- convert date and time to string
.SH SYNOPSIS
.LP
.nf
@@ -22,12 +23,16 @@ strftime, cftime, ascftime \- convert date and time to string
\fBconst char *restrict\fR \fIformat\fR,
\fBconst struct tm *restrict\fR \fItimeptr\fR);
.fi
-
+.LP
+.nf
+\fBsize_t\fR \fBstrftime_l\fR(\fBchar *restrict\fR \fIs\fR, \fBsize_t\fR \fImaxsize\fR,
+ \fBconst char *restrict\fR \fIformat\fR,
+ \fBconst struct tm *restrict\fR \fItimeptr\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.LP
.nf
\fBint\fR \fBcftime\fR(\fBchar *\fR\fIs\fR, \fBchar *\fR\fIformat\fR, \fBconst time_t *\fR\fIclock\fR);
.fi
-
.LP
.nf
\fBint\fR \fBascftime\fR(\fBchar *\fR\fIs\fR, \fBconst char *\fR\fIformat\fR,
@@ -37,7 +42,8 @@ strftime, cftime, ascftime \- convert date and time to string
.SH DESCRIPTION
.sp
.LP
-The \fBstrftime()\fR, \fBascftime()\fR, and \fBcftime()\fR functions place
+The \fBstrftime()\fR, \fBstrftime_l()\fR, \fBascftime()\fR, and \fBcftime()\fR
+functions place
bytes into the array pointed to by \fIs\fR as controlled by the string pointed
to by \fIformat\fR. The \fIformat\fR string consists of zero or more conversion
specifications and ordinary characters. A conversion specification consists of
@@ -46,8 +52,9 @@ characters that determine the conversion specification's behavior. All
ordinary characters (including the terminating null byte) are copied unchanged
into the array pointed to by \fIs\fR. If copying takes place between objects
that overlap, the behavior is undefined. For \fBstrftime()\fR, no more than
-\fImaxsize\fR bytes are placed into the array.
-.sp
+\fImaxsize\fR bytes are placed into the array. The \fBstrftime_l()\fR function
+behaves identically to \fBstrftime()\fR function, but instead of operating in
+the current locale, it operates in the locale specified by \fIloc\fR.
.LP
If \fIformat\fR is \fB(char *)0\fR, then the locale's default format is used.
For \fBstrftime()\fR the default format is the same as \fB%c\fR; for
@@ -55,7 +62,6 @@ For \fBstrftime()\fR the default format is the same as \fB%c\fR; for
\fBcftime()\fR and \fBascftime()\fR first try to use the value of the
environment variable \fBCFTIME\fR, and if that is undefined or empty, the
default format is used.
-.sp
.LP
Each conversion specification is replaced by appropriate characters as
described in the following list. The appropriate characters are determined by
@@ -465,12 +471,10 @@ Time zone name or abbreviation, or no bytes if no time zone information exists.
Locale's date and time representation as produced by \fBdate\fR(1).
.RE
-.sp
.LP
If a conversion specification does not correspond to any of the above or to any
of the modified conversion specifications listed below, the behavior is
undefined and \fB0\fR is returned.
-.sp
.LP
The difference between \fB%U\fR and \fB%W\fR (and also between modified
conversion specifications \fB%OU\fR and \fB%OW\fR) lies in which day is counted
@@ -479,7 +483,6 @@ with a Sunday for \fB%U\fR or a Monday for \fB%W\fR. Week number 0 contains
those days before the first Sunday or Monday in January for \fB%U\fR and
\fB%W\fR, respectively.
.SS "Modified Conversion Specifications"
-.sp
.LP
Some conversion specifications can be modified by the \fBE\fR and \fBO\fR
modifiers to indicate that an alternate format or specification should be used
@@ -681,20 +684,16 @@ the locale's alternate numeric symbols.
.RE
.SS "Selecting the Output Language"
-.sp
.LP
-By default, the output of \fBstrftime()\fR, \fBcftime()\fR, and
-\fBascftime()\fR appear in U.S. English. The user can request that the output
-of \fBstrftime()\fR, \fBcftime()\fR, or \fBascftime()\fR be in a specific
-language by setting the \fBLC_TIME\fR category using \fBsetlocale()\fR.
+These routines produce output that is formatted according to the \fBLC_TIME\fR
+locale category. They use either the current locale, or in the case of
+\fBstrftime_l()\fR, the locale supplied by \fIloc\fR.
.SS "Time Zone"
-.sp
.LP
Local time zone information is used as though \fBtzset\fR(3C) were called.
.SH RETURN VALUES
-.sp
.LP
-The \fBstrftime()\fR, \fBcftime()\fR, and \fBascftime()\fR functions return the
+These functions return the
number of characters placed into the array pointed to by \fIs\fR, not including
the terminating null character. If the total number of resulting characters
including the terminating null character is more than \fImaxsize\fR,
@@ -703,31 +702,20 @@ indeterminate.
.SH EXAMPLES
.LP
\fBExample 1 \fRAn example of the \fBstrftime()\fR function.
-.sp
.LP
The following example illustrates the use of \fBstrftime()\fR for the
\fBPOSIX\fR locale. It shows what the string in \fIstr\fR would look like if
the structure pointed to by \fItmptr\fR contains the values corresponding to
Thursday, August 28, 1986 at 12:44:36.
-
-.sp
-.in +2
.nf
-\fBstrftime (str, strsize, "%A %b %d %j", tmptr)\fR
+.IP
+\fBstrftime\fR(\fIstr\fR, \fIstrsize\fR, "%A %b %d %j", \fItmptr\fR);
.fi
-.in -2
-
-.sp
.LP
This results in \fIstr\fR containing "Thursday Aug 28 240".
-
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -736,24 +724,25 @@ ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Committed
+Interface Stability See below.
_
MT-Level MT-Safe
_
Standard See below.
.TE
-.sp
.LP
-For \fBstrftime()\fR, see \fBstandards\fR(5).
+The \fBstrftime()\fR and \fBstrftime_l()\fR functions are Standard.
+\fBcftime()\fR and \fBascftime()\fR functions are Committed.
+.LP
+For \fBstrftime()\fR and \fBstrftime_l()\fR, see \fBstandards\fR(5).
.SH SEE ALSO
-.sp
.LP
-\fBdate\fR(1), \fBctime\fR(3C), \fBmktime\fR(3C), \fBsetlocale\fR(3C),
-\fBstrptime\fR(3C), \fBtzset\fR(3C), \fBTIMEZONE\fR(4), \fBzoneinfo\fR(4),
+\fBdate\fR(1), \fBctime\fR(3C), \fBmktime\fR(3C),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBstrptime\fR(3C), \fBtzset\fR(3C),
+\fBuselocale\fR(3C), \fBTIMEZONE\fR(4), \fBzoneinfo\fR(4),
\fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5)
.SH NOTES
-.sp
.LP
The conversion specification for \fB%V\fR was changed in the Solaris 7 release.
This change was based on the public review draft of the ISO C9x standard at
@@ -761,24 +750,19 @@ that time. Previously, the specification stated that if the week containing 1
January had fewer than four days in the new year, it became week 53 of the
previous year. The ISO C9x standard committee subsequently recognized that that
specification had been incorrect.
-.sp
.LP
The conversion specifications for \fB%g\fR, \fB%G\fR, \fB%Eg\fR, \fB%EG\fR, and
\fB%Og\fR were added in the Solaris 7 release. This change was based on the
-public review draft of the ISO C9x standard at that time. These specifications
-are evolving. If the ISO C9x standard is finalized with a different
-conclusion, these specifications will change to conform to the ISO C9x standard
-decision.
-.sp
+public review draft of the ISO C9x standard at that time. The \fB%g\fR and
+\fB%G\fR specifications were adopted in the formal standard. The other two
+were not, and should not be used in portable applications.
.LP
The conversion specification for \fB%u\fR was changed in the Solaris 8 release.
This change was based on the XPG4 specification.
-.sp
.LP
If using the \fB%Z\fR specifier and \fBzoneinfo\fR timezones and if the input
date is outside the range 20:45:52 UTC, December 13, 1901 to 03:14:07 UTC,
January 19, 2038, the timezone name may not be correct.
-.sp
.LP
The conversion specification for \fB%+\fR was added in illumos.
It is not part of any standard, although it is available on a number
diff --git a/usr/src/man/man3c/string.3c b/usr/src/man/man3c/string.3c
index 9bc9e4f3bf..cd2dacbedf 100644
--- a/usr/src/man/man3c/string.3c
+++ b/usr/src/man/man3c/string.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 1989 AT&T
.\" Portions Copyright (c) 1994 Man-cgi 1.15, Panagiotis Christias (christia@softlab.ntua.gr)
@@ -11,9 +12,10 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STRING 3C "Jun 19, 2013"
+.TH STRING 3C "Jun 21, 2013"
.SH NAME
-string, strcasecmp, strncasecmp, strcat, strncat, strlcat, strchr, strrchr,
+string, strcasecmp, strcasecmp_l, strncasecmp, strncasecmp_l, strcat, strncat,
+strlcat, strchr, strrchr,
strcmp, strncmp, strcpy, strncpy, strlcpy, strcspn, strspn, strdup, strlen,
strnlen, strpbrk, strsep, strstr, strtok, strtok_r \- string operations
.SH SYNOPSIS
@@ -23,115 +25,101 @@ strnlen, strpbrk, strsep, strstr, strtok, strtok_r \- string operations
\fBint\fR \fBstrcasecmp\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
+.LP
+.nf
+\fBint\fR \fBstrcasecmp_l\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.LP
.nf
\fBint\fR \fBstrncasecmp\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR, \fBsize_t\fR \fIn\fR);
.fi
-
+.LP
+.nf
+\fBint\fR \fBstrncasecmp_l\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR, \fBsize_t\fR \fIn\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.LP
.nf
#include <string.h>
\fBchar *\fR\fBstrcat\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrncat\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR, \fBsize_t\fR \fIn\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrlcat\fR(\fBchar *\fR\fIdst\fR, \fBconst char *\fR\fIsrc\fR, \fBsize_t\fR \fIdstsize\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrchr\fR(\fBconst char *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrrchr\fR(\fBconst char *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBint\fR \fBstrcmp\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBint\fR \fBstrncmp\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR, \fBsize_t\fR \fIn\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrcpy\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrncpy\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR, \fBsize_t\fR \fIn\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrlcpy\fR(\fBchar *\fR\fIdst\fR, \fBconst char *\fR\fIsrc\fR, \fBsize_t\fR \fIdstsize\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrcspn\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrspn\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrdup\fR(\fBconst char *\fR\fIs1\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrlen\fR(\fBconst char *\fR\fIs\fR);
.fi
-
.LP
.nf
\fBsize_t\fR \fBstrnlen\fR(\fBconst char *\fR\fIs\fR, \fBsize_t\fR \fIn\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrpbrk\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrsep\fR(\fBchar **\fR\fIstringp\fR, \fBconst char *\fR\fIdelim\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrstr\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrtok\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR);
.fi
-
.LP
.nf
\fBchar *\fR\fBstrtok_r\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR,
\fBchar **restrict\fR \fIlasts\fR);
.fi
-
.SS "ISO C++"
.LP
.nf
@@ -139,46 +127,37 @@ strnlen, strpbrk, strsep, strstr, strtok, strtok_r \- string operations
\fBconst char *\fR\fBstrchr\fR(\fBconst char *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBconst char *\fR\fBstrpbrk\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBconst char *\fR\fBstrrchr\fR(\fBconst char *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBconst char *\fR\fBstrstr\fR(\fBconst char *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
#include <cstring>
\fBchar *std::\fR\fBstrchr\fR(\fBchar *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBchar *std::\fR\fBstrpbrk\fR(\fBchar *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.LP
.nf
\fBchar *std::\fR\fBstrrchr\fR(\fBchar *\fR\fIs\fR, \fBint\fR \fIc\fR);
.fi
-
.LP
.nf
\fBchar *std::\fR\fBstrstr\fR(\fBchar *\fR\fIs1\fR, \fBconst char *\fR\fIs2\fR);
.fi
-
.SH DESCRIPTION
-.sp
.LP
The arguments \fIs\fR, \fIs1\fR, and \fIs2\fR point to strings (arrays of
characters terminated by a null character). The \fBstrcat()\fR,
@@ -191,10 +170,27 @@ all alter their first argument. Additionally, the \fBstrcat()\fR and
.LP
The \fBstrcasecmp()\fR and \fBstrncasecmp()\fR functions are case-insensitive
versions of \fBstrcmp()\fR and \fBstrncmp()\fR respectively, described below.
-They assume the \fBASCII\fR character set and ignore differences in case when
-comparing lower and upper case characters.
+.LP
+The \fBstrcasecmp()\fR and \fBstrncasecmp()\fR functions compare two strings
+byte-by-byte, after
+converting each upper-case character to lower-case (as determined by the
+\fBLC_CTYPE\fR category of the current locale). Note that neither the contents
+pointed to by \fIs1\fR nor \fIs2\fR are modified.
+.LP
+The functions return an integer
+greater than, equal to, or less than 0, if the string pointed to by \fIs1\fR
+is greater than, equal to, or less than the string pointed to by \fIs2\fR
+respectively. The sign of a non-zero return value is determined by the sign of
+the difference between the values of the first pair of bytes that differ in the
+.LP
+The \fBstrncasecmp()\fR function examines at most \fIn\fR bytes from each
+string.
+.SS "\fBstrcasecmp_l()\fR, \fBstrncasecmp_l()\fR"
+.LP
+The \fBstrcasecmp_l()\fR and \fBstrncasecmp_l()\fR functions behave identically
+to \fBstrcasecmp()\fR and \fBstrncasecmp()\fR, except instead of operating in
+the current locale, they instead operate in the locale specified by \fIloc\fR.
.SS "\fBstrcat()\fR, \fBstrncat()\fR, \fBstrlcat()\fR"
-.sp
.LP
The \fBstrcat()\fR function appends a copy of string \fIs2\fR, including the
terminating null character, to the end of string \fIs1\fR. The \fBstrncat()\fR
@@ -203,7 +199,6 @@ null-terminated result. The initial character of \fIs2\fR overrides the null
character at the end of \fIs1\fR. If copying takes place between objects that
overlap, the behavior of \fBstrcat()\fR, \fBstrncat()\fR, and \fBstrlcat()\fR
is undefined.
-.sp
.LP
The \fBstrlcat()\fR function appends at most
(\fIdstsize\fR-\fBstrlen\fR(\fIdst\fR)-1) characters of \fIsrc\fR to \fIdst\fR
@@ -225,9 +220,7 @@ if (strlcat(dst, src, dstsize) >= dstsize)
return \(mi1;
.fi
.in -2
-
.SS "\fBstrchr()\fR, \fBstrrchr()\fR"
-.sp
.LP
The \fBstrchr()\fR function returns a pointer to the first occurrence of
\fIc\fR (converted to a \fBchar\fR) in string \fIs\fR, or a null pointer if
@@ -235,7 +228,6 @@ The \fBstrchr()\fR function returns a pointer to the first occurrence of
pointer to the last occurrence of \fIc\fR. The null character terminating a
string is considered to be part of the string.
.SS "\fBstrcmp()\fR, \fBstrncmp()\fR"
-.sp
.LP
The \fBstrcmp()\fR function compares two strings byte-by-byte, according to the
ordering of your machine's character set. The function returns an integer
@@ -247,7 +239,6 @@ strings being compared. The \fBstrncmp()\fR function makes the same comparison
but looks at a maximum of \fIn\fR bytes. Bytes following a null byte are not
compared.
.SS "\fBstrcpy()\fR, \fBstrncpy()\fR, \fBstrlcpy()\fR"
-.sp
.LP
The \fBstrcpy()\fR function copies string \fIs2\fR to \fIs1\fR, including the
terminating null character, stopping after the null character has been copied.
@@ -256,7 +247,6 @@ or adding null characters to \fIs1\fR if necessary. The result will not be
null-terminated if the length of \fIs2\fR is \fIn\fR or more. Each function
returns \fIs1\fR. If copying takes place between objects that overlap, the
behavior of \fBstrcpy()\fR, \fBstrncpy()\fR, and \fBstrlcpy()\fR is undefined.
-.sp
.LP
The \fBstrlcpy()\fR function copies at most \fIdstsize\fR\(mi1 characters
(\fIdstsize\fR being the size of the string buffer \fIdst\fR) from \fIsrc\fR
@@ -272,14 +262,12 @@ if (strlcpy(dst, src, dstsize) >= dstsize)
.in -2
.SS "\fBstrcspn()\fR, \fBstrspn()\fR"
-.sp
.LP
The \fBstrcspn()\fR function returns the length of the initial segment of
string \fIs1\fR that consists entirely of characters not from string \fIs2\fR.
The \fBstrspn()\fR function returns the length of the initial segment of string
\fIs1\fR that consists entirely of characters from string \fIs2\fR.
.SS "\fBstrdup()\fR"
-.sp
.LP
The \fBstrdup()\fR function returns a pointer to a new string that is a
duplicate of the string pointed to by \fIs1\fR. The returned pointer can be
@@ -289,23 +277,19 @@ returned and \fBerrno\fR may be set to \fBENOMEM\fR to indicate that the
storage space available is insufficient.
.SS "\fBstrlen()\fR, \fBstrnlen()\fR"
.sp
-.LP
The \fBstrlen()\fR function returns the number of bytes in \fIs\fR, not
including the terminating null character.
-.sp
.LP
The \fBstrnlen()\fR function returns the smaller of \fIn\fR or the number of
bytes in \fIs\fR, not including the terminating null character. The
\fBstrnlen()\fR function never examines more than \fIn\fR bytes of the string
pointed to by \fIs\fR.
.SS "\fBstrpbrk()\fR"
-.sp
.LP
The \fBstrpbrk()\fR function returns a pointer to the first occurrence in
string \fIs1\fR of any character from string \fIs2\fR, or a null pointer if no
character from \fIs2\fR exists in \fIs1\fR.
.SS "\fBstrsep()\fR"
-.sp
.LP
The \fBstrsep()\fR function locates, in the null-terminated string referenced
by *\fIstringp\fR, the first occurrence of any character in the string
@@ -313,16 +297,13 @@ by *\fIstringp\fR, the first occurrence of any character in the string
The location of the next character after the delimiter character (or
\fINULL\fR, if the end of the string was reached) is stored in *\fIstringp\fR.
The original value of *\fIstringp\fR is returned.
-.sp
.LP
An ``empty'' field (one caused by two adjacent delimiter characters) can be
detected by comparing the location referenced by the pointer returned by
\fBstrsep()\fR to `\e0'.
-.sp
.LP
If *\fIstringp\fR is initially \fINULL\fR, \fBstrsep()\fR returns \fINULL\fR.
.SS "\fBstrstr()\fR"
-.sp
.LP
The \fBstrstr()\fR function locates the first occurrence of the string \fIs2\fR
(excluding the terminating null character) in string \fIs1\fR and returns a
@@ -330,7 +311,6 @@ pointer to the located string, or a null pointer if the string is not found. If
\fIs2\fR points to a string with zero length (that is, the string \fB""\fR),
the function returns \fIs1\fR.
.SS "\fBstrtok()\fR"
-.sp
.LP
A sequence of calls to \fBstrtok()\fR breaks the string pointed to by \fIs1\fR
into a sequence of tokens, each of which is delimited by a byte from the string
@@ -338,14 +318,12 @@ pointed to by \fIs2\fR. The first call in the sequence has \fIs1\fR as its
first argument, and is followed by calls with a null pointer as their first
argument. The separator string pointed to by \fIs2\fR can be different from
call to call.
-.sp
.LP
The first call in the sequence searches the string pointed to by \fIs1\fR for
the first byte that is not contained in the current separator string pointed to
by \fIs2\fR. If no such byte is found, then there are no tokens in the string
pointed to by \fIs1\fR and \fBstrtok()\fR returns a null pointer. If such a
byte is found, it is the start of the first token.
-.sp
.LP
The \fBstrtok()\fR function then searches from there for a byte that is
contained in the current separator string. If no such byte is found, the
@@ -354,23 +332,19 @@ subsequent searches for a token return a null pointer. If such a byte is found,
it is overwritten by a null byte that terminates the current token. The
\fBstrtok()\fR function saves a pointer to the following byte in
thread-specific data, from which the next search for a token starts.
-.sp
.LP
Each subsequent call, with a null pointer as the value of the first argument,
starts searching from the saved pointer and behaves as described above.
-.sp
.LP
See Example 1, 2, and 3 in the \fBEXAMPLES\fR section for examples of
\fBstrtok()\fR usage and the explanation in \fBNOTES\fR.
.SS "\fBstrtok_r()\fR"
-.sp
.LP
The \fBstrtok_r()\fR function considers the null-terminated string \fIs1\fR as
a sequence of zero or more text tokens separated by spans of one or more
characters from the separator string \fIs2\fR. The argument \fIlasts\fR points
to a user-provided pointer which points to stored information necessary for
\fBstrtok_r()\fR to continue scanning the same string.
-.sp
.LP
In the first call to \fBstrtok_r()\fR, \fIs1\fR points to a null-terminated
string, \fIs2\fR to a null-terminated string of separator characters, and the
@@ -378,21 +352,18 @@ value pointed to by \fIlasts\fR is ignored. The \fBstrtok_r()\fR function
returns a pointer to the first character of the first token, writes a null
character into \fIs1\fR immediately following the returned token, and updates
the pointer to which \fIlasts\fR points.
-.sp
.LP
In subsequent calls, \fIs1\fR is a null pointer and \fIlasts\fR is unchanged
from the previous call so that subsequent calls move through the string
\fIs1\fR, returning successive tokens until no tokens remain. The separator
string \fIs2\fR can be different from call to call. When no token remains in
\fIs1\fR, a null pointer is returned.
-.sp
.LP
See Example 3 in the \fBEXAMPLES\fR section for an example of \fBstrtok_r()\fR
usage and the explanation in \fBNOTES\fR.
.SH EXAMPLES
.LP
\fBExample 1 \fRSearch for word separators.
-.sp
.LP
The following example searches for tokens separated by space characters.
@@ -415,7 +386,6 @@ token = strtok(NULL, search);
.LP
\fBExample 2 \fRBreak a Line.
-.sp
.LP
The following example uses strtok to break a line into two character strings
separated by any combination of SPACEs, TABs, or NEWLINEs.
@@ -440,7 +410,6 @@ data = strtok(NULL, " \en");
.LP
\fBExample 3 \fRSearch for tokens.
-.sp
.LP
The following example uses both \fBstrtok()\fR and \fBstrtok_r()\fR to search
for tokens separated by one or more characters from the string pointed to by
@@ -479,7 +448,6 @@ main() {
.fi
.in -2
-.sp
.LP
When compiled and run, this example produces the following output:
@@ -499,61 +467,55 @@ token = "45"
.in -2
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Committed
+Interface Stability See below.
_
MT-Level See below.
_
Standard See below.
.TE
-.sp
+.LP
+The
+\fBstrlcat()\fR, \fBstrlcpy()\fR, and \fBstrsep()\fR functions are Committed.
+All the rest are Standard.
.LP
The \fBstrtok()\fR and \fBstrdup()\fR functions are MT-Safe. The remaining
functions are Async-Signal-Safe.
-.sp
.LP
For all except \fBstrlcat()\fR, \fBstrlcpy()\fR, and \fBstrsep()\fR, see
\fBstandards\fR(5).
.SH SEE ALSO
-.sp
.LP
-\fBmalloc\fR(3C), \fBsetlocale\fR(3C), \fBstrxfrm\fR(3C), \fBattributes\fR(5),
-\fBstandards\fR(5)
+\fBmalloc\fR(3C),
+\fBnewlocale(3C), \fBsetlocale\fR(3C), \fBstrxfrm\fR(3C), \fBuselocale\fR(3C),
+\fBattributes\fR(5), \fBstandards\fR(5)
.SH NOTES
-.sp
.LP
When compiling multithreaded applications, the \fB_REENTRANT\fR flag must be
defined on the compile line. This flag should only be used in multithreaded
applications.
-.sp
.LP
A single-threaded application can gain access to \fBstrtok_r()\fR only by
defining \fB__EXTENSIONS__\fR or by defining \fB_POSIX_C_SOURCE\fR to a value
greater than or equal to 199506L.
-.sp
.LP
-All of these functions assume the default locale ``C.'' For some locales,
+Except where noted otherwise, all of these functions assume the default
+locale ``C.'' For some locales,
\fBstrxfrm\fR(3C) should be applied to the strings before they are passed to
the functions.
-.sp
.LP
The \fBstrtok()\fR function is safe to use in multithreaded applications
because it saves its internal state in a thread-specific data area. However,
its use is discouraged, even for single-threaded applications. The
\fBstrtok_r()\fR function should be used instead.
-.sp
.LP
Do not pass the address of a character string literal as the argument \fIs1\fR
to either \fBstrtok()\fR or \fBstrtok_r()\fR. Similarly, do not pass a pointer
diff --git a/usr/src/man/man3c/strptime.3c b/usr/src/man/man3c/strptime.3c
index e9c77c9d1f..64a8a43a94 100644
--- a/usr/src/man/man3c/strptime.3c
+++ b/usr/src/man/man3c/strptime.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved.
.\" Portions Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
@@ -8,9 +9,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STRPTIME 3C "Aug 27, 2007"
+.TH STRPTIME 3C "Jun 27, 2014"
.SH NAME
-strptime \- date and time conversion
+strptime, strptime_l \- date and time conversion
.SH SYNOPSIS
.LP
.nf
@@ -19,7 +20,15 @@ strptime \- date and time conversion
\fBchar *\fR\fBstrptime\fR(\fBconst char *restrict\fR \fIbuf\fR,
\fBconst char *restrict\fR \fIformat\fR, \fBstruct tm *restrict\fR \fItm\fR);
.fi
+.LP
+.nf
+#include <time.h>
+#include <xlocale.h>
+\fBchar *\fR\fBstrptime_l\fR(\fBconst char *restrict\fR \fIbuf\fR,
+ \fBconst char *restrict\fR \fIformat\fR, \fBstruct tm *restrict\fR \fItm\fR,
+ \fBlocale_t\fR \fIloc\fR);
+.fi
.SS "Non-zeroing Behavior"
.LP
.nf
@@ -31,12 +40,12 @@ strptime \- date and time conversion
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBstrptime()\fR function converts the character string pointed to by
\fIbuf\fR to values which are stored in the \fBtm\fR structure pointed to by
-\fItm\fR, using the format specified by \fIformat\fR.
-.sp
+\fItm\fR, using the format specified by \fIformat\fR. The \fBstrptime_l()\fR
+function is identical to \fBstrptime()\fR except instead of acting in the
+current locale, it acts in the locale specified by the argument \fIloc\fR.
.LP
The \fIformat\fR argument is composed of zero or more conversion
specifications. Each conversion specification is composed of a "%" (percent)
@@ -45,12 +54,10 @@ replacement required. One or more white space characters (as specified by
\fBisspace\fR(3C)) may precede or follow a conversion specification. There must
be white-space or other non-alphanumeric characters between any two conversion
specifications.
-.sp
.LP
A non-zeroing version of \fBstrptime()\fR, described below under \fBNon-zeroing
Behavior\fR, is provided if \fB_STRPTIME_DONTZERO\fR is defined.
.SS "Conversion Specifications"
-.sp
.LP
The following conversion specifications are supported:
.sp
@@ -360,7 +367,6 @@ Time zone name or no characters if no time zone exists.
.RE
.SS "Modified Conversion Specifications"
-.sp
.LP
Some conversion specifications can be modified by the \fBE\fR and \fBO\fR
modifier characters to indicate that an alternate format or specification
@@ -525,7 +531,6 @@ the locale's alternate numeric symbols.
.RE
.SS "General Specifications"
-.sp
.LP
A conversion specification that is an ordinary character is executed by
scanning the next character from the buffer. If the character scanned from the
@@ -537,7 +542,6 @@ A series of specifications composed of \fB%n\fR, \fB%t\fR, white-space
characters or any combination is executed by scanning up to the first character
that is not white space (which remains unscanned), or until no more characters
can be scanned. White space is defined by \fBisspace\fR(3C).
-.sp
.LP
Any other conversion specification is executed by scanning characters until a
character matching the next specification is scanned, or until no more
@@ -554,7 +558,6 @@ consist of any combination of upper and lower case letters. The user can
request that the input date or time specification be in a specific language by
setting the \fBLC_TIME\fR category using \fBsetlocale\fR(3C).
.SS "Non-zeroing Behavior"
-.sp
.LP
In addition to the behavior described above by various standards, the Solaris
implementation of \fBstrptime()\fR provides the following extensions. These may
@@ -577,7 +580,6 @@ If \fB_STRPTIME_DONTZERO\fR is defined, \fBstrptime()\fR does not zero the
will use some values in the input \fBtm struct\fR to recalculate the date and
re-assign the appropriate members of the \fBtm struct\fR.
.RE
-.sp
.LP
The following describes extended features regardless of whether
\fB_STRPTIME_DONTZERO\fR is defined or not defined:
@@ -597,7 +599,6 @@ If \fB%U\fR or \fB%W\fR is specified and if weekday and year are given and
month and day of month are not given, \fBstrptime()\fR calculates and sets
\fBtm_mon\fR, \fBtm_mday\fR, \fBtm_wday\fR, and \fBtm_year\fR.
.RE
-.sp
.LP
The following describes extended features when \fB_STRPTIME_DONTZERO\fR is not
defined:
@@ -608,7 +609,6 @@ defined:
If \fB%C\fR is specified and \fB%y\fR is not specified, \fBstrptime()\fRassumes
0 as the year offset, then calculates the year, and assigns \fBtm_year\fR.
.RE
-.sp
.LP
The following describes extended features when \fB_STRPTIME_DONTZERO\fR is
defined:
@@ -654,17 +654,14 @@ input is p.m. and the input \fBtm_hour\fR value is between 0 - 11,
\fBstrptime()\fR will subtract 12 hours and update \fBtm_hour\fR.
.RE
.SH RETURN VALUES
-.sp
.LP
Upon successful completion, \fBstrptime()\fR returns a pointer to the character
following the last character parsed. Otherwise, a null pointer is returned.
.SH USAGE
-.sp
.LP
Several "same as" formats, and the special processing of white-space characters
are provided in order to ease the use of identical \fIformat\fR strings for
\fBstrftime\fR(3C) and \fBstrptime()\fR.
-.sp
.LP
The \fBstrptime()\fR function tries to calculate \fBtm_year\fR, \fBtm_mon\fR,
and \fBtm_mday\fR when given incomplete input. This allows the \fBstruct tm\fR
@@ -675,12 +672,8 @@ created by \fBstrptime()\fR to be passed to \fBmktime\fR(3C) to produce a
in \fBtm_yday\fR when \fB%j\fR is specified without otherwise specifying a
month and day within month.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -689,16 +682,20 @@ ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Committed
+Interface Stability See below.
_
MT-Level MT-Safe
_
-Standard See \fBstandards\fR(5).
+Standard See \fBstandards\fR(5) for \fBstrptime()\fR.
.TE
+.LP
+The \fBstrptime()\fR function is Standard. The \fBstrptime_l()\fR function
+is Uncommitted.
.SH SEE ALSO
-.sp
.LP
\fBctime\fR(3C), \fBgetdate\fR(3C), \fBisspace\fR(3C), \fBmktime\fR(3C),
-\fBsetlocale\fR(3C), \fBstrftime\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5),
+\fBnewlocale\fR(3C),
+\fBsetlocale\fR(3C), \fBstrftime\fR(3C), \fBuselocale\fR(3C),
+\fBattributes\fR(5), \fBenviron\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/strxfrm.3c b/usr/src/man/man3c/strxfrm.3c
index 3a1cc8da90..3781a9164f 100644
--- a/usr/src/man/man3c/strxfrm.3c
+++ b/usr/src/man/man3c/strxfrm.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright 1989 AT&T. Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved. Portions Copyright (c) 1992, X/Open Company Limited. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STRXFRM 3C "Dec 10, 2003"
+.TH STRXFRM 3C "Jun 21, 2014"
.SH NAME
-strxfrm \- string transformation
+strxfrm, strxfrm_l \- string transformation
.SH SYNOPSIS
.LP
.nf
@@ -17,9 +18,12 @@ strxfrm \- string transformation
\fBsize_t\fR \fBstrxfrm\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR, \fBsize_t\fR \fIn\fR);
.fi
-
+.LP
+.nf
+\fBsize_t\fR \fBstrxfrm_l\fR(\fBchar *restrict\fR \fIs1\fR, \fBconst char *restrict\fR \fIs2\fR, \fBsize_t\fR \fIn\fR,
+ \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBstrxfrm()\fR function transforms the string pointed to by \fIs2\fR and
places the resulting string into the array pointed to by \fIs1\fR. The
@@ -30,33 +34,31 @@ original strings. No more than \fIn\fR bytes are placed into the resulting
array pointed to by \fIs1\fR, including the terminating null byte. If \fIn\fR
is \fB0\fR, \fIs1\fR is permitted to be a null pointer. If copying takes place
between objects that overlap, the behavior is undefined.
-.sp
.LP
The \fBstrxfrm()\fR function does not change the setting of \fBerrno\fR if
successful.
-.sp
.LP
Since no return value is reserved to indicate an error, an application wishing
to check for error situations should set \fBerrno\fR to 0, then call
\fBstrxfrm()\fR, then check \fBerrno\fR.
+.LP
+The \fBstrxfrm_l()\fR functions behaves identically to the function
+\fBstrxfrm()\fR, except instead of operating in the current locale it
+operates in the locale specified by the argument \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
Upon successful completion, \fBstrxfrm()\fR returns the length of the
transformed string (not including the terminating null byte). If the value
returned is \fIn\fR or more, the contents of the array pointed to by \fIs1\fR
are indeterminate.
-.sp
.LP
On error, \fBstrxfrm()\fR may set \fBerrno\fR but no return value is reserved
to indicate the error.
.SH USAGE
-.sp
.LP
The transformation function is such that two transformed strings can be ordered
by \fBstrcmp\fR(3C) as appropriate to collating sequence information in the
-program's locale (category \fBLC_COLLATE\fR).
-.sp
+locale (category \fBLC_COLLATE\fR).
.LP
The fact that when \fIn\fR is \fB0\fR, \fIs1\fR is permitted to be a null
pointer, is useful to determine the size of the \fIs1\fR array prior to making
@@ -64,7 +66,6 @@ the transformation.
.SH EXAMPLES
.LP
\fBExample 1 \fRA sample of using the \fBstrxfm()\fR function.
-.sp
.LP
The value of the following expression is the size of the array needed to hold
the transformation of the string pointed to by \fIs\fR.
@@ -77,23 +78,11 @@ the transformation of the string pointed to by \fIs\fR.
.in -2
.SH FILES
-.sp
-.ne 2
-.na
-\fB\fB/usr/lib/locale/\fIlocale\fR/\fIlocale\fR.so.*\fR\fR
-.ad
-.sp .6
-.RS 4n
-\fBLC_COLLATE\fR database for \fIlocale\fR
-.RE
-
+.IP \fB/usr/lib/locale/\fR\fIlocale\fR\fB/LC_COLLATE/*
+collation database for \fIlocale\fR
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -104,15 +93,11 @@ CSI Enabled
_
Interface Stability Standard
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.sp
-.LP
-The \fBstrxfrm()\fR function can be used safely in a multithreaded application,
-as long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH SEE ALSO
-.sp
.LP
-\fBlocaledef\fR(1), \fBsetlocale\fR(3C), \fBstrcmp\fR(3C), \fBstrcoll\fR(3C),
+\fBlocaledef\fR(1), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBstrcmp\fR(3C),
+\fBstrcoll\fR(3C), \fBuselocale\fR(3C),
\fBwscoll\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/tolower.3c b/usr/src/man/man3c/tolower.3c
index 727e6f3ebd..2a06d7bbfa 100644
--- a/usr/src/man/man3c/tolower.3c
+++ b/usr/src/man/man3c/tolower.3c
@@ -1,11 +1,12 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH TOLOWER 3C "Aug 14, 2002"
+.TH TOLOWER 3C "Jun 21, 2014"
.SH NAME
-tolower \- transliterate upper-case characters to lower-case
+tolower, tolower_l \- transliterate upper-case characters to lower-case
.SH SYNOPSIS
.LP
.nf
@@ -13,35 +14,36 @@ tolower \- transliterate upper-case characters to lower-case
\fBint\fR \fBtolower\fR(\fBint\fR \fIc\fR);
.fi
+.LP
+.nf
+\fBint\fR \fBtolower_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBtolower()\fR function has as a domain a type \fBint\fR, the value of
which is representable as an \fBunsigned char\fR or the value of \fBEOF\fR. If
the argument has any other value, the argument is returned unchanged. If the
argument of \fBtolower()\fR represents an upper-case letter, and there exists a
corresponding lower-case letter (as defined by character type information in
-the program locale category \fB\fR\fBLC_CTYPE\fR\fB), \fR the result is the
+the locale category \fB\fR\fBLC_CTYPE\fR\fB), \fR the result is the
corresponding lower-case letter. All other arguments in the domain are returned
unchanged.
+.LP
+The function \fBtolower_l()\fR behaves identically to \fBtolower()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
On successful completion, \fBtolower()\fR returns the lower-case letter
corresponding to the argument passed. Otherwise, it returns the argument
unchanged.
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -56,7 +58,6 @@ MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fB_tolower\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
-\fBstandards\fR(5)
+\fB_tolower\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBuselocale\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/toupper.3c b/usr/src/man/man3c/toupper.3c
index 99c782cd6d..3885d28925 100644
--- a/usr/src/man/man3c/toupper.3c
+++ b/usr/src/man/man3c/toupper.3c
@@ -1,11 +1,12 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH TOUPPER 3C "Aug 14, 2002"
+.TH TOUPPER 3C "Jun 21, 2014"
.SH NAME
-toupper \- transliterate lower-case characters to upper-case
+toupper, toupper_l \- transliterate lower-case characters to upper-case
.SH SYNOPSIS
.LP
.nf
@@ -13,33 +14,34 @@ toupper \- transliterate lower-case characters to upper-case
\fBint\fR \fBtoupper\fR(\fBint\fR \fIc\fR);
.fi
+.LP
+.nf
+\fBint\fR \fBtoupper_l\fR(\fBint\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBtoupper()\fR function has as a domain a type \fBint\fR, the value of
which is representable as an \fBunsigned char\fR or the value of \fBEOF\fR. If
the argument has any other value, the argument is returned unchanged. If the
argument of \fBtoupper()\fR represents a lower-case letter, and there exists a
corresponding upper-case letter (as defined by character type information in
-the program locale category \fBLC_CTYPE\fR), the result is the corresponding
+the locale category \fBLC_CTYPE\fR), the result is the corresponding
upper-case letter. All other arguments in the domain are returned unchanged.
+.LP
+The function \fBtoupper_l()\fR behaves identically to \fBtoupper()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
On successful completion, \fBtoupper()\fR returns the upper-case letter
corresponding to the argument passed.
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -54,7 +56,7 @@ MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fB_toupper\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
-\fBstandards\fR(5)
+\fB_toupper\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBuselocale\fR(3C),
+\fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/towlower.3c b/usr/src/man/man3c/towlower.3c
new file mode 100644
index 0000000000..e0024720b4
--- /dev/null
+++ b/usr/src/man/man3c/towlower.3c
@@ -0,0 +1,75 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2014 Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH TOWLOWER 3C "Jun 21, 2014"
+.SH NAME
+towlower, towlower_l \- transliterate upper-case wide characters to lower-case
+.SH SYNOPSIS
+.LP
+.nf
+#include <wctype.h>
+
+\fBwint_t\fR \fBtowlower\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBwint_t\fR \fBtowlower_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.nf
+.SH DESCRIPTION
+The function
+.BR towlower()
+is the wide character equivalent of the function
+.BR tolower (3C).
+It converts the upper-case wide character
+.I wc
+to the equivalent lower-case
+wide character, if one exists. If one does not exist, it returns
+.I wc
+unchanged.
+.LP
+The function
+.B towlower_l()
+is equivalent to the function
+.BR towlower() ,
+but instead of operating in the current locale, operates in the
+locale specified by
+.IR loc .
+.SH RETURN VALUES
+On successful completion,
+.B towlower()
+and
+.B towlower_l()
+return the lower-case character that corresponds to the argument passed.
+Otherwise, they return the argument unchanged.
+.SH ERRORS
+No errors are defined.
+.SH ATTRIBUTES
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Standard
+_
+MT-Level MT-Safe
+.TE
+
+.SH SEE ALSO
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR towupper (3C),
+.BR uselocale (3C),
+.BR locale (5)
diff --git a/usr/src/man/man3c/towupper.3c b/usr/src/man/man3c/towupper.3c
new file mode 100644
index 0000000000..c8c86eef72
--- /dev/null
+++ b/usr/src/man/man3c/towupper.3c
@@ -0,0 +1,75 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2014 Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH TOWUPPER 3C "Jun 21, 2014"
+.SH NAME
+towupper, towupper_l \- transliterate lower-case wide characters to upper-case
+.SH SYNOPSIS
+.LP
+.nf
+#include <wctype.h>
+
+\fBwint_t\fR \fBtowupper\fR(\fBwint_t\fR \fIwc\fR);
+.fi
+.LP
+.nf
+\fBwint_t\fR \fBtowupper_l\fR(\fBwint_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.SH DESCRIPTION
+The function
+.BR towupper()
+is the wide character equivalent of the function
+.BR toupper (3C).
+It converts the lower-case wide character
+.I wc
+to the equivalent upper-case
+wide character, if one exists. If one does not exist, it returns
+.I wc
+unchanged.
+.LP
+The function
+.B towupper_l()
+is equivalent to the function
+.BR towupper() ,
+but instead of operating in the current locale, operates in the
+locale specified by
+.IR loc .
+.SH RETURN VALUES
+On successful completion,
+.B towupper()
+and
+.B towupper_l()
+return the upper-case character that corresponds to the argument passed.
+Otherwise, they return the argument unchanged.
+.SH ERRORS
+No errors are defined.
+.SH ATTRIBUTES
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Standard
+_
+MT-Level MT-Safe
+.TE
+
+.SH SEE ALSO
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR toupper(3C),
+.BR uselocale (3C),
+.BR locale (5)
diff --git a/usr/src/man/man3c/uselocale.3c b/usr/src/man/man3c/uselocale.3c
new file mode 100644
index 0000000000..ca2d034c6e
--- /dev/null
+++ b/usr/src/man/man3c/uselocale.3c
@@ -0,0 +1,95 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2014 Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH USELOCALE 3C "Jun 24, 2014"
+
+.SH NAME
+uselocale \- get and set the locale for an individual thread
+.SH SYNOPSIS
+.LP
+.nf
+#include <locale.h>
+
+\fBlocale_t\fR \fBuselocale\fR(\fBlocale_t\fR \fIloc\fR);
+.fi
+.SH DESCRIPTION
+.LP
+The
+.B uselocale()
+function is used to obtain and set the current locale for a thread. When
+a thread is created, it uses the global locale as specified by calls to
+.BR setlocale() .
+.LP
+If
+.BR (locale_t) 0
+is supplied for
+.IR loc ,
+then no change is made to the thread's locale setting. This can be used
+to query the thread's locale without making any change.
+.LP
+If
+.B LC_GLOBAL_LOCALE
+is supplied for
+.IR loc ,
+then the thread will use the global locale, undoing the effect of any
+prior call to establish a thread-specific locale.
+.LP
+Otherwise the thread will use the supplied
+.I loc
+locale object as a thread-specific locale. Changes to the global
+locale, or to the locale of any other thread, will not affect this thread.
+.LP
+Locale objects for use with
+.B uselocale()
+can be created with the functions
+.BR duplocale (3C)
+and
+.BR newlocale (3C).
+.SH RETURN VALUES
+Upon successful completion, the
+.B uselocale()
+function always returns the previous locale that was set. If no locale
+was previously set, the global locale,
+.BR LC_GLOBAL_LOCALE ,
+is returned. On failure, the
+.B uselocale()
+function returns
+.BR (locale_t) 0,
+and sets
+.B errno
+to indicate the error.
+.SH ERRORS
+.TP
+.B EINVAL
+An invalid locale was encountered or an internal error occurred that
+caused the system to be unable to update the locale.
+.SH ATTRIBUTES
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Standard
+_
+MT-Level MT-Safe
+.TE
+
+.SH SEE ALSO
+.BR locale (1),
+.BR duplocale (3C),
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR locale (5)
diff --git a/usr/src/man/man3c/wcrtomb.3c b/usr/src/man/man3c/wcrtomb.3c
index da302b25d1..f245b23146 100644
--- a/usr/src/man/man3c/wcrtomb.3c
+++ b/usr/src/man/man3c/wcrtomb.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCRTOMB 3C "Nov 1, 2003"
+.TH WCRTOMB 3C "Jun 24, 2014"
.SH NAME
-wcrtomb \- convert a wide-character code to a character (restartable)
+wcrtomb, wcrtomb_l \- convert a wide-character code to a character (restartable)
.SH SYNOPSIS
.LP
.nf
@@ -17,19 +18,22 @@ wcrtomb \- convert a wide-character code to a character (restartable)
\fBsize_t\fR \fBwcrtomb\fR(\fBchar *restrict\fR \fIs\fR, \fBwchar_t\fR \fIwc\fR, \fBmbstate_t *restrict\fR \fIps\fR);
.fi
+.LP
+.nf
+#include <stdio.h>
+#include <xlocale.h>
+\fBsize_t\fR \fBwcrtomb_l\fR(\fBchar *restrict\fR \fIs\fR, \fBwchar_t\fR \fIwc\fR, \fBmbstate_t *restrict\fR \fIps\fR,
+ \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
If \fIs\fR is a null pointer, the \fBwcrtomb()\fR function is equivalent to the
call:
-.sp
-.LP
-wcrtomb(buf, L'\e0', ps)
-.sp
+.IP
+\fBwcrtomb\fR(\fIbuf\fR, L'\e0', \fIps\fR);
.LP
where \fIbuf\fR is an internal buffer.
-.sp
.LP
If \fIs\fR is not a null pointer, the \fBwcrtomb()\fR function determines the
number of bytes needed to represent the character that corresponds to the
@@ -39,20 +43,19 @@ At most \fBMB_CUR_MAX\fR bytes are stored. If \fIwc\fR is a null
wide-character, a null byte is stored, preceded by any shift sequence needed to
restore the initial shift state. The resulting state described is the initial
conversion state.
-.sp
.LP
If \fIps\fR is a null pointer, the \fBwcrtomb()\fR function uses its own
internal \fBmbstate_t\fR object, which is initialized at program startup to the
initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to
by \fIps\fR is used to completely describe the current conversion state of the
-associated character sequence. Solaris will behave as if no function defined in
-the Solaris Reference Manual calls \fBwcrtomb()\fR.
-.sp
+associated character sequence. The system will behave as if no function
+defined in the Reference Manual calls \fBwcrtomb()\fR.
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The behavior of \fBwcrtomb()\fR is affected by the \fBLC_CTYPE\fR category of the
+current locale. See \fBenviron\fR(5). The function \fBwcrtomb_l()\fR behaves
+identically to \fBwcrtomb()\fR, except instead of operating in the current
+locale, it operates in the locale specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
The \fBwcrtomb()\fR function returns the number of bytes stored in the array
object (including any shift sequences). When \fIwc\fR is not a valid
@@ -60,7 +63,6 @@ wide-character, an encoding error occurs. In this case, the function stores
the value of the macros \fBEILSEQ\fR in \fBerrno\fR and returns
\fB(size_t)\(mi1\fR; the conversion state is undefined.
.SH ERRORS
-.sp
.LP
The \fBwcrtomb()\fR function may fail if:
.sp
@@ -81,36 +83,28 @@ state.
.RS 10n
Invalid wide-character code is detected.
.RE
-
-.SH USAGE
-.sp
-.LP
-If \fIps\fR is not a null pointer, \fBwcrtomb()\fR uses the \fBmbstate_t\fR
-object pointed to by \fIps\fR and the function can be used safely in
-multithreaded applications, as long as \fBsetlocale\fR(3C) is not being called
-to change the locale. If \fIps\fR is a null pointer, \fBwcrtomb()\fR uses its
-internal \fBmbstate_t\fR object and the function is Unsafe in multithreaded
-applications.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level See NOTES below
+MT-Level See below.
.TE
+.LP
+The \fBwcrtomb()\fR function is Standard. The
+\fBwcrtomb_l()\fR function is Uncommitted.
+.LP
+If \fIps\fR is a null pointer, these functions should be considered Unsafe
+for use in multithreaded applications. Otherwise, they are MT-Safe.
.SH SEE ALSO
-.sp
.LP
-\fBmbsinit\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
+\fBmbsinit\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBuselocale\fR(3C), \fBattributes\fR(5),
\fBstandards\fR(5), \fBenviron\fR(5)
diff --git a/usr/src/man/man3c/wcscoll.3c b/usr/src/man/man3c/wcscoll.3c
index 364ce08054..f7d88a7519 100644
--- a/usr/src/man/man3c/wcscoll.3c
+++ b/usr/src/man/man3c/wcscoll.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCSCOLL 3C "Aug 14, 2002"
+.TH WCSCOLL 3C "Jun 25, 2014"
.SH NAME
-wcscoll, wscoll \- wide character string comparison using collating information
+wcscoll, wcscoll_l wscoll \- wide character string comparison using collating information
.SH SYNOPSIS
.LP
.nf
@@ -17,42 +18,43 @@ wcscoll, wscoll \- wide character string comparison using collating information
\fBint\fR \fBwcscoll\fR(\fBconst wchar_t *\fR\fIws1\fR, \fBconst wchar_t *\fR\fIws2\fR);
.fi
-
+.LP
+.nf
+\fBint\fR \fBwcscoll_l\fR(\fBconst wchar_t *\fR\fIws1\fR, \fBconst wchar_t *\fR\fIws2\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.LP
.nf
\fBint\fR \fBwscoll\fR(\fBconst wchar_t *\fR\fIws1\fR, \fBconst wchar_t *\fR\fIws2\fR);
.fi
-
.SH DESCRIPTION
-.sp
.LP
-The \fBwcscoll()\fR and \fBwscoll()\fR functions compare the wide character
+The \fBwcscoll()\fR, \fBwcscoll_l()\fR, and \fBwscoll()\fR functions compare
+the wide character
string pointed to by \fIws1\fR to the wide character string pointed to by
-\fIws2\fR, both interpreted as appropriate to the \fBLC_COLLATE\fR category of
-the current locale.
-.sp
+\fIws2\fR, both interpreted as appropriate to the \fBLC_COLLATE\fR locale
+category.
.LP
-The \fBwcscoll()\fR and \fBwscoll()\fR functions do not change the setting of
-\fBerrno\fR if successful.
-.sp
+These functions do not change the setting of \fBerrno\fR if successful.
.LP
An application wanting to check for error situations should set \fBerrno\fR to
-0 before calling \fBwcscoll()\fR or \fBwscoll()\fR. If \fBerrno\fR is non-zero
+0 before calling these functions. If \fBerrno\fR is non-zero
on return, an error has occurred.
+.LP
+The function \fBwcsoll_l()\fR behaves identically to \fBwcsoll\fR(), except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-Upon successful completion, \fBwcscoll()\fR and \fBwscoll()\fR return an
+Upon successful completion, these functions return an
integer greater than, equal to, or less than 0, depending upon whether the wide
character string pointed to by \fIws1\fR is greater than, equal to, or less
than the wide character string pointed to by \fIws2\fR, when both are
-interpreted as appropriate to the current locale. On error, \fBwcscoll()\fR and
-\fBwscoll()\fR may set \fBerrno\fR, but no return value is reserved to indicate
-an error.
+interpreted as appropriate to the the current locale, or the locale
+specified by \fIloc\fR. On error,
+they set \fBerrno\fR, but no return value is reserved to indicate an error.
.SH ERRORS
-.sp
.LP
-The \fBwcscoll()\fR and \fBwscoll()\fR functions may fail if:
+The \fBwcscoll()\fR, \fBwcscoll_l()\fR and \fBwscoll()\fR functions may fail if:
.sp
.ne 2
.na
@@ -62,39 +64,32 @@ The \fBwcscoll()\fR and \fBwscoll()\fR functions may fail if:
The \fIws1\fR or \fIws2\fR arguments contain wide character codes outside the
domain of the collating sequence.
.RE
-
.SH USAGE
.sp
.LP
The \fBwcsxfrm\fR(3C) and \fBwcscmp\fR(3C) functions should be used for sorting
-large lists.
+large lists, or when performing many comparisions on the same strings.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
-l | l
+c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability \fBwcscoll()\fR is Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.sp
.LP
-The \fBwcscoll()\fR and \fBwscoll()\fR functions can be used safely in
-multithreaded applications as long as \fBsetlocale\fR(3C) is not being called
-to change the locale.
+The \fBwcscoll()\fR and \fBwcscoll_l()\fR functions are Standard.
+The \fBwscoll()\fR function is Committed.
.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBwcscmp\fR(3C), \fBwcsxfrm\fR(3C), \fBattributes\fR(5),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBwcscmp\fR(3C), \fBwcsxfrm\fR(3C), \fBattributes\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wcsrtombs.3c b/usr/src/man/man3c/wcsrtombs.3c
index 053d27cb49..860f83b913 100644
--- a/usr/src/man/man3c/wcsrtombs.3c
+++ b/usr/src/man/man3c/wcsrtombs.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. Portions Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCSRTOMBS 3C "Nov 1, 2003"
+.TH WCSRTOMBS 3C "Jun 25, 2014"
.SH NAME
-wcsrtombs \- convert a wide-character string to a character string
+wcsrtombs, wcsrtombs_l \- convert a wide-character string to a character string
(restartable)
.SH SYNOPSIS
.LP
@@ -20,9 +21,16 @@ wcsrtombs \- convert a wide-character string to a character string
\fBconst wchar_t **restrict\fR \fIsrc\fR, \fBsize_t\fR \fIlen\fR,
\fBmbstate_t *restrict\fR \fIps\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBsize_t\fR \fBwcsrtombs_l\fR(\fBchar *restrict\fR \fIdst\fR,
+ \fBconst wchar_t **restrict\fR \fIsrc\fR, \fBsize_t\fR \fIlen\fR,
+ \fBmbstate_t *restrict\fR \fIps\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwcsrtombs()\fR function converts a sequence of wide-characters from the
array indirectly pointed to by \fIsrc\fR into a sequence of corresponding
@@ -45,10 +53,8 @@ When the next character would exceed the limit of \fIlen\fR total bytes to be
stored in the array pointed to by \fIdst\fR (and \fIdst\fR is not a null
pointer).
.RE
-.sp
.LP
Each conversion takes place as if by a call to the \fBwcrtomb()\fR function.
-.sp
.LP
If \fIdst\fR is not a null pointer, the pointer object pointed to by \fIsrc\fR
is assigned either a null pointer (if conversion stopped due to reaching a
@@ -56,31 +62,31 @@ terminating null wide-character) or the address just past the last
wide-character converted (if any). If conversion stopped due to reaching a
terminating null wide-character, the resulting state described is the initial
conversion state.
-.sp
.LP
If \fIps\fR is a null pointer, the \fBwcsrtombs()\fR function uses its own
internal \fBmbstate_t\fR object, which is initialized at program startup to the
initial conversion state. Otherwise, the \fBmbstate_t\fR object pointed to by
\fIps\fR is used to completely describe the current conversion state of the
-associated character sequence. Solaris will behave as if no function defined in
-the Solaris Reference Manual calls \fBwcsrtombs()\fR.
-.sp
+associated character sequence. The system will behave as if no function defined
+in the Reference Manual calls any of these functions.
+.LP
+The behavior of \fBwcsrtombs()\fR is affected by the \fBLC_CTYPE\fR category of
+the current locale. See \fBenviron\fR(5).
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
-current locale. See \fBenviron\fR(5).
+The function \fBwcsrtombs_l()\fR behaves identically to \fBwcsrtombs\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
If conversion stops because a code is reached that does not correspond to a
-valid character, an encoding error occurs. In this case, the \fBwcsrtombs()\fR
-function stores the value of the macro \fBEILSEQ\fR in \fBerrno\fR and returns
-\fB(size_t)\(mi1\fR; the conversion state is undefined. Otherwise, it returns
+valid character, an encoding error occurs. In this case, these
+functions store the value of the macro \fBEILSEQ\fR in \fBerrno\fR and return
+\fB(size_t)\(mi1\fR; the conversion state is undefined. Otherwise, they return
the number of bytes in the resulting character sequence, not including the
terminating null (if any).
.SH ERRORS
-.sp
.LP
-The \fBwcsrtombs()\fR function may fail if:
+The \fBwcsrtombs()\fR and \fBwcsrtombs_l()\fR functions may fail if:
.sp
.ne 2
.na
@@ -99,36 +105,28 @@ state.
.RS 10n
A wide-character code does not correspond to a valid character.
.RE
-
-.SH USAGE
-.sp
-.LP
-If \fIps\fR is not a null pointer, \fBwcsrtombs()\fR uses the \fBmbstate_t\fR
-object pointed to by \fIps\fR and the function can be used safely in
-multithreaded applications, as long as \fBsetlocale\fR(3C) is not being called
-to change the locale. If \fIps\fR is a null pointer, \fBwcsrtombs()\fR uses its
-internal \fBmbstate_t\fR object and the function is Unsafe in multithreaded
-applications.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level See NOTES below
+MT-Level See below.
.TE
+.LP
+The \fBwcsrtombs()\fR function is Standard. The \fBwcsrtombs_l()\fR
+function is Uncommitted.
+.LP
+If \fIps\fR is a null pointer, these functions should be considered Unsafe
+for use in multithreaded applications. Otherwise, they are MT-Safe.
.SH SEE ALSO
-.sp
.LP
-\fBmbsinit\fR(3C), \fBsetlocale\fR(3C), \fBwcrtomb\fR(3C), \fBattributes\fR(5),
+\fBmbsinit\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBwcrtomb\fR(3C), \fBattributes\fR(5),
\fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wcswidth.3c b/usr/src/man/man3c/wcswidth.3c
index 0a3b7d1d08..4fc2e56a20 100644
--- a/usr/src/man/man3c/wcswidth.3c
+++ b/usr/src/man/man3c/wcswidth.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved.
.\" Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
@@ -8,9 +9,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCSWIDTH 3C "Aug 14, 2002"
+.TH WCSWIDTH 3C "Jul 11, 2014"
.SH NAME
-wcswidth \- number of column positions of a wide-character string
+wcswidth, wcswidth_l \- number of column positions of a wide-character string
.SH SYNOPSIS
.LP
.nf
@@ -18,6 +19,13 @@ wcswidth \- number of column positions of a wide-character string
\fBint\fR \fBwcswidth\fR(\fBconst wchar_t *\fR\fIpwcs\fR, \fBsize_t\fR \fIn\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+
+\fBint\fR \fBwcswidth_l\fR(\fBconst wchar_t *\fR\fIpwcs\fR, \fBsize_t\fR \fIn\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
.sp
@@ -27,7 +35,6 @@ required for \fIn\fR wide-character codes (or fewer than \fIn\fR wide-character
codes if a null wide-character code is encountered before \fIn\fR
wide-character codes are exhausted) in the string pointed to by \fIpwcs\fR.
.SH RETURN VALUES
-.sp
.LP
The \fBwcswidth()\fR function either returns \fB0\fR (if \fIpwcs\fR points to a
null wide-character code), or returns the number of column positions to be
@@ -35,17 +42,16 @@ occupied by the wide-character string pointed to by \fIpwcs\fR, or returns
\fB\(mi1\fR (if any of the first \fIn\fR wide-character codes in the
wide-character string pointed to by \fIpwcs\fR is not a printing wide-character
code).
+.LP
+The function \fBwcwidth_l()\fR behaves identically to \fBwcwidth()\fR, except
+instead of operating in the current environemtn, it operates in the environment
+specified by \fIloc\fR.
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -60,6 +66,6 @@ MT-Level MT-Safe with exceptions
.TE
.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBwcwidth\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBwcwidth\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wctob.3c b/usr/src/man/man3c/wctob.3c
index 4d004097d2..ddeb81fc5e 100644
--- a/usr/src/man/man3c/wctob.3c
+++ b/usr/src/man/man3c/wctob.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCTOB 3C "Aug 14, 2002"
+.TH WCTOB 3C "Jun 25, 2014"
.SH NAME
-wctob \- wide-character to single-byte conversion
+wctob, wctob_l \- wide-character to single-byte conversion
.SH SYNOPSIS
.LP
.nf
@@ -18,52 +19,52 @@ wctob \- wide-character to single-byte conversion
\fBint\fR \fBwctob\fR(\fBwint_t\fR \fIc\fR);
.fi
+.LP
+.nf
+#include <stdio.h>
+#include <wchar.h>
+#include <xlocale.h>
+\fBint\fR \fBwctob_l\fR(\fBwint_t\fR \fIc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwctob()\fR function determines whether \fIc\fR corresponds to a member
of the extended character set whose character representation is a single byte
when in the initial shift state.
-.sp
.LP
-The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
+The behavior of \fBwctob()\fR is affected by the \fBLC_CTYPE\fR category of the
current locale. See \fBenviron\fR(5)
+.LP
+The function \fBwctob_l()\fR behaves identically to \fBwctob()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-The \fBwctob()\fR function returns \fBEOF\fR if \fIc\fR does not correspond to
-a character with length one in the initial shift state. Otherwise, it returns
+These functions return \fBEOF\fR if \fIc\fR does not correspond to
+a character with length one in the initial shift state. Otherwise, they return
the single-byte representation of that character.
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE ATTRIBUTE VALUE
_
-Interface Stability Standard
+Interface Stability See below
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
-.SH SEE ALSO
-.sp
.LP
-\fBbtowc\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5),
-\fBstandards\fR(5)
-.SH NOTES
-.sp
+The \fBwctob()\fR function is Standard. The \fBwctob_l()\fR function
+is Uncommitted.
+.SH SEE ALSO
.LP
-The \fBwctob()\fR function can be used safely in multithreaded applications, as
-long as \fBsetlocale\fR(3C) is not being called to change the locale.
+\fBbtowc\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wctomb.3c b/usr/src/man/man3c/wctomb.3c
index 813907e9f5..f499f80fdb 100644
--- a/usr/src/man/man3c/wctomb.3c
+++ b/usr/src/man/man3c/wctomb.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCTOMB 3C "Aug 14, 2002"
+.TH WCTOMB 3C "Jun 25, 2014"
.SH NAME
-wctomb \- convert a wide-character code to a character
+wctomb, wctomb_l \- convert a wide-character code to a character
.SH SYNOPSIS
.LP
.nf
@@ -17,47 +18,43 @@ wctomb \- convert a wide-character code to a character
\fBint\fR \fBwctomb\fR(\fBchar *\fR\fIs\fR, \fBwchar_t\fR \fIwchar\fR);
.fi
+.LP
+.nf
+#include <stdlib.h>
+#include <xlocale.h>
+\fBint\fR \fBwctomb_l\fR(\fBchar *\fR\fIs\fR, \fBwchar_t\fR \fIwchar\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwctomb()\fR function determines the number of bytes needed to represent
the character corresponding to the wide-character code whose value is
\fIwchar\fR. It stores the character representation (possibly multiple bytes)
in the array object pointed to by \fIs\fR (if \fIs\fR is not a null pointer).
At most \fBMB_CUR_MAX\fR bytes are stored.
-.sp
.LP
A call with \fIs\fR as a null pointer causes this function to return \fB0\fR.
The behavior of this function is affected by the \fBLC_CTYPE\fR category of the
current locale.
+.LP
+The function \fBwctomb_l()\fR behaves identically to \fBwctomb()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
If \fIs\fR is a null pointer, \fBwctomb()\fR returns \fB0\fR value. If \fIs\fR
is not a null pointer, \fBwctomb()\fR returns \fB\(mi1\fR if the value of
\fIwchar\fR does not correspond to a valid character, or returns the number of
bytes that constitute the character corresponding to the value of \fIwchar\fR.
-.sp
.LP
In no case will the value returned be greater than the value of the
\fBMB_CUR_MAX\fR macro.
.SH ERRORS
-.sp
.LP
No errors are defined.
-.SH USAGE
-.sp
-.LP
-The \fBwctomb()\fR function can be used safely in a multithreaded application,
-as long as \fBsetlocale\fR(3C) is not being called to change the locale.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -66,13 +63,16 @@ ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The \fBwctomb()\fR function is Standard. The \fBwctomb_l()\fR function
+is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBmblen\fR(3C), \fBmbstowcs\fR(3C), \fBmbtowc\fR(3C), \fBsetlocale\fR(3C),
+\fBmblen\fR(3C), \fBmbstowcs\fR(3C), \fBmbtowc\fR(3C),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
\fBwcstombs\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wctrans.3c b/usr/src/man/man3c/wctrans.3c
new file mode 100644
index 0000000000..64b9c7b390
--- /dev/null
+++ b/usr/src/man/man3c/wctrans.3c
@@ -0,0 +1,140 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2014 Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH WCTRANS 3C "Jun 25, 2014"
+
+.SH NAME
+towctrans, towctrans_l, wctrans, wctrans_l \- define and perform transliteration mappings
+.SH SYNOPSIS
+.LP
+.nf
+#include <wctype.h>
+
+\fBwint_t\fR \fBtowctrans\fR(\fBwint_t\fR \fIwc\fR, \fBwctrans_t\fR \fIdesc\fR);
+.fi
+.LP
+.nf
+\fBwint_t\fR \fBtowctrans_l\fR(\fBwint_t\fR \fIwc\fR, \fBwctrans_t\fR \fIdesc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.LP
+.nf
+\fBwctrans_t\fR \fBwctrans\fR(\fBconst char *\fR \fItranclass\fR);
+.fi
+.LP
+.nf
+\fBwctrans_t\fR \fBwctrans_l\fR(\fBconst char *\fR \fItranclass\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
+.SH DESCRIPTION
+.LP
+The functions
+.B wctrans()
+and
+.B wctrans_l()
+are used to obtain a handle to a table that maps one set of wide
+characters to another. They return an object of type
+.I wctrans_t
+which can be used with the functions
+.B towctrans()
+and
+.BR towctrans_l() .
+The valid set of classes that are available depends on the locale.
+The following names are valid in all locales:
+.TP
+"tolower"
+Conversion from upper case to lower case characters.
+.TP
+"toupper"
+Conversion from lower case to upper case characters.
+.LP
+The
+.B towctrans()
+and
+.B towctrans_l()
+functions convert the wide character
+.IR wc
+based on the conversion table specified by
+.IR desc .
+.LP
+The functions
+.B towctrans_l()
+and
+.B wctrans_l()
+are equivalent to the functions
+.B towctrans()
+and
+.BR wctrans() ,
+but instead of operating in the current locale, they operate on the
+locale specified by
+.IR loc .
+.SH RETURN VALUES
+On successful completion,
+.B towctrans()
+and
+.B towctrans_l()
+functions return the character that corresponds to the argument passed
+through the mapping table described by
+.IR desc .
+Otherwise, they return the character unchanged and set
+.BR errno .
+On successful completion,
+.B wctrans()
+and
+.B wctrans_l()
+functions return a non-zero identifier for
+.IR tranclass .
+On failure, they return zero and set
+.BR errno .
+.SH ERRORS
+.LP
+The
+.B wctrans()
+and
+.B wctrans_l()
+functions will fail if:
+.TP
+.B EINVAL
+The mapping class specified by
+.I tranclass
+does not exist or is invalid.
+.LP
+The
+.B towctrans()
+and
+.B towctrans_l()
+functions will fail if:
+.TP
+.B EINVAL
+The mapping class specified by
+.I desc
+is invalid.
+.SH ATTRIBUTES
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Standard
+_
+MT-Level MT-Safe
+.TE
+
+.SH SEE ALSO
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR towlower (3C),
+.BR towupper (3C),
+.BR environ (5),
+.BR locale (5)
diff --git a/usr/src/man/man3c/wctype.3c b/usr/src/man/man3c/wctype.3c
index ef49f2b1d2..7dd303e548 100644
--- a/usr/src/man/man3c/wctype.3c
+++ b/usr/src/man/man3c/wctype.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,9 +8,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCTYPE 3C "Aug 14, 2002"
+.TH WCTYPE 3C "Jun 25, 2014"
.SH NAME
-wctype \- define character class
+wctype, wctype_l \- define character class
.SH SYNOPSIS
.LP
.nf
@@ -17,52 +18,50 @@ wctype \- define character class
\fBwctype_t\fR \fBwctype\fR(\fBconst char *\fR\fIcharclass\fR);
.fi
+.LP
+.nf
+\fBwctype_t\fR \fBwctype_l\fR(\fBconst char *\fR\fIcharclass\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwctype()\fR function is defined for valid character class names as
defined in the current locale. The \fIcharclass\fR is a string identifying a
generic character class for which codeset-specific type information is
required. The following character class names are defined in all locales:
-.sp
-
-.sp
+.IP
.TS
l l l
l l l .
-alnum alpha blank
-cntrl digit graph
-lower print punct
-space upper xdigit
+"alnum" "alpha" "blank"
+"cntrl" "digit" "graph"
+"lower" "print" "punct"
+"space" "upper" "xdigit"
.TE
-.sp
.LP
Additional character class names defined in the locale definition file
(category \fBLC_CTYPE\fR) can also be specified.
-.sp
.LP
The function returns a value of type \fBwctype_t\fR, which can be used as the
-second argument to subsequent calls of \fBiswctype\fR(3C). \fBwctype()\fR
-determines values of \fBwctype_t\fR according to the rules of the coded
-character set defined by character type information in the program's locale
+second argument to subsequent calls of \fBiswctype\fR(3C). The \fBwctype()\fR
+function determines values of \fBwctype_t\fR according to the rules of the coded
+character set defined by character type information in the current locale
(category \fBLC_CTYPE\fR). The values returned by \fBwctype()\fR are valid
-until a call to \fBsetlocale\fR(3C) that modifies the category \fBLC_CTYPE\fR.
+only in the locale, or locales with the same \fBLC_CTYPE\fR category.
+.LP
+The function \fBwctype_l()\fR behaves identically to \fBwctype()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-The \fBwctype()\fR function returns \fB0\fR if the given character class name
-is not valid for the current locale (category \fBLC_CTYPE\fR); otherwise it
+These functions return \fB0\fR if the given character class name
+is not valid for the locale (category \fBLC_CTYPE\fR); otherwise it
returns an object of type \fBwctype_t\fR that can be used in calls to
-\fBiswctype()\fR.
+\fBiswctype\fR(3C).
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -73,11 +72,12 @@ CSI Enabled
_
Interface Stability Standard
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
.SH SEE ALSO
-.sp
.LP
-\fBiswctype\fR(3C), \fBsetlocale\fR(3C), \fBattributes\fR(5),
+\fBiswctype\fR(3C), \fBnewlocale\fR(3C), \fBsetlocale\fR(3C),
+\fBuselocale\fR(3C),
+\fBattributes\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3c/wcwidth.3c b/usr/src/man/man3c/wcwidth.3c
index 01dd8c59b6..b11934cf54 100644
--- a/usr/src/man/man3c/wcwidth.3c
+++ b/usr/src/man/man3c/wcwidth.3c
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 1992, X/Open Company Limited. All Rights Reserved.
.\" Portions Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
@@ -8,9 +9,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH WCWIDTH 3C "Aug 14, 2002"
+.TH WCWIDTH 3C "Jun 25, 2014"
.SH NAME
-wcwidth \- number of column positions of a wide-character code
+wcwidth, wcwidth_l \- number of column positions of a wide-character code
.SH SYNOPSIS
.LP
.nf
@@ -18,32 +19,35 @@ wcwidth \- number of column positions of a wide-character code
\fBint\fR \fBwcwidth\fR(\fBwchar_t\fR \fIwc\fR);
.fi
+.LP
+.nf
+#include <wchar.h>
+#include <xlocale.h>
+\fBint\fR \fBwcwidth_l\fR(\fBwchar_t\fR \fIwc\fR, \fBlocale_t\fR \fIloc\fR);
+.fi
.SH DESCRIPTION
-.sp
.LP
The \fBwcwidth()\fR function determines the number of column positions required
for the wide character \fIwc\fR. The value of \fIwc\fR must be a character
representable as a \fBwchar_t\fR, and must be a wide-character code
corresponding to a valid character in the current locale.
+.LP
+The function \fBwcwidth_l()\fR behaves identically to \fBwcwidth()\fR, except
+instead of operating in the current locale, it operates in the locale
+specified by \fIloc\fR.
.SH RETURN VALUES
-.sp
.LP
-The \fBwcwidth()\fR function either returns \fB0\fR (if \fIwc\fR is a null
-wide-character code), or returns the number of column positions to be occupied
-by the wide-character code \fIwc\fR, or returns \fB\(mi1\fR (if \fIwc\fR does
+These functions either return \fB0\fR (if \fIwc\fR is a null
+wide-character code), or the number of column positions to be occupied
+by the wide-character code \fIwc\fR, or \fB\(mi1\fR (if \fIwc\fR does
not correspond to a printing wide-character code).
.SH ERRORS
-.sp
.LP
No errors are defined.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -52,13 +56,16 @@ ATTRIBUTE TYPE ATTRIBUTE VALUE
_
CSI Enabled
_
-Interface Stability Standard
+Interface Stability See below.
_
-MT-Level MT-Safe with exceptions
+MT-Level MT-Safe
.TE
+.LP
+The \fBwcwidth()\fR function is Standard. The \fBwcwidth_l()\fR function
+is Uncommitted.
.SH SEE ALSO
-.sp
.LP
-\fBsetlocale\fR(3C), \fBwcswidth\fR(3C), \fBattributes\fR(5),
+\fBnewlocale\fR(3C), \fBsetlocale\fR(3C), \fBuselocale\fR(3C),
+\fBwcswidth\fR(3C), \fBattributes\fR(5),
\fBstandards\fR(5)
diff --git a/usr/src/man/man3head/Makefile b/usr/src/man/man3head/Makefile
index 4d58016fbe..e53332b152 100644
--- a/usr/src/man/man3head/Makefile
+++ b/usr/src/man/man3head/Makefile
@@ -12,6 +12,7 @@
#
# Copyright 2011, Richard Lowe
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
#
include $(SRC)/Makefile.master
@@ -104,7 +105,8 @@ MANFILES= acct.h.3head \
wait.h.3head \
wchar.h.3head \
wctype.h.3head \
- wordexp.h.3head
+ wordexp.h.3head \
+ xlocale.h.3head
MANLINKS= acct.3head \
aio.3head \
@@ -192,7 +194,8 @@ MANLINKS= acct.3head \
wait.3head \
wchar.3head \
wctype.3head \
- wordexp.3head
+ wordexp.3head \
+ xlocale.3head
acct.3head := LINKSRC = acct.h.3head
aio.3head := LINKSRC = aio.h.3head
@@ -281,6 +284,7 @@ wait.3head := LINKSRC = wait.h.3head
wchar.3head := LINKSRC = wchar.h.3head
wctype.3head := LINKSRC = wctype.h.3head
wordexp.3head := LINKSRC = wordexp.h.3head
+xlocale.3head := LINKSRC = xlocale.h.3head
.KEEP_STATE:
diff --git a/usr/src/man/man3head/locale.h.3head b/usr/src/man/man3head/locale.h.3head
index 277ef1dd95..2c9d433970 100644
--- a/usr/src/man/man3head/locale.h.3head
+++ b/usr/src/man/man3head/locale.h.3head
@@ -1,5 +1,7 @@
'\" te
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved. Portions Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
.\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between these versions and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html.
@@ -7,7 +9,7 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH LOCALE.H 3HEAD "Sep 10, 2004"
+.TH LOCALE.H 3HEAD "Jun 23, 2004"
.SH NAME
locale.h, locale \- category macros
.SH SYNOPSIS
@@ -15,9 +17,7 @@ locale.h, locale \- category macros
.nf
#include <\fBlocale.h\fR>
.fi
-
.SH DESCRIPTION
-.sp
.LP
The <\fBlocale.h\fR> header provides a definition for the \fBlconv\fR
structure, which includes the following members. (See the definition of
@@ -51,8 +51,6 @@ char p_sign_posn
char *thousands_sep
.fi
.in -2
-
-.sp
.LP
The <\fBlocale.h\fR> header defines \fINULL\fR (as defined in <\fBstddef.h\fR>)
and the following as macros:
@@ -68,22 +66,64 @@ LC_NUMERIC
LC_TIME
.fi
.in -2
-
-.sp
.LP
The preceding expand to distinct integer constant expressions, for use as the
first argument to the \fBsetlocale()\fR function. See \fBsetlocale\fR(3C).
+.LP
+The <\fBlocale.h\fR> header also defines the following macros, for use with
+\fBnewlocale\fR(3C):
+.sp
+.in +2
+.nf
+LC_ALL_MASK
+LC_COLLATE_MASK
+LC_CTYPE_MASK
+LC_MESSAGES_MASK
+LC_MONETARY_MASK
+LC_NUMERIC_MASK
+LC_TIME_MASK
+.fi
+.in -2
+.LP
+In addition, to facilitate the use of per-thread locales with the
+.BR uselocale (3C)
+function, the
+.RB < locale.h >
+header defines the following type and macro:
+.sp
+.in +2
+.nf
+locale_t
+.fi
+.in -2
+.sp
+.RS 6n
+An opaque type that refers to a locale constructed through the use of
+the
+.BR newlocale (3C)
+function.
+.RE
+
.sp
+.in +2
+.nf
+LC_GLOBAL_LOCALE
+.fi
+.in -2
+.sp
+.RS 6n
+A macro which expands to a
+.B locale_t
+that represents the current global locale as set by
+.BR setlocale (3C).
+.RE
+
.LP
Additional macro definitions, beginning with the characters \fBLC_\fR and an
uppercase letter, can also be specified here.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.sp
-
-.sp
.TS
box;
c | c
@@ -96,5 +136,11 @@ Interface Stability Standard
.SH SEE ALSO
.sp
.LP
-\fBsetlocale\fR(3C), \fBlocaleconv\fR(3C), \fBstddef.h\fR(3HEAD),
-\fBattributes\fR(5), \fBlocale\fR(5), \fBstandards\fR(5)
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR localeconv (3C),
+.BR stddef.h (3HEAD),
+.BR attributes (5),
+.BR locale (5),
+.BR standards (5)
diff --git a/usr/src/man/man3head/xlocale.h.3head b/usr/src/man/man3head/xlocale.h.3head
new file mode 100644
index 0000000000..d096d9d890
--- /dev/null
+++ b/usr/src/man/man3head/xlocale.h.3head
@@ -0,0 +1,59 @@
+'\" te
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
+.\"
+.TH XLOCALE.H 3HEAD "Jun 26, 2014"
+.SH NAME
+xlocale.h, xlocale \- extended locale support
+.SH SYNOPSIS
+.LP
+.nf
+#include <\fBxlocale.h\fR>
+.fi
+.SH DESCRIPTION
+.LP
+The
+.RB < xlocale.h >
+header supplies prototypes for various functions that operate
+using the
+.B locale_t
+structure but which are not specified as part of any formal standard.
+Their location in this header follows the convention established by
+other operating systems.
+.LP
+As none of the definitions supplied in this header, nor this
+header itself, are specified in any standard, their use should
+be avoided in portable applications.
+.SH ATTRIBUTES
+.LP
+See
+.BR attributes (5)
+for descriptions of the following attributes:
+.TS
+box;
+c | c
+l | l .
+ATTRIBUTE TYPE ATTRIBUTE VALUE
+_
+Interface Stability Uncommitted
+.TE
+
+.SH SEE ALSO
+.LP
+.BR newlocale (3C),
+.BR setlocale (3C),
+.BR uselocale (3C),
+.BR locale (3HEAD),
+.BR attributes (5),
+.BR locale (5),
+.BR standards (5)
diff --git a/usr/src/man/man3lib/libc.3lib b/usr/src/man/man3lib/libc.3lib
index 036786751a..387ac1b007 100644
--- a/usr/src/man/man3lib/libc.3lib
+++ b/usr/src/man/man3lib/libc.3lib
@@ -1,10 +1,11 @@
'\" te
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" Copyright (c) 2009, Sun Microsystems, Inc. All rights reserved.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with
.\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
.\" Copyright 2011 by Delphix. All rights reserved.
-.TH LIBC 3LIB "Sep 15, 2009"
+.TH LIBC 3LIB "Jul 1, 2014"
.SH NAME
libc \- C library
.SH DESCRIPTION
@@ -35,7 +36,8 @@ l l .
\fB__fwritable\fR \fB__fwriting\fR
\fB__huge_val\fR \fB__iob\fR
\fB__loc1\fR \fB__major\fR
-\fB__makedev\fR \fB__minor\fR
+\fB__makedev\fR \fB__mb_cur_max_l\fR
+\fB__minor\fR
\fB__nsw_extended_action\fR \fB__nsw_freeconfig\fR
\fB__nsw_getconfig\fR \fB__posix_asctime_r\fR
\fB__posix_ctime_r\fR \fB__posix_getgrgid_r\fR
@@ -153,7 +155,8 @@ l l .
\fBbcmp\fR \fBbcopy\fR
\fBbindtextdomain\fR \fBbind_textdomain_codeset\fR
\fBbrk\fR \fBbsd_signal\fR
-\fBbsearch\fR \fBbtowc\fR
+\fBbsearch\fR
+\fBbtowc\fR \fBbtowc_l\fR
\fBbzero\fR \fBcalloc\fR
\fBcatclose\fR \fBcatgets\fR
\fBcatopen\fR \fBcfgetispeed\fR
@@ -201,6 +204,7 @@ l l .
\fBdoor_ucred\fR \fBdoor_unbind\fR
\fBdouble_to_decimal\fR \fBdrand48\fR
\fBdup\fR \fBdup2\fR
+\fBduplocale\fR
\fBeconvert\fR \fBecvt\fR
\fBenable_extended_FILE_stdio\fR
\fBencrypt\fR \fBendgrent\fR
@@ -232,7 +236,8 @@ l l .
\fBfgetpos\fR \fBfgetpwent\fR
\fBfgetpwent_r\fR \fBfgets\fR
\fBfgetspent\fR \fBfgetspent_r\fR
-\fBfgetwc\fR \fBfgetws\fR
+\fBfgetwc\fR \fBfgetwc_l\fR
+\fBfgetws\fR
\fBfile_to_decimal\fR \fBfileno\fR
\fBfinite\fR \fBflockfile\fR
\fBfmtmsg\fR \fBfnmatch\fR
@@ -246,7 +251,8 @@ l l .
\fBfpsetsticky\fR \fBfputc\fR
\fBfputs\fR \fBfputwc\fR
\fBfputws\fR \fBfread\fR
-\fBfree\fR \fBfreopen\fR
+\fBfree\fR \fBfreelocale\fR
+\fBfreopen\fR
\fBfrexp\fR \fBfscanf\fR
\fBfseek\fR \fBfseeko\fR
\fBfsetattr\fR
@@ -310,8 +316,10 @@ l l .
\fBgetutxid\fR \fBgetutxline\fR
\fBgetvfsany\fR \fBgetvfsent\fR
\fBgetvfsfile\fR \fBgetvfsspec\fR
-\fBgetw\fR \fBgetwc\fR
-\fBgetwchar\fR \fBgetwd\fR
+\fBgetw\fR
+\fBgetwc\fR \fBgetwc_l\fR
+\fBgetwchar\fR \fBgetwchar_l\fR
+\fBgetwd\fR
\fBgetwidth\fR \fBgetws\fR
\fBgetzoneid\fR \fBgetzoneidbyname\fR
\fBgetzonenamebyid\fR \fBglob\fR
@@ -326,25 +334,46 @@ l l .
\fBinitstate\fR \fBinnetgr\fR
\fBinsque\fR \fBioctl\fR
\fBis_system_labeled\fR
-\fBisaexec\fR \fBisalnum\fR
-\fBisalpha\fR \fBisascii\fR
-\fBisastream\fR \fBisatty\fR
-\fBisblank\fR \fBiscntrl\fR
-\fBisdigit\fR \fBisenglish\fR
-\fBisgraph\fR \fBisideogram\fR
-\fBislower\fR \fBisnan\fR
+\fBisaexec\fR
+\fBisalnum\fR \fBisalnum_l\fR
+\fBisalpha\fR \fBisalpha_l\fR
+\fBisascii\fR \fBisastream\fR
+\fBisatty\fR
+\fBisblank\fR \fBisblank_l\fR
+\fBiscntrl\fR \fBiscntrl_l\fR
+\fBisdigit\fR \fBisdigit_l\fR
+\fBisenglish\fR
+\fBisgraph\fR \fBisgraph_l\fR
+\fBisideogram\fR
+\fBislower\fR \fBislower_l\fR
+\fBisnan\fR
\fBisnand\fR \fBisnanf\fR
\fBisnumber\fR \fBisphonogram\fR
-\fBisprint\fR \fBispunct\fR
-\fBissetugid\fR \fBisspace\fR
-\fBisspecial\fR \fBisupper\fR
-\fBiswalnum\fR \fBiswalpha\fR
-\fBiswblank\fR \fBiswcntrl\fR
-\fBiswctype\fR \fBiswdigit\fR
-\fBiswgraph\fR \fBiswlower\fR
-\fBiswprint\fR \fBiswpunct\fR
-\fBiswspace\fR \fBiswupper\fR
-\fBiswxdigit\fR \fBisxdigit\fR
+\fBisprint\fR \fBisprint_l\fR
+\fBispunct\fR \fBispunct_l\fR
+\fBissetugid\fR
+\fBisspace\fR \fBisspace_l\fR
+\fBisspecial\fR
+\fBisupper\fR \fBisupper_l\fR
+\fBiswalnum\fR \fBiswalnum_l\fR
+\fBiswalpha\fR \fBiswalpha_l\fR
+\fBiswblank\fR \fBiswblank_l\fR
+\fBiswcntrl\fR \fBiswcntrl_l\fR
+\fBiswctype\fR \fBiswctype_l\fR
+\fBiswdigit\fR \fBiswdigit_l\fR
+\fBiswideogram\fR \fBiswideogram_l\fR
+\fBiswgraph\fR \fBiswgraph_l\fR
+\fBiswhexnumber\fR \fBiswhexnumber_l\fR
+\fBiswlower\fR \fBiswlower_l\fR
+\fBiswnumber\fR \fBiswnumber_l\fR
+\fBiswphonogram\fR \fBiswphonogram_l\fR
+\fBiswprint\fR \fBiswprint_l\fR
+\fBiswpunct\fR \fBiswpunct_l\fR
+\fBiswspace\fR \fBiswspace_l\fR
+\fBiswspecial\fR \fBiswspecial_l\fR
+\fBiswupper\fR \fBiswupper_l\fR
+\fBiswxdigit\fR \fBiswxdigit_l\fR
+\fBisxdigit\fR \fBisxdigit_l\fR
\fBjrand48\fR \fBkill\fR
\fBkillpg\fR \fBl64a\fR
\fBlabs\fR \fBladd\fR
@@ -365,10 +394,15 @@ l l .
\fBlsub\fR \fBlten\fR
\fBlzero\fR \fBmadvise\fR
\fBmakecontext\fR \fBmakeutx\fR
-\fBmalloc\fR \fBmblen\fR
-\fBmbrlen\fR \fBmbrtowc\fR
-\fBmbsinit\fR \fBmbsrtowcs\fR
-\fBmbstowcs\fR \fBmbtowc\fR
+\fBmalloc\fR
+\fBmblen\fR \fBmblen_l\fR
+\fBmbrlen\fR \fBmbrlen_l\fR
+\fBmbrtowc\fR \fBmbrtowc_l\fR
+\fBmbsinit\fR \fBmbsinit_l\fR
+\fBmbsnrtowcs\fR \fBmbsnrtowcs_l\fR
+\fBmbsrtowcs\fR \fBmbsrtowcs_l\fR
+\fBmbstowcs\fR \fBmbstowcs_l\fR
+\fBmbtowc\fR \fBmbtowc_l\fR
\fBmemalign\fR \fBmembar_consumer\fR
\fBmembar_enter\fR \fBmembar_exit\fR
\fBmembar_producer\fR \fBmemccpy\fR
@@ -400,10 +434,11 @@ l l .
\fBmutex_destroy\fR \fBmutex_init\fR
\fBmutex_lock\fR \fBmutex_trylock\fR
\fBmutex_unlock\fR \fBnanosleep\fR
-\fBnextafter\fR
+\fBnextafter\fR \fBnewlocale\fR
\fBnfs_getfh\fR \fBnftw\fR
\fBngettext\fR \fBnice\fR
-\fBnl_langinfo\fR \fBnrand48\fR
+\fBnl_langinfo\fR \fBnl_langinfo_l\fR
+\fBnrand48\fR
\fBnss_default_finders\fR \fBnss_delete\fR
\fBnss_endent\fR \fBnss_getent\fR
\fBnss_search\fR \fBnss_setent\fR
@@ -626,19 +661,23 @@ l l .
\fBstack_setbounds\fR \fBstack_violation\fR
\fBstat\fR \fBstatfs\fR
\fBstatvfs\fR \fBstime\fR
-\fBstr2sig\fR \fBstrcasecmp\fR
+\fBstr2sig\fR
+\fBstrcasecmp\fR \fBstrcasecmp_l\fR
\fBstrcat\fR \fBstrchr\fR
\fBstrcmp\fR \fBstrcoll\fR
\fBstrcpy\fR \fBstrcspn\fR
\fBstrdup\fR \fBstrerror\fR
-\fBstrerror_r\fR \fBstrfmon\fR
-\fBstrftime\fR \fBstring_to_decimal\fR
+\fBstrerror_r\fR
+\fBstrfmon\fR \fBstrfmon_l\fR
+\fBstrftime\fR \fBstrftime_l\fR
+\fBstring_to_decimal\fR
\fBstrlcat\fR \fBstrlcpy\fR
-\fBstrlen\fR \fBstrncasecmp\fR
+\fBstrlen\fR
+\fBstrncasecmp\fR \fBstrncasecmp_l\fR
\fBstrncat\fR \fBstrncmp\fR
\fBstrncpy\fR \fBstrpbrk\fR
-\fBstrptime\fR \fBstrrchr\fR
-\fBstrsep\fR
+\fBstrptime\fR \fBstrptime_l\fR
+\fBstrrchr\fR \fBstrsep\fR
\fBstrsignal\fR \fBstrspn\fR
\fBstrstr\fR \fBstrtod\fR
\fBstrtof\fR \fBstrtoimax\fR
@@ -678,9 +717,12 @@ l l .
\fBtimes\fR \fBtimezone\fR
\fBtmpfile\fR \fBtmpnam\fR
\fBtmpnam_r\fR \fBtoascii\fR
-\fBtolower\fR \fBtoupper\fR
-\fBtowctrans\fR \fBtowlower\fR
-\fBtowupper\fR \fBtruncate\fR
+\fBtolower\fR \fBtolower_l\fR
+\fBtoupper\fR \fBtoupper_l\fR
+\fBtowctrans\fR \fBtowctrans_l\fR
+\fBtowlower\fR \fBtowlower_l\fR
+\fBtowupper\fR \fBtowupper_l\fR
+\fBtruncate\fR
\fBtsearch\fR \fBttyname\fR
\fBttyname_r\fR \fBttyslot\fR
\fBtwalk\fR \fBtzname\fR
@@ -706,6 +748,7 @@ l l .
\fBunlinkat\fR \fBunlockpt\fR
\fBunordered\fR \fBunsetenv\fR
\fBupdwtmp\fR \fBupdwtmpx\fR
+\fBuselocale\fR
\fBusleep\fR \fBustat\fR
\fButime\fR \fButimensat\fR
\fButimes\fR \fButmpname\fR
@@ -727,24 +770,32 @@ l l .
\fBwaitid\fR \fBwaitpid\fR
\fBwalkcontext\fR \fBwarn\fR
\fBwarnx\fR \fBwatoll\fR
-\fBwcrtomb\fR \fBwcscat\fR
+\fBwcrtomb\fR \fBwcrtomb_l\fR
+\fBwcscat\fR
\fBwcschr\fR \fBwcscmp\fR
-\fBwcscoll\fR \fBwcscpy\fR
+\fBwcscoll\fR \fBwcscoll_l\fR
+\fBwcscpy\fR
\fBwcscspn\fR \fBwcsftime\fR
\fBwcslen\fR \fBwcsncat\fR
\fBwcsncmp\fR \fBwcsncpy\fR
\fBwcspbrk\fR \fBwcsrchr\fR
-\fBwcsrtombs\fR \fBwcsspn\fR
+\fBwcsrtombs\fR \fBwcsrtombs_l\fR
+\fBwcsspn\fR
\fBwcsstr\fR \fBwcstod\fR
\fBwcstof\fR \fBwcstoimax\fR
\fBwcstok\fR \fBwcstol\fR
\fBwcstold\fR \fBwcstoll\fR
-\fBwcstombs\fR \fBwcstoul\fR
+\fBwcstombs\fR \fBwctombs_l\fR
+\fBwcstoul\fR
\fBwcstoull\fR \fBwcstoumax\fR
-\fBwcswcs\fR \fBwcswidth\fR
-\fBwcsxfrm\fR \fBwctob\fR
-\fBwctomb\fR \fBwctrans\fR
-\fBwctype\fR \fBwcwidth\fR
+\fBwcswcs\fR
+\fBwcswidth\fR \fBwcswidth_l\fR
+\fBwcsxfrm\fR \fBwcsxfrm_l\fR
+\fBwctob\fR \fBwctob_l\fR
+\fBwctomb\fR \fBwctomb_l\fR
+\fBwctrans\fR \fBwctrans_l\fR
+\fBwctype\fR \fBwctype_l\fR
+\fBwcwidth\fR \fBwcwidth_l\fR
\fBwmemchr\fR \fBwmemcmp\fR
\fBwmemcpy\fR \fBwmemmove\fR
\fBwmemset\fR \fBwordexp\fR
diff --git a/usr/src/man/man5/environ.5 b/usr/src/man/man5/environ.5
index 558abd87c5..2e82787f81 100644
--- a/usr/src/man/man5/environ.5
+++ b/usr/src/man/man5/environ.5
@@ -1,28 +1,27 @@
'\" te
.\" Copyright 1989 AT&T
.\" Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright (c) 2014, Joyent, Inc. All Rights Reserved
+.\" Copyright 2014 Garrett D'Amore <garrett@damore.org>
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH ENVIRON 5 "Nov 19, 2002"
+.TH ENVIRON 5 "Jun 26, 2014"
.SH NAME
environ \- user environment
.SH DESCRIPTION
-.sp
.LP
When a process begins execution, one of the \fBexec\fR family of functions
makes available an array of strings called the environment; see \fBexec\fR(2).
By convention, these strings have the form \fIvariable=value\fR, for example,
\fBPATH=/sbin:/usr/sbin\fR. These environmental variables provide a way to make
information about a program's environment available to programs.
-.sp
.LP
A name may be placed in the environment by the \fBexport\fR command and
\fIname\fR=\fIvalue\fR arguments in \fBsh\fR(1), or by one of the \fBexec\fR
functions. It is unwise to conflict with certain shell variables such as
\fBMAIL\fR, \fBPS1\fR, \fBPS2\fR, and \fBIFS\fR that are frequently exported by
\fB\&.profile\fR files; see \fBprofile\fR(4).
-.sp
.LP
The following environmental variables can be used by applications and are
expected to be set in the target run-time environment.
@@ -45,8 +44,9 @@ file; see \fBpasswd\fR(4).
.sp .6
.RS 4n
The string used to specify internationalization information that allows users
-to work with different national conventions. The \fBsetlocale\fR(3C) function
-checks the \fBLANG\fR environment variable when it is called with \fB""\fR as
+to work with different national conventions. The \fBsetlocale\fR(3C) and
+\fBnewlocale\fR(3C) functions
+check the \fBLANG\fR environment variable when they are called with \fB""\fR as
the \fBlocale\fR argument. \fBLANG\fR is used as the default locale if the
corresponding environment variable for a particular category is unset or null.
If, however, \fBLC_ALL\fR is set to a valid, non-empty value, its contents are
@@ -60,7 +60,10 @@ locale will be used to set the \fBLC_CTYPE\fR category.
.sp
Most commands will invoke \fBsetlocale(LC_ALL, "")\fR prior to any other
processing. This allows the command to be used with different national
-conventions by setting the appropriate environment variables.
+conventions by setting the appropriate environment variables. In addition, some
+commands will use
+.BR uselocale (3C)
+to set a thread-specific locale.
.sp
The following environment variables correspond to each category of
\fBsetlocale\fR(3C):
@@ -84,7 +87,7 @@ and all the other \fBLC_*\fRvariables.
.RS 4n
This category specifies the character collation sequence being used. The
information corresponding to this category is stored in a database created by
-the \fBlocaledef\fR(1) command. This environment variable affects
+the \fBlocaledef\fR(1) command. This environment variable affects
\fBstrcoll\fR(3C) and \fBstrxfrm\fR(3C).
.RE
@@ -517,7 +520,6 @@ The \fItime\fR has the same format as \fIoffset\fR except that no leading sign
.RE
.SH SEE ALSO
-.sp
.LP
\fBcat\fR(1), \fBdate\fR(1), \fBed\fR(1), \fBfmtmsg\fR(1), \fBlocaledef\fR(1),
\fBlogin\fR(1), \fBls\fR(1), \fBmkmsgs\fR(1), \fBnice\fR(1), \fBnohup\fR(1),
@@ -525,6 +527,7 @@ The \fItime\fR has the same format as \fIoffset\fR except that no leading sign
\fBaddseverity\fR(3C), \fBcatopen\fR(3C), \fBctime\fR(3C), \fBctype\fR(3C),
\fBfmtmsg\fR(3C), \fBgetdate\fR(3C), \fBgetnetpath\fR(3NSL), \fBgettext\fR(3C),
\fBgettxt\fR(3C), \fBlocaleconv\fR(3C), \fBmblen\fR(3C), \fBmktime\fR(3C),
+\fBnewlocale\fR(3C),
\fBprintf\fR(3C), \fBsetlocale\fR(3C), \fBstrcoll\fR(3C), \fBstrftime\fR(3C),
-\fBstrtod\fR(3C), \fBstrxfrm\fR(3C), \fBTIMEZONE\fR(4), \fBnetconfig\fR(4),
-\fBpasswd\fR(4), \fBprofile\fR(4)
+\fBstrtod\fR(3C), \fBstrxfrm\fR(3C), \fBuselocale\fR(3C), \fBTIMEZONE\fR(4),
+\fBnetconfig\fR(4), \fBpasswd\fR(4), \fBprofile\fR(4)
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index dd231b99ea..eba786e9d0 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -23,7 +23,7 @@
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
-# Copyright 2013 Garrett D'Amore <garrett@damore.org>
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
#
set name=pkg.fmri value=pkg:/system/header@$(PKGVERS)
@@ -440,7 +440,6 @@ file path=usr/include/ipp/ipp.h
file path=usr/include/ipp/ipp_config.h
file path=usr/include/ipp/ipp_impl.h
file path=usr/include/ipp/ippctl.h
-file path=usr/include/iso/ctype_c99.h
file path=usr/include/iso/ctype_iso.h
file path=usr/include/iso/limits_iso.h
file path=usr/include/iso/locale_iso.h
@@ -457,7 +456,6 @@ file path=usr/include/iso/string_iso.h
file path=usr/include/iso/time_iso.h
file path=usr/include/iso/wchar_c99.h
file path=usr/include/iso/wchar_iso.h
-file path=usr/include/iso/wctype_c99.h
file path=usr/include/iso/wctype_iso.h
file path=usr/include/iso646.h
file path=usr/include/kerberosv5/com_err.h
@@ -1681,6 +1679,7 @@ file path=usr/include/wchar_impl.h
file path=usr/include/wctype.h
file path=usr/include/widec.h
file path=usr/include/wordexp.h
+file path=usr/include/xlocale.h
file path=usr/include/xti.h
file path=usr/include/xti_inet.h
file path=usr/include/zone.h
@@ -1935,6 +1934,7 @@ file path=usr/share/man/man3head/wait.h.3head
file path=usr/share/man/man3head/wchar.h.3head
file path=usr/share/man/man3head/wctype.h.3head
file path=usr/share/man/man3head/wordexp.h.3head
+file path=usr/share/man/man3head/xlocale.h.3head
file path=usr/share/man/man4/note.4
file path=usr/share/man/man5/prof.5
file path=usr/share/man/man7i/cdio.7i
@@ -2115,6 +2115,7 @@ link path=usr/share/man/man3head/wait.3head target=wait.h.3head
link path=usr/share/man/man3head/wchar.3head target=wchar.h.3head
link path=usr/share/man/man3head/wctype.3head target=wctype.h.3head
link path=usr/share/man/man3head/wordexp.3head target=wordexp.h.3head
+link path=usr/share/man/man3head/xlocale.3head target=xlocale.h.3head
$(i386_ONLY)link path=usr/share/src/uts/i86pc/sys \
target=../../../../platform/i86pc/include/sys
$(i386_ONLY)link path=usr/share/src/uts/i86pc/vm \
diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc
index 79c6412ada..2714097dc6 100644
--- a/usr/src/pkg/manifests/system-library.man3c.inc
+++ b/usr/src/pkg/manifests/system-library.man3c.inc
@@ -13,6 +13,7 @@
# Copyright 2011, Richard Lowe
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
# Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
#
file path=usr/share/man/man3c/__fbufsize.3c
@@ -235,6 +236,7 @@ file path=usr/share/man/man3c/msync.3c
file path=usr/share/man/man3c/mutex_init.3c
file path=usr/share/man/man3c/nanosleep.3c
file path=usr/share/man/man3c/ndbm.3c
+file path=usr/share/man/man3c/newlocale.3c
file path=usr/share/man/man3c/nl_langinfo.3c
file path=usr/share/man/man3c/offsetof.3c
file path=usr/share/man/man3c/opendir.3c
@@ -406,6 +408,7 @@ file path=usr/share/man/man3c/stdio.3c
file path=usr/share/man/man3c/str2sig.3c
file path=usr/share/man/man3c/strcoll.3c
file path=usr/share/man/man3c/strerror.3c
+file path=usr/share/man/man3c/strfmon.3c
file path=usr/share/man/man3c/strftime.3c
file path=usr/share/man/man3c/string.3c
file path=usr/share/man/man3c/string_to_decimal.3c
@@ -457,6 +460,8 @@ file path=usr/share/man/man3c/tmpnam.3c
file path=usr/share/man/man3c/toascii.3c
file path=usr/share/man/man3c/tolower.3c
file path=usr/share/man/man3c/toupper.3c
+file path=usr/share/man/man3c/towlower.3c
+file path=usr/share/man/man3c/towupper.3c
file path=usr/share/man/man3c/truncate.3c
file path=usr/share/man/man3c/tsearch.3c
file path=usr/share/man/man3c/ttyname.3c
@@ -471,6 +476,7 @@ file path=usr/share/man/man3c/ungetc.3c
file path=usr/share/man/man3c/ungetwc.3c
file path=usr/share/man/man3c/unlockpt.3c
file path=usr/share/man/man3c/unsetenv.3c
+file path=usr/share/man/man3c/uselocale.3c
file path=usr/share/man/man3c/usleep.3c
file path=usr/share/man/man3c/vfwprintf.3c
file path=usr/share/man/man3c/vlfmt.3c
@@ -495,6 +501,7 @@ file path=usr/share/man/man3c/wcswidth.3c
file path=usr/share/man/man3c/wcsxfrm.3c
file path=usr/share/man/man3c/wctob.3c
file path=usr/share/man/man3c/wctomb.3c
+file path=usr/share/man/man3c/wctrans.3c
file path=usr/share/man/man3c/wctype.3c
file path=usr/share/man/man3c/wcwidth.3c
file path=usr/share/man/man3c/wmemchr.3c
@@ -649,6 +656,7 @@ link path=usr/share/man/man3c/bcmp.3c target=bstring.3c
link path=usr/share/man/man3c/bcopy.3c target=bstring.3c
link path=usr/share/man/man3c/bind_textdomain_codeset.3c target=gettext.3c
link path=usr/share/man/man3c/bindtextdomain.3c target=gettext.3c
+link path=usr/share/man/man3c/btowc_l.3c target=btowc.3c
link path=usr/share/man/man3c/bzero.3c target=bstring.3c
link path=usr/share/man/man3c/calloc.3c target=malloc.3c
link path=usr/share/man/man3c/catclose.3c target=catopen.3c
@@ -698,6 +706,7 @@ link path=usr/share/man/man3c/door_unbind.3c target=door_bind.3c
link path=usr/share/man/man3c/double_to_decimal.3c \
target=floating_to_decimal.3c
link path=usr/share/man/man3c/dup3.3c target=dup2.3c
+link path=usr/share/man/man3c/duplocale.3c target=newlocale.3c
link path=usr/share/man/man3c/edata.3c target=end.3c
link path=usr/share/man/man3c/endgrent.3c target=getgrnam.3c
link path=usr/share/man/man3c/endnetgrent.3c target=getnetgrent.3c
@@ -726,6 +735,7 @@ link path=usr/share/man/man3c/fgetpwent_r.3c target=getpwnam.3c
link path=usr/share/man/man3c/fgets.3c target=gets.3c
link path=usr/share/man/man3c/fgetspent.3c target=getspnam.3c
link path=usr/share/man/man3c/fgetspent_r.3c target=getspnam.3c
+link path=usr/share/man/man3c/fgetwc_l.3c target=fgetwc.3c
link path=usr/share/man/man3c/fgetws.3c target=getws.3c
link path=usr/share/man/man3c/file_to_decimal.3c target=string_to_decimal.3c
link path=usr/share/man/man3c/fileno.3c target=ferror.3c
@@ -739,6 +749,7 @@ link path=usr/share/man/man3c/fpsetround.3c target=fpgetround.3c
link path=usr/share/man/man3c/fpsetsticky.3c target=fpgetround.3c
link path=usr/share/man/man3c/fputs.3c target=puts.3c
link path=usr/share/man/man3c/free.3c target=malloc.3c
+link path=usr/share/man/man3c/freelocale.3c target=newlocale.3c
link path=usr/share/man/man3c/fscanf.3c target=scanf.3c
link path=usr/share/man/man3c/fseeko.3c target=fseek.3c
link path=usr/share/man/man3c/fsetattr.3c target=fgetattr.3c
@@ -785,6 +796,8 @@ link path=usr/share/man/man3c/getvfsany.3c target=getvfsent.3c
link path=usr/share/man/man3c/getvfsfile.3c target=getvfsent.3c
link path=usr/share/man/man3c/getvfsspec.3c target=getvfsent.3c
link path=usr/share/man/man3c/getw.3c target=fgetc.3c
+link path=usr/share/man/man3c/getwc_l.3c target=getwc.3c
+link path=usr/share/man/man3c/getwchar_l.3c target=getwchar.3c
link path=usr/share/man/man3c/getzoneidbyname.3c target=getzoneid.3c
link path=usr/share/man/man3c/getzonenamebyid.3c target=getzoneid.3c
link path=usr/share/man/man3c/globfree.3c target=glob.3c
@@ -797,36 +810,71 @@ link path=usr/share/man/man3c/hdestroy.3c target=hsearch.3c
link path=usr/share/man/man3c/initstate.3c target=random.3c
link path=usr/share/man/man3c/innetgr.3c target=getnetgrent.3c
link path=usr/share/man/man3c/isalnum.3c target=ctype.3c
+link path=usr/share/man/man3c/isalnum_l.3c target=ctype.3c
link path=usr/share/man/man3c/isalpha.3c target=ctype.3c
+link path=usr/share/man/man3c/isalpha_l.3c target=ctype.3c
link path=usr/share/man/man3c/isascii.3c target=ctype.3c
link path=usr/share/man/man3c/isblank.3c target=ctype.3c
+link path=usr/share/man/man3c/isblank_l.3c target=ctype.3c
link path=usr/share/man/man3c/iscntrl.3c target=ctype.3c
+link path=usr/share/man/man3c/iscntrl_l.3c target=ctype.3c
link path=usr/share/man/man3c/isdigit.3c target=ctype.3c
+link path=usr/share/man/man3c/isdigit_l.3c target=ctype.3c
link path=usr/share/man/man3c/isenglish.3c target=iswalpha.3c
link path=usr/share/man/man3c/isgraph.3c target=ctype.3c
+link path=usr/share/man/man3c/isgraph_l.3c target=ctype.3c
link path=usr/share/man/man3c/isideogram.3c target=iswalpha.3c
link path=usr/share/man/man3c/islower.3c target=ctype.3c
+link path=usr/share/man/man3c/islower_l.3c target=ctype.3c
link path=usr/share/man/man3c/isnanf.3c target=isnand.3c
link path=usr/share/man/man3c/isnumber.3c target=iswalpha.3c
link path=usr/share/man/man3c/isphonogram.3c target=iswalpha.3c
link path=usr/share/man/man3c/isprint.3c target=ctype.3c
+link path=usr/share/man/man3c/isprint_l.3c target=ctype.3c
link path=usr/share/man/man3c/ispunct.3c target=ctype.3c
+link path=usr/share/man/man3c/ispunct_l.3c target=ctype.3c
link path=usr/share/man/man3c/isspace.3c target=ctype.3c
+link path=usr/share/man/man3c/isspace_l.3c target=ctype.3c
link path=usr/share/man/man3c/isspecial.3c target=iswalpha.3c
link path=usr/share/man/man3c/isupper.3c target=ctype.3c
+link path=usr/share/man/man3c/isupper_l.3c target=ctype.3c
link path=usr/share/man/man3c/iswalnum.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswalnum_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswalpha_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswascii.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswblank.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswblank_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswcntrl.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswcntrl_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswctype_l.3c target=iswctype.3c
link path=usr/share/man/man3c/iswdigit.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswdigit_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswgraph.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswgraph_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswhexnumber.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswhexnumber_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswideogram.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswideogram_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswlower.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswlower_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswnumber.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswnumber_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswphonogram.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswphonogram_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswprint.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswprint_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswpunct.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswpunct_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswspace.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswspace_l.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswspecial.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswspecial_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswupper.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswupper_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/iswxdigit.3c target=iswalpha.3c
+link path=usr/share/man/man3c/iswxdigit_l.3c target=iswalpha.3c
link path=usr/share/man/man3c/isxdigit.3c target=ctype.3c
+link path=usr/share/man/man3c/isxdigit_l.3c target=ctype.3c
link path=usr/share/man/man3c/jrand48.3c target=drand48.3c
link path=usr/share/man/man3c/l64a.3c target=a64l.3c
link path=usr/share/man/man3c/labs.3c target=abs.3c
@@ -841,6 +889,16 @@ link path=usr/share/man/man3c/localtime_r.3c target=ctime.3c
link path=usr/share/man/man3c/longjmp.3c target=setjmp.3c
link path=usr/share/man/man3c/lrand48.3c target=drand48.3c
link path=usr/share/man/man3c/major.3c target=makedev.3c
+link path=usr/share/man/man3c/mblen_l.3c target=mblen.3c
+link path=usr/share/man/man3c/mbrlen_l.3c target=mbrlen.3c
+link path=usr/share/man/man3c/mbrtowc_l.3c target=mbrtowc.3c
+link path=usr/share/man/man3c/mbsinit_l.3c target=mbsinit.3c
+link path=usr/share/man/man3c/mbsnrtowcs.3c target=mbsrtowcs.3c
+link path=usr/share/man/man3c/mbsnrtowcs_l.3c target=mbsrtowcs.3c
+link path=usr/share/man/man3c/mbsrtowcs_l.3c target=mbsrtowcs.3c
+link path=usr/share/man/man3c/mbstowcs.3c target=mbsrtowcs.3c
+link path=usr/share/man/man3c/mbstowcs_l.3c target=mbsrtowcs.3c
+link path=usr/share/man/man3c/mbtowc_l.3c target=mbtowc.3c
link path=usr/share/man/man3c/memalign.3c target=malloc.3c
link path=usr/share/man/man3c/membar_consumer.3c target=membar_ops.3c
link path=usr/share/man/man3c/membar_enter.3c target=membar_ops.3c
@@ -871,6 +929,7 @@ link path=usr/share/man/man3c/mutex_trylock.3c target=mutex_init.3c
link path=usr/share/man/man3c/mutex_unlock.3c target=mutex_init.3c
link path=usr/share/man/man3c/nftw.3c target=ftw.3c
link path=usr/share/man/man3c/ngettext.3c target=gettext.3c
+link path=usr/share/man/man3c/nl_langinfo_l.3c target=nl_langinfo.3c
link path=usr/share/man/man3c/nrand48.3c target=drand48.3c
link path=usr/share/man/man3c/openlog.3c target=syslog.3c
link path=usr/share/man/man3c/pclose.3c target=popen.3c
@@ -1126,22 +1185,28 @@ link path=usr/share/man/man3c/stderr.3c target=stdio.3c
link path=usr/share/man/man3c/stdin.3c target=stdio.3c
link path=usr/share/man/man3c/stdout.3c target=stdio.3c
link path=usr/share/man/man3c/strcasecmp.3c target=string.3c
+link path=usr/share/man/man3c/strcasecmp_l.3c target=string.3c
link path=usr/share/man/man3c/strcat.3c target=string.3c
link path=usr/share/man/man3c/strchr.3c target=string.3c
link path=usr/share/man/man3c/strcmp.3c target=string.3c
+link path=usr/share/man/man3c/strcoll_l.3c target=strcoll.3c
link path=usr/share/man/man3c/strcpy.3c target=string.3c
link path=usr/share/man/man3c/strcspn.3c target=string.3c
link path=usr/share/man/man3c/strdup.3c target=string.3c
+link path=usr/share/man/man3c/strfmon_l.3c target=strfmon.3c
+link path=usr/share/man/man3c/strftime_l.3c target=strftime.3c
link path=usr/share/man/man3c/strerror_r.3c target=strerror.3c
link path=usr/share/man/man3c/strlcat.3c target=string.3c
link path=usr/share/man/man3c/strlcpy.3c target=string.3c
link path=usr/share/man/man3c/strlen.3c target=string.3c
link path=usr/share/man/man3c/strncasecmp.3c target=string.3c
+link path=usr/share/man/man3c/strncasecmp_l.3c target=string.3c
link path=usr/share/man/man3c/strncat.3c target=string.3c
link path=usr/share/man/man3c/strncmp.3c target=string.3c
link path=usr/share/man/man3c/strncpy.3c target=string.3c
link path=usr/share/man/man3c/strnlen.3c target=string.3c
link path=usr/share/man/man3c/strpbrk.3c target=string.3c
+link path=usr/share/man/man3c/strptime_l.3c target=strptime.3c
link path=usr/share/man/man3c/strrchr.3c target=string.3c
link path=usr/share/man/man3c/strsep.3c target=string.3c
link path=usr/share/man/man3c/strspn.3c target=string.3c
@@ -1153,6 +1218,7 @@ link path=usr/share/man/man3c/strtold.3c target=strtod.3c
link path=usr/share/man/man3c/strtoll.3c target=strtol.3c
link path=usr/share/man/man3c/strtoull.3c target=strtoul.3c
link path=usr/share/man/man3c/strtoumax.3c target=strtoimax.3c
+link path=usr/share/man/man3c/strxfrm_l.3c target=strxfrm.3c
link path=usr/share/man/man3c/swapcontext.3c target=makecontext.3c
link path=usr/share/man/man3c/swprintf.3c target=fwprintf.3c
link path=usr/share/man/man3c/swscanf.3c target=fwscanf.3c
@@ -1174,6 +1240,12 @@ link path=usr/share/man/man3c/timercmp.3c target=timeradd.3c
link path=usr/share/man/man3c/timerisset.3c target=timeradd.3c
link path=usr/share/man/man3c/timersub.3c target=timeradd.3c
link path=usr/share/man/man3c/tmpnam_r.3c target=tmpnam.3c
+link path=usr/share/man/man3c/tolower_l.3c target=tolower.3c
+link path=usr/share/man/man3c/toupper_l.3c target=toupper.3c
+link path=usr/share/man/man3c/towctrans.3c target=wctrans.3c
+link path=usr/share/man/man3c/towctrans_l.3c target=wctrans.3c
+link path=usr/share/man/man3c/towlower_l.3c target=towlower.3c
+link path=usr/share/man/man3c/towupper_l.3c target=towupper.3c
link path=usr/share/man/man3c/ttyname_r.3c target=ttyname.3c
link path=usr/share/man/man3c/twalk.3c target=tsearch.3c
link path=usr/share/man/man3c/tzset.3c target=ctime.3c
@@ -1228,9 +1300,11 @@ link path=usr/share/man/man3c/watof.3c target=wcstod.3c
link path=usr/share/man/man3c/watoi.3c target=wcstol.3c
link path=usr/share/man/man3c/watol.3c target=wcstol.3c
link path=usr/share/man/man3c/watoll.3c target=wcstol.3c
+link path=usr/share/man/man3c/wcrtomb_l.3c target=wcrtomb.3c
link path=usr/share/man/man3c/wcscat.3c target=wcstring.3c
link path=usr/share/man/man3c/wcschr.3c target=wcstring.3c
link path=usr/share/man/man3c/wcscmp.3c target=wcstring.3c
+link path=usr/share/man/man3c/wcscoll_l.3c target=wcscoll.3c
link path=usr/share/man/man3c/wcscpy.3c target=wcstring.3c
link path=usr/share/man/man3c/wcscspn.3c target=wcstring.3c
link path=usr/share/man/man3c/wcsetno.3c target=cset.3c
@@ -1248,6 +1322,12 @@ link path=usr/share/man/man3c/wcstoll.3c target=wcstol.3c
link path=usr/share/man/man3c/wcstoull.3c target=wcstoul.3c
link path=usr/share/man/man3c/wcstoumax.3c target=wcstoimax.3c
link path=usr/share/man/man3c/wcswcs.3c target=wcstring.3c
+link path=usr/share/man/man3c/wcswidth_l.3c target=wcswidth.3c
+link path=usr/share/man/man3c/wctob_l.3c target=wctob.3c
+link path=usr/share/man/man3c/wctomb_l.3c target=wctomb.3c
+link path=usr/share/man/man3c/wctrans_l.3c target=wctrans.3c
+link path=usr/share/man/man3c/wctype_l.3c target=wctype.3c
+link path=usr/share/man/man3c/wcwidth_l.3c target=wcwidth.3c
link path=usr/share/man/man3c/windex.3c target=wcstring.3c
link path=usr/share/man/man3c/wordfree.3c target=wordexp.3c
link path=usr/share/man/man3c/wprintf.3c target=fwprintf.3c
diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf
new file mode 100644
index 0000000000..896141f517
--- /dev/null
+++ b/usr/src/pkg/manifests/system-test-libctest.mf
@@ -0,0 +1,37 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+set name=pkg.fmri value=pkg:/system/test/libctest@$(PKGVERS)
+set name=pkg.description value="C library Unit Tests"
+set name=pkg.summary value="C Library Unit Test Suite"
+set name=info.classification \
+ value=org.opensolaris.category.2008:Development/System
+set name=variant.arch value=$(ARCH)
+dir path=opt/libc-tests
+dir path=opt/libc-tests/bin
+dir path=opt/libc-tests/runfiles
+dir path=opt/libc-tests/tests
+file path=opt/libc-tests/README mode=0444
+file path=opt/libc-tests/bin/libctest mode=0555
+file path=opt/libc-tests/runfiles/default.run mode=0444
+file path=opt/libc-tests/tests/newlocale_test mode=0555
+license lic_CDDL license=lic_CDDL
+depend fmri=locale/de type=require
+depend fmri=locale/en type=require
+depend fmri=locale/ja type=require
+depend fmri=locale/ru type=require
+depend fmri=system/test/testrunner type=require
diff --git a/usr/src/test/Makefile b/usr/src/test/Makefile
index f7ec9e8d37..304163b79f 100644
--- a/usr/src/test/Makefile
+++ b/usr/src/test/Makefile
@@ -16,6 +16,6 @@
.PARALLEL: $(SUBDIRS)
-SUBDIRS = os-tests test-runner util-tests zfs-tests
+SUBDIRS = libc-tests os-tests test-runner util-tests zfs-tests
include Makefile.com
diff --git a/usr/src/test/libc-tests/Makefile b/usr/src/test/libc-tests/Makefile
new file mode 100644
index 0000000000..535d00744b
--- /dev/null
+++ b/usr/src/test/libc-tests/Makefile
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+.PARALLEL: $(SUBDIRS)
+
+SUBDIRS = cmd runfiles tests doc
+
+include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/libc-tests/cmd/Makefile b/usr/src/test/libc-tests/cmd/Makefile
new file mode 100644
index 0000000000..bff7d1228b
--- /dev/null
+++ b/usr/src/test/libc-tests/cmd/Makefile
@@ -0,0 +1,38 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+include $(SRC)/test/Makefile.com
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+ROOTBIN = $(ROOTOPTPKG)/bin
+
+PROGS = libctest
+
+CMDS = $(PROGS:%=$(ROOTBIN)/%)
+$(CMDS) := FILEMODE = 0555
+
+all lint clean clobber:
+
+install: $(CMDS)
+
+$(CMDS): $(ROOTBIN)
+
+$(ROOTBIN):
+ $(INS.dir)
+
+$(ROOTBIN)/%: %.ksh
+ $(INS.rename)
diff --git a/usr/src/test/libc-tests/cmd/libctest.ksh b/usr/src/test/libc-tests/cmd/libctest.ksh
new file mode 100644
index 0000000000..7a9539626d
--- /dev/null
+++ b/usr/src/test/libc-tests/cmd/libctest.ksh
@@ -0,0 +1,63 @@
+#!/usr/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+export MY_TESTS="/opt/libc-tests"
+runner="/opt/test-runner/bin/run"
+
+function fail
+{
+ echo $1
+ exit ${2:-1}
+}
+
+function find_runfile
+{
+ typeset distro=
+ if [[ -d /opt/delphix && -h /etc/delphix/version ]]; then
+ distro=delphix
+ elif [[ 0 -ne $(grep -c OpenIndiana /etc/release 2>/dev/null) ]]; then
+ distro=openindiana
+ elif [[ 0 -ne $(grep -c OmniOS /etc/release 2>/dev/null) ]]; then
+ distro=omnios
+ fi
+
+ if [[ ! -f $MY_TESTS/runfiles/$distro.run ]] && \
+ [[ -f $MY_TESTS/runfiles/default.run ]]; then
+ distro=default
+ fi
+
+ [[ -n $distro ]] && echo $MY_TESTS/runfiles/$distro.run
+}
+
+while getopts c: c; do
+ case $c in
+ 'c')
+ runfile=$OPTARG
+ [[ -f $runfile ]] || fail "Cannot read file: $runfile"
+ ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+[[ -z $runfile ]] && runfile=$(find_runfile)
+[[ -z $runfile ]] && fail "Couldn't determine distro"
+
+$runner -c $runfile
+
+exit $?
diff --git a/usr/src/test/libc-tests/doc/Makefile b/usr/src/test/libc-tests/doc/Makefile
new file mode 100644
index 0000000000..f39f83788a
--- /dev/null
+++ b/usr/src/test/libc-tests/doc/Makefile
@@ -0,0 +1,36 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+include $(SRC)/Makefile.master
+
+READMES = README
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+
+FILES = $(READMES:%=$(ROOTOPTPKG)/%)
+$(FILES) := FILEMODE = 0444
+
+all: $(READMES)
+
+install: $(ROOTOPTPKG) $(FILES)
+
+clean lint clobber:
+
+$(ROOTOPTPKG):
+ $(INS.dir)
+
+$(ROOTOPTPKG)/%: %
+ $(INS.file)
diff --git a/usr/src/test/libc-tests/doc/README b/usr/src/test/libc-tests/doc/README
new file mode 100644
index 0000000000..60fc3b969a
--- /dev/null
+++ b/usr/src/test/libc-tests/doc/README
@@ -0,0 +1,70 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+# Copyright (c) 2012 by Delphix. All rights reserved.
+#
+
+libc Unit Test Suite README
+
+1. What this Unit Test Suite tests
+2. Building and installing this Unit Test Suite
+3. Running this Unit Test Suite
+4. Test results
+
+--------------------------------------------------------------------------------
+
+1. What this Unit Test Suite tests
+
+This Unit Test Suite is for testing various libc interfaces.
+
+2. Building and installing this Unit Test Suite
+
+This Test Suite runs under the testrunner framework (which can be installed
+as pkg:/system/test/testrunner). To build both this Unit Test Suite and the
+testrunner without running a full nightly:
+
+ build_machine$ bldenv [-d] <your_env_file>
+ build_machine$ cd $SRC/test
+ build_machine$ dmake install
+ build_machine$ cd $SRC/pkg
+ build_machine$ dmake install
+
+Then set the publisher on the test machine to point to your repository and
+install the Utils Unit Test Suite.
+
+ test_machine# pkg install pkg:/system/test/libctest
+
+Note, the framework will be installed automatically, as this test suite
+depends on it.
+
+Additionally some text locales are required, specifically, en_US.UTF-8,
+de_DE.UTF-8, ja_JP.UTF-8, and ru_RU.UTF-8. Again, these are listed as
+dependencies and will be automatically installed.
+
+3. Running this Unit Test Suite
+
+The pre-requisites for running the this Unit Test Suite are:
+ - Any user may perform these tests.
+ - The en_US.UTF-8, ja_JP.UTF-8, de_DE.UTF-8, and ru_RU.UTF-8 locales
+ must be installed.
+
+Once the pre-requisites are satisfied, simply run the ostest script:
+
+ test_machine$ /opt/util-tests/bin/libctest
+
+4. Test results
+
+While the Unit Test Suite is running, one informational line is printed at
+the end of each test, and a results summary is printed at the end of the run.
+The results summary includes the location of the complete logs, which is of the
+form /var/tmp/test_results/<ISO 8601 date>.
diff --git a/usr/src/test/libc-tests/runfiles/Makefile b/usr/src/test/libc-tests/runfiles/Makefile
new file mode 100644
index 0000000000..6b51bc1dff
--- /dev/null
+++ b/usr/src/test/libc-tests/runfiles/Makefile
@@ -0,0 +1,40 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+include $(SRC)/Makefile.master
+
+SRCS = default.run
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+RUNFILES = $(ROOTOPTPKG)/runfiles
+
+CMDS = $(SRCS:%=$(RUNFILES)/%)
+$(CMDS) := FILEMODE = 0444
+
+all: $(SRCS)
+
+install: $(CMDS)
+
+clean lint clobber:
+
+$(CMDS): $(RUNFILES) $(SRCS)
+
+$(RUNFILES):
+ $(INS.dir)
+
+$(RUNFILES)/%: %
+ $(INS.file)
diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run
new file mode 100644
index 0000000000..18f1475199
--- /dev/null
+++ b/usr/src/test/libc-tests/runfiles/default.run
@@ -0,0 +1,25 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+[DEFAULT]
+pre =
+verbose = False
+quiet = False
+timeout = 60
+post =
+outputdir = /var/tmp/test_results
+
+[/opt/libc-tests/tests/newlocale_test]
diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile
new file mode 100644
index 0000000000..310dcf06a7
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/Makefile
@@ -0,0 +1,19 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+SUBDIRS = newlocale
+
+include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/libc-tests/tests/newlocale/Makefile b/usr/src/test/libc-tests/tests/newlocale/Makefile
new file mode 100644
index 0000000000..4f761595ca
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/newlocale/Makefile
@@ -0,0 +1,57 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2014 Garrett D'Amore <garrett@damore.org>
+#
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/test/Makefile.com
+
+PROG = newlocale_test
+OBJS = $(PROG:%=%.o)
+SRCS = $(OBJS:%.o=%.c)
+
+C99MODE = -xc99=%all
+
+ROOTOPTPKG = $(ROOT)/opt/libc-tests
+TESTDIR = $(ROOTOPTPKG)/tests
+
+CMDS = $(PROG:%=$(TESTDIR)/%)
+$(CMDS) := FILEMODE = 0555
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o: ../%.c
+ $(COMPILE.c) $<
+
+install: all $(CMDS)
+
+lint: lint_SRCS
+
+clobber: clean
+ -$(RM) $(PROG)
+
+clean:
+ -$(RM) $(OBJS)
+
+$(CMDS): $(TESTDIR) $(PROG)
+
+$(TESTDIR):
+ $(INS.dir)
+
+$(TESTDIR)/%: %
+ $(INS.file)
diff --git a/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c b/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c
new file mode 100644
index 0000000000..214fa9fb19
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c
@@ -0,0 +1,195 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ */
+
+/*
+ * This program tests that newlocale and uselocale work properly in
+ * multi-threaded programs. In order for it to work, it requires that
+ * some additional locales be installed.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <langinfo.h>
+#include <nl_types.h>
+#include <err.h>
+#include <unistd.h>
+#include <pthread.h>
+
+int debug = 0;
+
+/*
+ * Note that on some platforms, different symbols are used. For example,
+ * MacOS Mavericks uses "Eu" for Euro symbol, instead of €. If the locale
+ * data changes, then this program will need to update to reflect that.
+ */
+struct ldata {
+ const char *locale;
+ const char *day1;
+ const char *cursym;
+} ldata[] = {
+ { "C", "Sunday", "" },
+ { "en_US.UTF-8", "Sunday", "$" },
+ { "de_DE.UTF-8", "Sonntag", "€" },
+ { "ru_RU.UTF-8", "воскресенье", "руб." },
+ { "ja_JP.UTF-8", "日曜日", "¥" },
+};
+
+#define NUM_LDATA 5
+#define NUMTHR 20
+#define NUMITR 200
+
+static void
+test_start(const char *testName, const char *format, ...)
+{
+ va_list args;
+
+ (void) printf("TEST STARTING %s: ", testName);
+
+ va_start(args, format);
+ (void) vprintf(format, args);
+ va_end(args);
+ (void) fflush(stdout);
+}
+
+static void
+test_failed(const char *testName, const char *format, ...)
+{
+ va_list args;
+
+ (void) printf("TEST FAILED %s: ", testName);
+
+ va_start(args, format);
+ (void) vprintf(format, args);
+ va_end(args);
+
+ (void) exit(-1);
+}
+
+static void
+test_passed(const char *testName)
+{
+ (void) printf("TEST PASS: %s\n", testName);
+ (void) fflush(stdout);
+}
+
+void *
+testlocale_thr(void *ptr)
+{
+ locale_t cloc, loc;
+ struct lconv *lc;
+ char *day;
+ char *tname = ptr;
+
+ for (int i = 0; i < NUMITR; i++) {
+ struct ldata *l = &ldata[i % NUM_LDATA];
+ cloc = uselocale(NULL);
+
+ loc = newlocale(LC_ALL_MASK, l->locale, NULL);
+ if (loc == NULL) {
+ test_failed("newlocale %s failed", l->locale);
+ }
+ day = nl_langinfo_l(DAY_1, loc);
+ if (strcmp(day, l->day1) != 0) {
+ test_failed(tname, "newlocale data mismatch (%s != %s)",
+ day, l->day1);
+ }
+ if (debug)
+ (void) printf("DAY1: %s\n", day);
+
+ day = nl_langinfo(DAY_1);
+ if (strcmp(day, "Sunday") != 0) {
+ test_failed(tname, "C locale day wrong %s != Sunday",
+ day);
+ }
+ lc = localeconv();
+ if (strcmp(lc->currency_symbol, "") != 0) {
+ test_failed(tname, "C cursym mismatch (%s != %s)",
+ lc->currency_symbol, "");
+ }
+
+ /* we sleep a random bit to mix it up */
+ (void) usleep(rand() % 10);
+
+ (void) uselocale(loc);
+ day = nl_langinfo(DAY_1);
+ if (strcmp(day, l->day1) != 0) {
+ test_failed(tname, "uselocale data mismatch (%s != %s)",
+ day, l->day1);
+ }
+
+ lc = localeconv();
+ if (strcmp(lc->currency_symbol, l->cursym) != 0) {
+ test_failed(tname, "uselocal cursym %s != %s",
+ lc->currency_symbol, l->cursym);
+ }
+ if (debug)
+ (void) printf("CSYM: %s\n", lc->currency_symbol);
+
+ /* we sleep a random bit to mix it up */
+ (void) usleep(rand() % 10);
+
+ if (uselocale(cloc) != loc) {
+ test_failed(tname, "revert old locale mismatch");
+ }
+ freelocale(loc);
+ if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
+ test_failed(tname, "revert GLOBAL_LOCALE mismatch");
+ }
+ }
+ return (NULL);
+}
+
+
+void
+testlocale(void)
+{
+ char *tname = "newlocale/uselocale";
+ pthread_t tid[NUMTHR];
+
+ test_start(tname, "running %d threads %d iterations\n", NUMTHR, NUMITR);
+
+ for (int i = 0; i < NUMTHR; i++) {
+ (void) pthread_create(&tid[i], NULL, testlocale_thr, tname);
+ }
+
+ for (int i = 0; i < NUMTHR; i++) {
+ (void) pthread_join(tid[i], NULL);
+ }
+ test_passed(tname);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optc;
+
+ while ((optc = getopt(argc, argv, "d")) != EOF) {
+ switch (optc) {
+ case 'd':
+ debug++;
+ break;
+ default:
+ (void) fprintf(stderr, "Usage: %s [-d]\n", argv[0]);
+ exit(1);
+ }
+ }
+
+ testlocale();
+
+ exit(0);
+}
diff --git a/usr/src/uts/common/sys/feature_tests.h b/usr/src/uts/common/sys/feature_tests.h
index e6ababd3d4..f96760e34b 100644
--- a/usr/src/uts/common/sys/feature_tests.h
+++ b/usr/src/uts/common/sys/feature_tests.h
@@ -23,6 +23,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ */
#ifndef _SYS_FEATURE_TESTS_H
#define _SYS_FEATURE_TESTS_H
@@ -43,15 +46,16 @@ extern "C" {
* 199309L POSIX.1b-1993 compilation (Real Time)
* 199506L POSIX.1c-1995 compilation (POSIX Threads)
* 200112L POSIX.1-2001 compilation (Austin Group Revision)
+ * 200809L POSIX.1-2008 compilation
*/
#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 1
#endif
/*
- * The feature test macros __XOPEN_OR_POSIX, _STRICT_STDC, and _STDC_C99
- * are Sun implementation specific macros created in order to compress
- * common standards specified feature test macros for easier reading.
+ * The feature test macros __XOPEN_OR_POSIX, _STRICT_STDC, _STRICT_SYMBOLS,
+ * and _STDC_C99 are Sun implementation specific macros created in order to
+ * compress common standards specified feature test macros for easier reading.
* These macros should not be used by the application developer as
* unexpected results may occur. Instead, the user should reference
* standards(5) for correct usage of the standards feature test macros.
@@ -77,6 +81,10 @@ extern "C" {
* the C standard. A value of 199901L indicates a
* compiler that complies with ISO/IEC 9899:1999, other-
* wise known as the C99 standard.
+ *
+ * _STRICT_SYMBOLS Used in cases where symbol visibility is restricted
+ * by the standards, and the user has not explicitly
+ * relaxed the strictness via __EXTENSIONS__.
*/
#if defined(_XOPEN_SOURCE) || defined(_POSIX_C_SOURCE)
@@ -144,6 +152,14 @@ extern "C" {
#endif
/*
+ * Use strict symbol visibility.
+ */
+#if (defined(_STRICT_STDC) || defined(__XOPEN_OR_POSIX)) && \
+ !defined(__EXTENSIONS__)
+#define _STRICT_SYMBOLS
+#endif
+
+/*
* Large file interfaces:
*
* _LARGEFILE_SOURCE
@@ -222,6 +238,8 @@ extern "C" {
* X/Open CAE Specification, Issue 5 (XPG5)
* Open Group Technical Standard, Issue 6 (XPG6), also referred to as
* IEEE Std. 1003.1-2001 and ISO/IEC 9945:2002.
+ * Open Group Technical Standard, Issue 7 (XPG7), also referred to as
+ * IEEE Std. 1003.1-2008 and ISO/IEC 9945:2009.
*
* XPG4v2 is also referred to as UNIX 95 (SUS or SUSv1).
* XPG5 is also referred to as UNIX 98 or the Single Unix Specification,
@@ -229,6 +247,7 @@ extern "C" {
* XPG6 is the result of a merge of the X/Open and POSIX specifications
* and as such is also referred to as IEEE Std. 1003.1-2001 in
* addition to UNIX 03 and SUSv3.
+ * XPG7 is also referred to as UNIX 08 and SUSv4.
*
* When writing a conforming X/Open application, as per the specification
* requirements, the appropriate feature test macros must be defined at
@@ -241,6 +260,7 @@ extern "C" {
* _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED = 1 XPG4v2
* _XOPEN_SOURCE = 500 XPG5
* _XOPEN_SOURCE = 600 (or POSIX_C_SOURCE=200112L) XPG6
+ * _XOPEN_SOURCE = 700 (or POSIX_C_SOURCE=200809L) XPG7
*
* In order to simplify the guards within the headers, the following
* implementation private test macros have been created. Applications
@@ -260,6 +280,7 @@ extern "C" {
* _XPG4_2 X/Open CAE Specification, Issue 4, Version 2 (XPG4v2/UNIX 95/SUS)
* _XPG5 X/Open CAE Specification, Issue 5 (XPG5/UNIX 98/SUSv2)
* _XPG6 Open Group Technical Standard, Issue 6 (XPG6/UNIX 03/SUSv3)
+ * _XPG7 Open Group Technical Standard, Issue 7 (XPG7/UNIX 08/SUSv4)
*/
/* X/Open Portability Guide, Issue 3 */
@@ -294,6 +315,19 @@ extern "C" {
#define _POSIX_C_SOURCE 200112L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
+
+/* Open Group Technical Standard, Issue 7 */
+#elif (_XOPEN_SOURCE - 0 == 700) || (_POSIX_C_SOURCE - 0 == 200809L)
+#define _XPG7
+#define _XPG6
+#define _XPG5
+#define _XPG4_2
+#define _XPG4
+#define _XPG3
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#undef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 700
#endif
/*
@@ -304,12 +338,15 @@ extern "C" {
* with the value of 4 indicates an XPG4 or XPG4v2 (UNIX 95) application.
* _XOPEN_VERSION defined with a value of 500 indicates an XPG5 (UNIX 98)
* application and with a value of 600 indicates an XPG6 (UNIX 03)
- * application. The appropriate version is determined by the use of the
+ * application and with a value of 700 indicates an XPG7 (UNIX 08).
+ * The appropriate version is determined by the use of the
* feature test macros described earlier. The value of _XOPEN_VERSION
* defaults to 3 otherwise indicating support for XPG3 applications.
*/
#ifndef _XOPEN_VERSION
-#ifdef _XPG6
+#if defined(_XPG7)
+#define _XOPEN_VERSION 700
+#elif defined(_XPG6)
#define _XOPEN_VERSION 600
#elif defined(_XPG5)
#define _XOPEN_VERSION 500