Replace the single-byte placeholders for the multi-byte/wide-character
authorstsp <stsp@openbsd.org>
Tue, 27 Jul 2010 16:59:03 +0000 (16:59 +0000)
committerstsp <stsp@openbsd.org>
Tue, 27 Jul 2010 16:59:03 +0000 (16:59 +0000)
conversion interfaces of libc (mbrtowc(3) and friends) with new
implementations that internally call an API based on NetBSD's citrus.
This allows us to support locales with multi-byte character encodings.

Provide two implementations of the citrus-based API: one based on the old
single-byte placeholders for use with our existing single-byte character
locales (C, ISO8859-*, KOI8, CP1251, etc.), and one that provides support
for UTF-8 encoded characters (code based on FreeBSD's implementation).

Install the en_US.UTF-8 ctype locale support file, and allow the UTF-8
ctype locale to be enabled via setlocale(3) (export LC_CTYPE='en_US.UTF-8').

A lot of programs, especially from ports, will now start using UTF-8 if the
UTF-8 locale is enabled. Use at your own risk, and please report any breakage.
Note that ncurses-based programs cannot display UTF-8 right now, this is being
worked on.

To prevent install media growth, add vfprintf(3) and mbrtowc(3) to libstubs.
The mbrtowc stub was copied unchanged from its old single-byte placeholder.
vfprintf.c doesn't need to be copied, just put in .PATH (hint by fgsch@).

Testing by myself, naddy, sthen, nicm, espie, armani, Dmitrij D. Czarkoff.

ok matthieu espie millert sthen nicm deraadt

29 files changed:
distrib/special/libstubs/Makefile
distrib/special/libstubs/mbrtowc_sb.c [new file with mode: 0644]
lib/libc/Makefile.inc
lib/libc/citrus/Makefile.inc [new file with mode: 0644]
lib/libc/citrus/citrus_ctype.c [new file with mode: 0644]
lib/libc/citrus/citrus_ctype.h
lib/libc/citrus/citrus_ctype_local.h
lib/libc/citrus/citrus_none.c [new file with mode: 0644]
lib/libc/citrus/citrus_none.h [new file with mode: 0644]
lib/libc/citrus/citrus_utf8.c [new file with mode: 0644]
lib/libc/citrus/citrus_utf8.h [new file with mode: 0644]
lib/libc/locale/Makefile.inc
lib/libc/locale/btowc.c [new file with mode: 0644]
lib/libc/locale/mblen.c [new file with mode: 0644]
lib/libc/locale/mbrlen.c [new file with mode: 0644]
lib/libc/locale/mbrtowc_sb.c [deleted file]
lib/libc/locale/mbstowcs.c [new file with mode: 0644]
lib/libc/locale/mbtowc.c [new file with mode: 0644]
lib/libc/locale/multibyte.h [new file with mode: 0644]
lib/libc/locale/multibyte_citrus.c [new file with mode: 0644]
lib/libc/locale/multibyte_sb.c [deleted file]
lib/libc/locale/runetable.c
lib/libc/locale/setrunelocale.c
lib/libc/locale/wcscoll.c [new file with mode: 0644]
lib/libc/locale/wcstombs.c [new file with mode: 0644]
lib/libc/locale/wcsxfrm.c [new file with mode: 0644]
lib/libc/locale/wctob.c [new file with mode: 0644]
lib/libc/locale/wctomb.c [new file with mode: 0644]
share/locale/ctype/Makefile

index 3d26028..1be061e 100644 (file)
@@ -1,20 +1,22 @@
-#      $OpenBSD: Makefile,v 1.5 2009/11/18 07:43:22 guenther Exp $
+#      $OpenBSD: Makefile,v 1.6 2010/07/27 16:59:03 stsp Exp $
 
 .include <bsd.own.mk>
 LIB=    stubs
 SRCS=  db.c setlocale.c sha2.c getgrent.c getpwent.c \
-       ethers.c getaddrinfo.c gethostnamadr.c getnetnamadr.c
+       ethers.c getaddrinfo.c gethostnamadr.c getnetnamadr.c \
+       mbrtowc_sb.c vfprintf.c
 NOPIC= Yes
 NOPROFILE=Yes
 NOMAN= 1
 
 CFLAGS+=-D__DBINTERFACE_PRIVATE -DSHA256_ONLY -UYP -I${LIBCSRCDIR}/include \
-       -DNO_LOG_BAD_DNS_RESPONSES
+       -DNO_LOG_BAD_DNS_RESPONSES -I${LIBCSRCDIR}/locale -I${LIBCSRCDIR}/stdio
 
 LIBCSRCDIR=${.CURDIR}/../../../lib/libc
 
 .PATH: ${.CURDIR}/../../../lib/libc/hash
 .PATH: ${.CURDIR}/../../../lib/libc/gen
 .PATH: ${.CURDIR}/../../../lib/libc/net
+.PATH: ${.CURDIR}/../../../lib/libc/stdio
 
 .include <bsd.lib.mk>
diff --git a/distrib/special/libstubs/mbrtowc_sb.c b/distrib/special/libstubs/mbrtowc_sb.c
new file mode 100644 (file)
index 0000000..c31f541
--- /dev/null
@@ -0,0 +1,64 @@
+/*     $OpenBSD: mbrtowc_sb.c,v 1.1 2010/07/27 16:59:03 stsp Exp $     */
+/*     $NetBSD: multibyte_sb.c,v 1.4 2003/08/07 16:43:04 agc Exp $     */
+
+/*
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+/*ARGSUSED*/
+size_t
+mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+{
+
+       /* pwc may be NULL */
+       /* s may be NULL */
+       /* ps appears to be unused */
+
+       if (s == NULL)
+               return 0;
+       if (n == 0)
+               return (size_t)-2;
+       if (pwc)
+               *pwc = (wchar_t)(unsigned char)*s;
+       return (*s != '\0');
+}
+
+int
+mbtowc(wchar_t *pwc, const char *s, size_t n)
+{
+
+       /* pwc may be NULL */
+       /* s may be NULL */
+
+       return mbrtowc(pwc, s, n, NULL);
+}
+
index 28622a6..170a44e 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.inc,v 1.14 2010/02/03 20:49:00 miod Exp $
+#      $OpenBSD: Makefile.inc,v 1.15 2010/07/27 16:59:03 stsp Exp $
 #
 # This file contains make rules used to build libc
 #
@@ -30,6 +30,7 @@ AINC+=  -nostdinc -idirafter ${DESTDIR}/usr/include
 
 .include "${LIBCSRCDIR}/db/Makefile.inc"
 .include "${LIBCSRCDIR}/dlfcn/Makefile.inc"
+.include "${LIBCSRCDIR}/citrus/Makefile.inc"
 .include "${LIBCSRCDIR}/compat-43/Makefile.inc"
 .include "${LIBCSRCDIR}/gen/Makefile.inc"
 .include "${LIBCSRCDIR}/crypt/Makefile.inc"
diff --git a/lib/libc/citrus/Makefile.inc b/lib/libc/citrus/Makefile.inc
new file mode 100644 (file)
index 0000000..b146644
--- /dev/null
@@ -0,0 +1,7 @@
+#      $OpenBSD: Makefile.inc,v 1.1 2010/07/27 16:59:03 stsp Exp $
+
+# citrus sources
+.PATH: ${LIBCSRCDIR}/citrus
+
+SRCS+= citrus_ctype.c citrus_none.c citrus_utf8.c
+CFLAGS+=-I${.CURDIR}
diff --git a/lib/libc/citrus/citrus_ctype.c b/lib/libc/citrus/citrus_ctype.c
new file mode 100644 (file)
index 0000000..c869519
--- /dev/null
@@ -0,0 +1,60 @@
+/*     $OpenBSD: citrus_ctype.c,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+/*     $NetBSD: citrus_ctype.c,v 1.5 2008/06/14 16:01:07 tnozaki Exp $ */
+
+/*-
+ * Copyright (c)1999, 2000, 2001, 2002 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "citrus_ctype.h"
+#include "citrus_none.h"
+#include "citrus_utf8.h"
+
+struct _citrus_ctype_rec _citrus_ctype_none = {
+       &_citrus_none_ctype_ops,        /* cc_ops */
+};
+
+struct _citrus_ctype_rec _citrus_ctype_utf8 = {
+       &_citrus_utf8_ctype_ops,        /* cc_ops */
+};
+
+_citrus_ctype_open(struct _citrus_ctype_rec **rcc, char const *encname)
+{
+       if (!strcmp(encname, "NONE")) {
+               *rcc = &_citrus_ctype_none;
+               __mb_cur_max = 1;
+               return (0);
+       } else if (!strcmp(encname, "UTF8")) {
+               *rcc = &_citrus_ctype_utf8;
+               __mb_cur_max = _CITRUS_UTF8_MB_CUR_MAX;
+               return (0);
+       }
+
+       return (-1);
+}
index 28356ab..5e69b3e 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: citrus_ctype.h,v 1.1 2005/08/07 10:16:23 espie Exp $       */
+/*      $OpenBSD: citrus_ctype.h,v 1.2 2010/07/27 16:59:03 stsp Exp $       */
 /*      $NetBSD: citrus_ctype.h,v 1.2 2003/03/05 20:18:15 tshiozak Exp $        */
 
 /*-
@@ -33,4 +33,6 @@
 
 #include "citrus_ctype_local.h"
 
+extern struct _citrus_ctype_rec _citrus_ctype_none;
+
 #endif
index e3bcd92..8ada0ef 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef _CITRUS_CTYPE_LOCAL_H_
-#define _CITRUS_CTYPE_LOCAL_H_
-/*      $OpenBSD: citrus_ctype_local.h,v 1.1 2005/08/07 10:16:23 espie Exp $       */
+/*      $OpenBSD: citrus_ctype_local.h,v 1.2 2010/07/27 16:59:03 stsp Exp $       */
 /*      $NetBSD: citrus_ctype_local.h,v 1.2 2003/03/05 20:18:15 tshiozak Exp $  */
 
 /*-
  *
  */
 
-#define _CITRUS_DEFAULT_CTYPE_NAME      "NONE"
+#ifndef _CITRUS_CTYPE_LOCAL_H_
+#define _CITRUS_CTYPE_LOCAL_H_
+
+#define _CITRUS_CTYPE_DECLS(_e_)                                       \
+size_t _citrus_##_e_##_ctype_mbrtowc(wchar_t * __restrict,             \
+                                     const char * __restrict, size_t,  \
+                                     void * __restrict);               \
+int    _citrus_##_e_##_ctype_mbsinit(const void * __restrict);         \
+size_t _citrus_##_e_##_ctype_mbsrtowcs(wchar_t * __restrict,           \
+                                       const char ** __restrict,       \
+                                       size_t, void * __restrict);     \
+size_t _citrus_##_e_##_ctype_wcrtomb(char * __restrict, wchar_t,       \
+                                     void * __restrict);               \
+size_t _citrus_##_e_##_ctype_wcsrtombs(char * __restrict,              \
+                                       const wchar_t ** __restrict,    \
+                                       size_t, void * __restrict);     \
 
-#endif
+#define _CITRUS_CTYPE_DEF_OPS(_e_)                                     \
+struct _citrus_ctype_ops_rec _citrus_##_e_##_ctype_ops = {             \
+       /* co_mbrtowc */        &_citrus_##_e_##_ctype_mbrtowc,         \
+       /* co_mbsinit */        &_citrus_##_e_##_ctype_mbsinit,         \
+       /* co_mbsrtowcs */      &_citrus_##_e_##_ctype_mbsrtowcs,       \
+       /* co_wcrtomb */        &_citrus_##_e_##_ctype_wcrtomb,         \
+       /* co_wcsrtombs */      &_citrus_##_e_##_ctype_wcsrtombs,       \
+}
 
+typedef size_t (*_citrus_ctype_mbrtowc_t)
+       (wchar_t * __restrict, const char * __restrict,
+       size_t, void * __restrict);
+typedef int    (*_citrus_ctype_mbsinit_t) (const void * __restrict);
+typedef size_t (*_citrus_ctype_mbsrtowcs_t)
+       (wchar_t * __restrict, const char ** __restrict,
+        size_t, void * __restrict);
+typedef size_t (*_citrus_ctype_wcrtomb_t)
+       (char * __restrict, wchar_t, void * __restrict);
+typedef size_t (*_citrus_ctype_wcsrtombs_t)
+       (char * __restrict, const wchar_t ** __restrict,
+        size_t, void * __restrict);
+
+struct _citrus_ctype_ops_rec {
+       _citrus_ctype_mbrtowc_t         co_mbrtowc;
+       _citrus_ctype_mbsinit_t         co_mbsinit;
+       _citrus_ctype_mbsrtowcs_t       co_mbsrtowcs;
+       _citrus_ctype_wcrtomb_t         co_wcrtomb;
+       _citrus_ctype_wcsrtombs_t       co_wcsrtombs;
+};
+
+#define _CITRUS_DEFAULT_CTYPE_NAME     "NONE"
+
+struct _citrus_ctype_rec {
+       struct _citrus_ctype_ops_rec    *cc_ops;
+};
+
+#endif
diff --git a/lib/libc/citrus/citrus_none.c b/lib/libc/citrus/citrus_none.c
new file mode 100644 (file)
index 0000000..b7b039e
--- /dev/null
@@ -0,0 +1,150 @@
+/*     $OpenBSD: citrus_none.c,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+/*     $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */
+
+/*-
+ * Copyright (c)2002 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <wchar.h>
+
+#include "citrus_ctype.h"
+#include "citrus_none.h"
+
+_CITRUS_CTYPE_DEF_OPS(none);
+
+size_t
+/*ARGSUSED*/
+_citrus_none_ctype_mbrtowc(wchar_t * __restrict pwc,
+                          const char * __restrict s, size_t n,
+                          void * __restrict pspriv)
+{
+       /* pwc may be NULL */
+       /* s may be NULL */
+       /* pspriv appears to be unused */
+
+       if (s == NULL)
+               return 0;
+       if (n == 0)
+               return (size_t)-2;
+       if (pwc)
+               *pwc = (wchar_t)(unsigned char)*s;
+       return (*s != '\0');
+}
+
+int
+/*ARGSUSED*/
+_citrus_none_ctype_mbsinit(const void * __restrict pspriv)
+{
+       return (1);  /* always initial state */
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_none_ctype_mbsrtowcs(wchar_t * __restrict pwcs,
+                            const char ** __restrict s, size_t n,
+                            void * __restrict pspriv)
+{
+       int count = 0;
+
+       /* pwcs may be NULL */
+       /* s may be NULL */
+       /* pspriv appears to be unused */
+
+       if (!s || !*s)
+               return 0;
+
+       if (n != 0) {
+               if (pwcs != NULL) {
+                       do {
+                               if ((*pwcs++ = (wchar_t)(unsigned char)*(*s)++) == 0)
+                                       break;
+                               count++;
+                       } while (--n != 0);
+               } else {
+                       do {
+                               if (((wchar_t)*(*s)++) == 0)
+                                       break;
+                               count++;
+                       } while (--n != 0);
+               }
+       }
+       
+       return count;
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_none_ctype_wcrtomb(char * __restrict s,
+                          wchar_t wc, void * __restrict pspriv)
+{
+       /* s may be NULL */
+       /* ps appears to be unused */
+
+       if (s == NULL)
+               return 0;
+
+       *s = (char) wc;
+       return 1;
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_none_ctype_wcsrtombs(char * __restrict s,
+                            const wchar_t ** __restrict pwcs, size_t n,
+                            void * __restrict pspriv)
+{
+       int count = 0;
+
+       /* s may be NULL */
+       /* pwcs may be NULL */
+       /* pspriv appears to be unused */
+
+       if (pwcs == NULL || *pwcs == NULL)
+               return (0);
+
+       if (s == NULL) {
+               while (*(*pwcs)++ != 0)
+                       count++;
+               return(count);
+       }
+
+       if (n != 0) {
+               do {
+                       if ((*s++ = (char) *(*pwcs)++) == 0)
+                               break;
+                       count++;
+               } while (--n != 0);
+       }
+
+       return count;
+}
diff --git a/lib/libc/citrus/citrus_none.h b/lib/libc/citrus/citrus_none.h
new file mode 100644 (file)
index 0000000..096e379
--- /dev/null
@@ -0,0 +1,37 @@
+/*     $OpenBSD: citrus_none.h,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+/*     $NetBSD: citrus_none.h,v 1.3 2003/06/25 09:51:38 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)2002 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CITRUS_NONE_H_
+#define _CITRUS_NONE_H_
+
+extern struct _citrus_ctype_ops_rec    _citrus_none_ctype_ops;
+
+_CITRUS_CTYPE_DECLS(none);
+
+#endif
diff --git a/lib/libc/citrus/citrus_utf8.c b/lib/libc/citrus/citrus_utf8.c
new file mode 100644 (file)
index 0000000..d28670c
--- /dev/null
@@ -0,0 +1,416 @@
+
+/*     $OpenBSD: citrus_utf8.c,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/limits.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "citrus_ctype.h"
+#include "citrus_utf8.h"
+
+_CITRUS_CTYPE_DEF_OPS(utf8);
+
+struct _utf8_state {
+       wchar_t ch;
+       int     want;
+       wchar_t lbound;
+};
+
+size_t
+/*ARGSUSED*/
+_citrus_utf8_ctype_mbrtowc(wchar_t * __restrict pwc,
+                          const char * __restrict s, size_t n,
+                          void * __restrict pspriv)
+{
+       struct _utf8_state *us;
+       int ch, i, mask, want;
+       wchar_t lbound, wch;
+
+       us = (struct _utf8_state *)pspriv;
+
+       if (us->want < 0 || us->want > _CITRUS_UTF8_MB_CUR_MAX) {
+               errno = EINVAL;
+               return ((size_t)-1);
+       }
+
+       if (s == NULL) {
+               s = "";
+               n = 1;
+               pwc = NULL;
+       }
+
+       if (n == 0) {
+               /* Incomplete multibyte sequence */
+               return ((size_t)-2);
+       }
+
+       if (us->want == 0 && ((ch = (unsigned char)*s) & ~0x7f) == 0) {
+               /* Fast path for plain ASCII characters. */
+               if (pwc != NULL)
+                       *pwc = ch;
+               return (ch != '\0' ? 1 : 0);
+       }
+
+       if (us->want == 0) {
+               /*
+                * Determine the number of octets that make up this character
+                * from the first octet, and a mask that extracts the
+                * interesting bits of the first octet. We already know
+                * the character is at least two bytes long.
+                *
+                * We also specify a lower bound for the character code to
+                * detect redundant, non-"shortest form" encodings. For
+                * example, the sequence C0 80 is _not_ a legal representation
+                * of the null character. This enforces a 1-to-1 mapping
+                * between character codes and their multibyte representations.
+                */
+               ch = (unsigned char)*s;
+               if ((ch & 0x80) == 0) {
+                       mask = 0x7f;
+                       want = 1;
+                       lbound = 0;
+               } else if ((ch & 0xe0) == 0xc0) {
+                       mask = 0x1f;
+                       want = 2;
+                       lbound = 0x80;
+               } else if ((ch & 0xf0) == 0xe0) {
+                       mask = 0x0f;
+                       want = 3;
+                       lbound = 0x800;
+               } else if ((ch & 0xf8) == 0xf0) {
+                       mask = 0x07;
+                       want = 4;
+                       lbound = 0x10000;
+               } else {
+                       /*
+                        * Malformed input; input is not UTF-8.
+                        * See RFC 3629.
+                        */
+                       errno = EILSEQ;
+                       return ((size_t)-1);
+               }
+       } else {
+               want = us->want;
+               lbound = us->lbound;
+       }
+
+       /*
+        * Decode the octet sequence representing the character in chunks
+        * of 6 bits, most significant first.
+        */
+       if (us->want == 0)
+               wch = (unsigned char)*s++ & mask;
+       else
+               wch = us->ch;
+       for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) {
+               if ((*s & 0xc0) != 0x80) {
+                       /*
+                        * Malformed input; bad characters in the middle
+                        * of a character.
+                        */
+                       errno = EILSEQ;
+                       return ((size_t)-1);
+               }
+               wch <<= 6;
+               wch |= *s++ & 0x3f;
+       }
+       if (i < want) {
+               /* Incomplete multibyte sequence. */
+               us->want = want - i;
+               us->lbound = lbound;
+               us->ch = wch;
+               return ((size_t)-2);
+       }
+       if (wch < lbound) {
+               /*
+                * Malformed input; redundant encoding.
+                */
+               errno = EILSEQ;
+               return ((size_t)-1);
+       }
+       if (pwc != NULL)
+               *pwc = wch;
+       us->want = 0;
+       return (wch == L'\0' ? 0 : want);
+}
+
+int
+/*ARGSUSED*/
+_citrus_utf8_ctype_mbsinit(const void * __restrict pspriv)
+{
+       return (pspriv == NULL ||
+           ((const struct _utf8_state *)pspriv)->want == 0);
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_utf8_ctype_mbsrtowcs(wchar_t * __restrict pwcs,
+                            const char ** __restrict s, size_t n,
+                            void * __restrict pspriv)
+{
+       struct _utf8_state *us;
+       const char *src;
+       size_t nchr;
+       wchar_t wc;
+       size_t nb;
+
+       us = (struct _utf8_state *)pspriv;
+       src = *s;
+       nchr = 0;
+
+       if (pwcs == NULL) {
+               /*
+                * The fast path in the loop below is not safe if an ASCII
+                * character appears as anything but the first byte of a
+                * multibyte sequence. Check now to avoid doing it in the loop.
+                */
+               if (us->want > 0 && (signed char)*src > 0) {
+                       errno = EILSEQ;
+                       return ((size_t)-1);
+               }
+               for (;;) {
+                       if ((signed char)*src > 0) {
+                               /*
+                                * Fast path for plain ASCII characters
+                                * excluding NUL.
+                                */
+                               nb = 1;
+                       } else {
+                               nb = _citrus_utf8_ctype_mbrtowc(&wc, src,
+                                   _CITRUS_UTF8_MB_CUR_MAX, us);
+                               if (nb == (size_t)-1) {
+                                       /* Invalid sequence. */
+                                       return (nb);
+                               }
+                               if (nb == 0 || nb == (size_t)-2) {
+                                       return (nchr);
+                               }
+                       }
+
+                       src += nb;
+                       nchr++;
+               }
+               /*NOTREACHED*/
+       }
+
+       /*
+        * The fast path in the loop below is not safe if an ASCII
+        * character appears as anything but the first byte of a
+        * multibyte sequence. Check now to avoid doing it in the loop.
+        */
+       if (n > 0 && us->want > 0 && (signed char)*src > 0) {
+               errno = EILSEQ;
+               return ((size_t)-1);
+       }
+       while (n-- > 0) {
+               if ((signed char)*src > 0) {
+                       /*
+                        * Fast path for plain ASCII characters
+                        * excluding NUL.
+                        */
+                       *pwcs = (wchar_t)*src;
+                       nb = 1;
+               } else {
+                       nb = _citrus_utf8_ctype_mbrtowc(pwcs, src, n, us);
+                       if (nb == (size_t)-1) {
+                               *s = src;
+                               return (nb);
+                       }
+                       if (nb == (size_t)-2) {
+                               *s = src;
+                               return (nchr);
+                       }
+                       if (nb == 0) {
+                               *s = NULL;
+                               return (nchr);
+                       }
+               }
+               src += nb;
+               nchr++;
+               pwcs++;
+       }
+       *s = src;
+       return (nchr);
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_utf8_ctype_wcrtomb(char * __restrict s,
+                          wchar_t wc, void * __restrict pspriv)
+{
+       struct _utf8_state *us;
+       unsigned char lead;
+       int i, len;
+
+       us = (struct _utf8_state *)pspriv;
+
+       if (us->want != 0) {
+               errno = EINVAL;
+               return ((size_t)-1);
+       }
+
+       if (s == NULL) {
+               /* Reset to initial shift state (no-op) */
+               return (1);
+       }
+
+       if ((wc & ~0x7f) == 0) {
+               /* Fast path for plain ASCII characters. */
+               *s = (char)wc;
+               return (1);
+       }
+
+       /*
+        * Determine the number of octets needed to represent this character.
+        * We always output the shortest sequence possible. Also specify the
+        * first few bits of the first octet, which contains the information
+        * about the sequence length.
+        */
+       if ((wc & ~0x7f) == 0) {
+               lead = 0;
+               len = 1;
+       } else if ((wc & ~0x7ff) == 0) {
+               lead = 0xc0;
+               len = 2;
+       } else if ((wc & ~0xffff) == 0) {
+               lead = 0xe0;
+               len = 3;
+       } else if ((wc & ~0x1fffff) == 0) {
+               lead = 0xf0;
+               len = 4;
+       } else {
+               errno = EILSEQ;
+               return ((size_t)-1);
+       }
+
+       /*
+        * Output the octets representing the character in chunks
+        * of 6 bits, least significant last. The first octet is
+        * a special case because it contains the sequence length
+        * information.
+        */
+       for (i = len - 1; i > 0; i--) {
+               s[i] = (wc & 0x3f) | 0x80;
+               wc >>= 6;
+       }
+       *s = (wc & 0xff) | lead;
+
+       return (len);
+}
+
+size_t
+/*ARGSUSED*/
+_citrus_utf8_ctype_wcsrtombs(char * __restrict s,
+                            const wchar_t ** __restrict pwcs, size_t n,
+                            void * __restrict pspriv)
+{
+       struct _utf8_state *us;
+       char buf[_CITRUS_UTF8_MB_CUR_MAX];
+       const wchar_t *src;
+       size_t nbytes;
+       size_t nb;
+
+       us = (struct _utf8_state *)pspriv;
+
+       if (us->want != 0) {
+               errno = EINVAL;
+               return ((size_t)-1);
+       }
+
+       src = *pwcs;
+       nbytes = 0;
+
+       if (s == NULL) {
+               for (;;) {
+                       if (0 <= *src && *src < 0x80)
+                               /* Fast path for plain ASCII characters. */
+                               nb = 1;
+                       else {
+                               nb = _citrus_utf8_ctype_wcrtomb(buf, *src, us);
+                               if (nb == (size_t)-1) {
+                                       /* Invalid character */
+                                       return (nb);
+                               }
+                       }
+                       if (*src == L'\0') {
+                               return (nbytes + nb - 1);
+                       }
+                       src++;
+                       nbytes += nb;
+               }
+               /*NOTREACHED*/
+       }
+
+       while (n > 0) {
+               if (0 <= *src && *src < 0x80) {
+                       /* Fast path for plain ASCII characters. */
+                       nb = 1;
+                       *s = *src;
+               } else if (n > (size_t)_CITRUS_UTF8_MB_CUR_MAX) {
+                       /* Enough space to translate in-place. */
+                       nb = _citrus_utf8_ctype_wcrtomb(s, *src, us);
+                       if (nb == (size_t)-1) {
+                               *pwcs = src;
+                               return (nb);
+                       }
+               } else {
+                       /*
+                        * May not be enough space; use temp. buffer.
+                        */
+                       nb = _citrus_utf8_ctype_wcrtomb(buf, *src, us);
+                       if (nb == (size_t)-1) {
+                               *pwcs = src;
+                               return (nb);
+                       }
+                       if (nb > n)
+                               /* MB sequence for character won't fit. */
+                               break;
+                       memcpy(s, buf, nb);
+               }
+               if (*src == L'\0') {
+                       *pwcs = NULL;
+                       return (nbytes + nb - 1);
+               }
+               src++;
+               s += nb;
+               n -= nb;
+               nbytes += nb;
+       }
+       *pwcs = src;
+       return (nbytes);
+}
diff --git a/lib/libc/citrus/citrus_utf8.h b/lib/libc/citrus/citrus_utf8.h
new file mode 100644 (file)
index 0000000..d7a7bd8
--- /dev/null
@@ -0,0 +1,39 @@
+/*     $OpenBSD */
+/*     $NetBSD: citrus_utf8.h,v 1.2 2003/06/25 09:51:49 tshiozak Exp $ */
+
+/*-
+ * Copyright (c)2002 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _CITRUS_UTF8_H_
+#define _CITRUS_UTF8_H_
+
+extern struct _citrus_ctype_ops_rec    _citrus_utf8_ctype_ops;
+
+#define _CITRUS_UTF8_MB_CUR_MAX        4
+
+_CITRUS_CTYPE_DECLS(utf8);
+
+#endif
index 8800b14..987996b 100644 (file)
@@ -1,15 +1,15 @@
-#      $OpenBSD: Makefile.inc,v 1.15 2010/02/03 20:49:00 miod Exp $
+#      $OpenBSD: Makefile.inc,v 1.16 2010/07/27 16:59:03 stsp Exp $
 
 # locale sources
 .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/locale ${LIBCSRCDIR}/locale
 
-SRCS+= _def_messages.c _def_monetary.c _def_numeric.c _def_time.c \
-       localeconv.c nl_langinfo.c setlocale.c iswctype.c mbrtowc_sb.c \
-       multibyte_sb.c __mb_cur_max.c \
-       wcstof.c wcstod.c wcstold.c \
-       wcstol.c wcstoul.c wcstoll.c wcstoull.c wcstoimax.c wcstoumax.c \
+SRCS+= btowc.c _def_messages.c _def_monetary.c _def_numeric.c _def_time.c \
+       localeconv.c nl_langinfo.c setlocale.c iswctype.c __mb_cur_max.c \
+       mblen.c mbrlen.c mbstowcs.c mbtowc.c multibyte_citrus.c wcscoll.c \
+       wcstombs.c wctob.c wctomb.c wcstof.c wcstod.c wcstold.c wcstol.c \
+       wcstoul.c wcstoll.c wcstoull.c wcstoimax.c wcstoumax.c \
        setrunelocale.c runeglue.c rune.c runetable.c ___runetype_mb.c \
-       _wctrans.c
+       _wctrans.c wcsxfrm.c
 
 MAN+=  nl_langinfo.3 setlocale.3 iswalnum.3 towlower.3 \
        btowc.3 mblen.3 mbrlen.3 mbrtowc.3 mbsinit.3 mbsrtowcs.3 \
@@ -37,4 +37,4 @@ MLINKS+=setlocale.3 localeconv.3 \
        wcstol.3 wcstoimax.3 \
        wcstol.3 wcstoumax.3
 
-CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${.CURDIR} -I${LIBCSRCDIR}/citrus
diff --git a/lib/libc/locale/btowc.c b/lib/libc/locale/btowc.c
new file mode 100644 (file)
index 0000000..e1c6893
--- /dev/null
@@ -0,0 +1,54 @@
+/*     $OpenBSD: btowc.c,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+wint_t
+btowc(int c)
+{
+       mbstate_t mbs;
+       char cc;
+       wchar_t wc;
+
+       if (c == EOF)
+               return (WEOF);
+       /*
+        * We expect mbrtowc() to return 0 or 1, hence the check for n > 1
+        * which detects error return values as well as "impossible" byte
+        * counts.
+        */
+       memset(&mbs, 0, sizeof(mbs));
+       cc = (char)c;
+       if (mbrtowc(&wc, &cc, 1, &mbs) > 1)
+               return (WEOF);
+       return (wc);
+}
diff --git a/lib/libc/locale/mblen.c b/lib/libc/locale/mblen.c
new file mode 100644 (file)
index 0000000..56d718e
--- /dev/null
@@ -0,0 +1,50 @@
+/*     $OpenBSD: mblen.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+int
+mblen(const char *s, size_t n)
+{
+       static mbstate_t mbs;
+       size_t rval;
+
+       if (s == NULL) {
+               /* No support for state dependent encodings. */
+               memset(&mbs, 0, sizeof(mbs));
+               return (0);
+       }
+       rval = mbrtowc(NULL, s, n, &mbs);
+       if (rval == (size_t)-1 || rval == (size_t)-2)
+               return (-1);
+       return ((int)rval);
+}
diff --git a/lib/libc/locale/mbrlen.c b/lib/libc/locale/mbrlen.c
new file mode 100644 (file)
index 0000000..97c48d2
--- /dev/null
@@ -0,0 +1,41 @@
+/*     $OpenBSD: mbrlen.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <wchar.h>
+
+size_t
+mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps)
+{
+       static mbstate_t mbs;
+
+       if (ps == NULL)
+               ps = &mbs;
+       return (mbrtowc(NULL, s, n, ps));
+}
diff --git a/lib/libc/locale/mbrtowc_sb.c b/lib/libc/locale/mbrtowc_sb.c
deleted file mode 100644 (file)
index e47e06a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*     $OpenBSD: mbrtowc_sb.c,v 1.4 2005/11/27 20:03:06 cloder Exp $   */
-/*     $NetBSD: multibyte_sb.c,v 1.4 2003/08/07 16:43:04 agc Exp $     */
-
-/*
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <wchar.h>
-
-/*ARGSUSED*/
-size_t
-mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
-{
-
-       /* pwc may be NULL */
-       /* s may be NULL */
-       /* ps appears to be unused */
-
-       if (s == NULL)
-               return 0;
-       if (n == 0)
-               return (size_t)-1;
-       if (pwc)
-               *pwc = (wchar_t)(unsigned char)*s;
-       return (*s != '\0');
-}
-
-int
-mbtowc(wchar_t *pwc, const char *s, size_t n)
-{
-
-       /* pwc may be NULL */
-       /* s may be NULL */
-
-       return mbrtowc(pwc, s, n, NULL);
-}
-
diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c
new file mode 100644 (file)
index 0000000..7ea97e4
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: mbstowcs.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+size_t
+mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
+{
+       mbstate_t mbs;
+       const char *sp;
+
+       memset(&mbs, 0, sizeof(mbs));
+       sp = s;
+       return (mbsrtowcs(pwcs, &sp, n, &mbs));
+}
diff --git a/lib/libc/locale/mbtowc.c b/lib/libc/locale/mbtowc.c
new file mode 100644 (file)
index 0000000..e0dcff0
--- /dev/null
@@ -0,0 +1,51 @@
+/*     $OpenBSD: mbtowc.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <errno.h>
+
+int
+mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n)
+{
+       static mbstate_t mbs;
+       size_t rval;
+
+       if (s == NULL) {
+               /* No support for state dependent encodings. */
+               memset(&mbs, 0, sizeof(mbs));
+               return (0);
+       }
+       rval = mbrtowc(pwc, s, n, &mbs);
+       if (rval == (size_t)-1 || rval == (size_t)-2)
+               return (-1);
+       return ((int)rval);
+}
diff --git a/lib/libc/locale/multibyte.h b/lib/libc/locale/multibyte.h
new file mode 100644 (file)
index 0000000..9a69ada
--- /dev/null
@@ -0,0 +1,50 @@
+/*     $OpenBSD: multibyte.h,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+/*     $NetBSD: multibyte.h,v 1.5 2009/01/11 02:46:28 christos Exp $   */
+
+/*-
+ * Copyright (c)2002 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MULTIBYTE_H_
+#define _MULTIBYTE_H_
+
+typedef struct _RuneStatePriv {
+       _RuneLocale     *__runelocale;
+       char            __private __attribute__((__aligned__));
+} _RuneStatePriv;
+
+typedef union _RuneState {
+       mbstate_t               __pad;
+       struct _RuneStatePriv   __priv;
+#define rs_runelocale          __priv.__runelocale
+#define rs_private             __priv.__private
+} _RuneState;
+#define _RUNE_STATE_PRIVSIZE   (sizeof(mbstate_t)-offsetof(_RuneStatePriv, __private))
+
+#define _ps_to_runestate(ps)   ((_RuneState *)(void *)(ps))
+#define _ps_to_runelocale(ps)  (_ps_to_runestate(ps)->rs_runelocale)
+#define _ps_to_private(ps)     ((void *)&_ps_to_runestate(ps)->rs_private)
+       
+#endif /*_MULTIBYTE_H_*/
diff --git a/lib/libc/locale/multibyte_citrus.c b/lib/libc/locale/multibyte_citrus.c
new file mode 100644 (file)
index 0000000..9993e67
--- /dev/null
@@ -0,0 +1,101 @@
+/*     $OpenBSD: multibyte_citrus.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+/*     $NetBSD: multibyte_amd1.c,v 1.7 2009/01/11 02:46:28 christos Exp $ */
+
+/*-
+ * Copyright (c)2002, 2008 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <wchar.h>
+
+#include "citrus_ctype.h"
+#include "rune.h"
+#include "multibyte.h"
+
+int
+mbsinit(const mbstate_t *ps)
+{
+       struct _citrus_ctype_rec *cc;
+       _RuneLocale *rl;
+
+       if (ps == NULL)
+               return 1;
+
+       rl = _ps_to_runelocale(ps);
+       if (rl == NULL)
+               rl = _CurrentRuneLocale;
+       cc = rl->rl_citrus_ctype;
+       return (*cc->cc_ops->co_mbsinit)(ps);
+}
+
+size_t
+mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+{
+       static mbstate_t mbs;
+       struct _citrus_ctype_rec *cc;
+
+       if (ps == NULL)
+               ps = &mbs;
+       cc = _CurrentRuneLocale->rl_citrus_ctype;
+       return (*cc->cc_ops->co_mbrtowc)(pwc, s, n, _ps_to_private(ps));
+}
+
+size_t
+mbsrtowcs(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps)
+{
+       static mbstate_t mbs;
+       struct _citrus_ctype_rec *cc;
+
+       if (ps == NULL)
+               ps = &mbs;
+       cc = _CurrentRuneLocale->rl_citrus_ctype;
+       return (*cc->cc_ops->co_mbsrtowcs)(pwcs, s, n, _ps_to_private(ps));
+}
+
+size_t
+wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
+{
+       static mbstate_t mbs;
+       struct _citrus_ctype_rec *cc;
+
+       if (ps == NULL)
+               ps = &mbs;
+       cc = _CurrentRuneLocale->rl_citrus_ctype;
+       return (*cc->cc_ops->co_wcrtomb)(s, wc, _ps_to_private(ps));
+}
+
+size_t
+wcsrtombs(char *s, const wchar_t **ppwcs, size_t n, mbstate_t *ps)
+{
+       static mbstate_t mbs;
+       struct _citrus_ctype_rec *cc;
+
+       if (ps == NULL)
+               ps = &mbs;
+       cc = _CurrentRuneLocale->rl_citrus_ctype;
+       return (*cc->cc_ops->co_wcsrtombs)(s, ppwcs, n, _ps_to_private(ps));
+}
diff --git a/lib/libc/locale/multibyte_sb.c b/lib/libc/locale/multibyte_sb.c
deleted file mode 100644 (file)
index 4067b15..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*     $OpenBSD: multibyte_sb.c,v 1.7 2008/08/23 07:51:35 djm Exp $    */
-/*     $NetBSD: multibyte_sb.c,v 1.4 2003/08/07 16:43:04 agc Exp $     */
-
-/*
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <wchar.h>
-
-/*
- * Stub multibyte character functions.
- * This cheezy implementation is fixed to the native single-byte
- * character set.
- */
-
-/*ARGSUSED*/
-int
-mbsinit(const mbstate_t *ps)
-{
-
-       return 1;
-}
-
-/*ARGSUSED*/
-size_t
-mbrlen(const char *s, size_t n, mbstate_t *ps)
-{
-
-       /* ps appears to be unused */
-
-       if (s == NULL || *s == '\0')
-               return 0;
-       if (n == 0)
-               return (size_t)-1;
-       return 1;
-}
-
-int
-mblen(const char *s, size_t n)
-{
-
-       /* s may be NULL */
-
-       return mbrlen(s, n, NULL);
-}
-
-/*ARGSUSED*/
-size_t
-wcrtomb(char *s, wchar_t wchar, mbstate_t *ps)
-{
-
-       /* s may be NULL */
-       /* ps appears to be unused */
-
-       if (s == NULL)
-               return 0;
-
-       *s = (char) wchar;
-       return 1;
-}
-
-int
-wctomb(char *s, wchar_t wchar)
-{
-
-       /* s may be NULL */
-
-       return wcrtomb(s, wchar, NULL);
-}
-
-/*ARGSUSED*/
-size_t
-mbsrtowcs(wchar_t *pwcs, const char **s, size_t n, mbstate_t *ps)
-{
-       int count = 0;
-
-       /* pwcs may be NULL */
-       /* s may be NULL */
-       /* ps appears to be unused */
-
-       if (!s || !*s)
-               return 0;
-
-       if (n != 0) {
-               if (pwcs != NULL) {
-                       do {
-                               if ((*pwcs++ = (wchar_t)(unsigned char)*(*s)++) == 0)
-                                       break;
-                               count++;
-                       } while (--n != 0);
-               } else {
-                       do {
-                               if (((wchar_t)*(*s)++) == 0)
-                                       break;
-                               count++;
-                       } while (--n != 0);
-               }
-       }
-       
-       return count;
-}
-
-size_t
-mbstowcs(wchar_t *pwcs, const char *s, size_t n)
-{
-
-       /* pwcs may be NULL */
-       if (pwcs == NULL)
-               return strlen(s);
-
-       return mbsrtowcs(pwcs, &s, n, NULL);
-}
-
-/*ARGSUSED*/
-size_t
-wcsrtombs(char *s, const wchar_t **pwcs, size_t n, mbstate_t *ps)
-{
-       int count = 0;
-
-       /* s may be NULL */
-       /* pwcs may be NULL */
-       /* ps appears to be unused */
-
-       if (pwcs == NULL || *pwcs == NULL)
-               return (0);
-
-       if (s == NULL) {
-               while (*(*pwcs)++ != 0)
-                       count++;
-               return(count);
-       }
-
-       if (n != 0) {
-               do {
-                       if ((*s++ = (char) *(*pwcs)++) == 0)
-                               break;
-                       count++;
-               } while (--n != 0);
-       }
-
-       return count;
-}
-
-size_t
-wcstombs(char *s, const wchar_t *pwcs, size_t n)
-{
-
-       /* s may be NULL */
-       /* pwcs may be NULL */
-
-       return wcsrtombs(s, &pwcs, n, NULL);
-}
-
-wint_t
-btowc(int c)
-{
-       if (c == EOF || c & ~0xFF)
-               return WEOF;
-       return (wint_t)c;
-}
-
-int
-wctob(wint_t c)
-{
-       if (c == WEOF || c & ~0xFF)
-               return EOF;
-       return (int)c;
-}
-
-int
-wcscoll(const wchar_t *s1, const wchar_t *s2)
-{
-       while (*s1 == *s2++)
-               if (*s1++ == 0)
-                       return (0);
-       return ((unsigned char)(*s1) - (unsigned char)(*--s2));
-}
-
-size_t 
-wcsxfrm(wchar_t *dest, const wchar_t *src, size_t n)
-{
-       if (n == 0)
-               return wcslen(src);
-       return wcslcpy(dest, src, n);
-}
index 3324d1b..07dce4b 100644 (file)
@@ -43,6 +43,8 @@
 #include <wchar.h>
 #include "rune.h"
 #include "rune_local.h"
+#include "citrus_ctype.h"
+#include "citrus_none.h"
 #include <stdlib.h>
 
 _RuneLocale _DefaultRuneLocale = {
@@ -378,7 +380,7 @@ _RuneLocale _DefaultRuneLocale = {
     { 0, NULL },
     NULL, 0,
     "646",
-   0,
+   &_citrus_ctype_none,
     {
            { NULL, NULL, NULL },
            { NULL, NULL, NULL },
index bbe4cfb..8001b00 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: setrunelocale.c,v 1.4 2008/06/26 05:42:05 ray Exp $ */
+/*     $OpenBSD: setrunelocale.c,v 1.5 2010/07/27 16:59:04 stsp Exp $ */
 /*     $NetBSD: setrunelocale.c,v 1.14 2003/08/07 16:43:07 agc Exp $   */
 
 /*-
@@ -151,10 +151,11 @@ found:
 
        rl->rl_citrus_ctype = NULL;
 
-       if (strcmp(rl->rl_encoding, _CITRUS_DEFAULT_CTYPE_NAME) != 0) {
+       if (_citrus_ctype_open(&rl->rl_citrus_ctype, rl->rl_encoding)) {
                _NukeRune(rl);
                return EINVAL;
        }
+
        /* register it */
        lt = malloc(sizeof(struct localetable));
        if (lt == NULL) {
diff --git a/lib/libc/locale/wcscoll.c b/lib/libc/locale/wcscoll.c
new file mode 100644 (file)
index 0000000..6d47669
--- /dev/null
@@ -0,0 +1,43 @@
+/*     $OpenBSD: wcscoll.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+/*     $NetBSD: wcscoll.c,v 1.1 2003/03/02 22:18:16 tshiozak Exp $     */
+
+/*-
+ * Copyright (c)2003 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <assert.h>
+#include <wchar.h>
+
+/*
+ * Compare strings with using collating information.
+ */
+int
+wcscoll(const wchar_t *s1, const wchar_t *s2)
+{
+       /* XXX: LC_COLLATE should be implemented. */
+       return (wcscmp(s1, s2));
+}
diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c
new file mode 100644 (file)
index 0000000..024e3af
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: wcstombs.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+size_t
+wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
+{
+       mbstate_t mbs;
+       const wchar_t *pwcsp;
+
+       memset(&mbs, 0, sizeof(mbs));
+       pwcsp = pwcs;
+       return (wcsrtombs(s, &pwcsp, n, &mbs));
+}
diff --git a/lib/libc/locale/wcsxfrm.c b/lib/libc/locale/wcsxfrm.c
new file mode 100644 (file)
index 0000000..d2e9ff3
--- /dev/null
@@ -0,0 +1,43 @@
+/*     $OpenBSD: wcsxfrm.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+/*     $OpenBSD: wcsxfrm.c,v 1.1 2010/07/27 16:59:04 stsp Exp $        */
+/*     $NetBSD: multibyte_sb.c,v 1.4 2003/08/07 16:43:04 agc Exp $     */
+
+/*
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <wchar.h>
+
+size_t 
+wcsxfrm(wchar_t *dest, const wchar_t *src, size_t n)
+{
+       if (n == 0)
+               return wcslen(src);
+       return wcslcpy(dest, src, n);
+}
diff --git a/lib/libc/locale/wctob.c b/lib/libc/locale/wctob.c
new file mode 100644 (file)
index 0000000..cc5a07c
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: wctob.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+int
+wctob(wint_t c)
+{
+       mbstate_t mbs;
+       char buf[MB_LEN_MAX];
+
+       memset(&mbs, 0, sizeof(mbs));
+       if (c == WEOF || wcrtomb(buf, c, &mbs) != 1)
+               return (EOF);
+       return ((unsigned char)*buf);
+}
diff --git a/lib/libc/locale/wctomb.c b/lib/libc/locale/wctomb.c
new file mode 100644 (file)
index 0000000..9cd1ee4
--- /dev/null
@@ -0,0 +1,49 @@
+/*     $OpenBSD: wctomb.c,v 1.1 2010/07/27 16:59:04 stsp Exp $ */
+
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+int
+wctomb(char *s, wchar_t wchar)
+{
+       static mbstate_t mbs;
+       size_t rval;
+
+       if (s == NULL) {
+               /* No support for state dependent encodings. */
+               memset(&mbs, 0, sizeof(mbs));
+               return (0);
+       }
+       if ((rval = wcrtomb(s, wchar, &mbs)) == (size_t)-1)
+               return (-1);
+       return ((int)rval);
+}
index 47bf372..f600d75 100644 (file)
@@ -68,8 +68,8 @@ LOCALES += en_US.ISO8859-1
 LOCALES += en_US.ISO8859-15
  LOCALESRC_en_US.ISO8859-15 = en_US.DIS_8859-15
 
-#LOCALES += en_US.UTF-8
-# LOCALESRC_en_US.UTF-8 = en_US.UTF-8
+LOCALES += en_US.UTF-8
+ LOCALESRC_en_US.UTF-8 = en_US.UTF-8
 
 LOCALES += es_ES.ISO8859-1
  LOCALESRC_es_ES.ISO8859-1 = en_US.ISO_8859-1