tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [PATCH] Support for mbsnrtowcs and wcsnrtomb



On Wed, Apr 24, 2013 at 10:13:54AM +0900, SODA Noriyuki wrote:
> >>>>> On Sun, 21 Apr 2013 16:10:42 +0200,
>       Joerg Sonnenberger <joerg%britannica.bec.de@localhost> said:
> 
> > attached patch adds the POSIX2008 functions mbsnrtowcs and wcsnrtombs.
> > They differ from the non-n variant in the possibility of limiting the
> > input size.
> 
> Since nozaki-san is being sick this week (he couldn't go to his work
> Monday and Tuesday), and really busy for his real world job even
> without the sickness,  I'm writing what I've heard...

Best wishes for this recovery then.

> Accoridng to nozaki-san, this patch has several problems.
> One of most important problems is that this is not using the already
> existing mechanism to keep compatibility of encoding modules.

Fixed.

> Also, why don't you just use the already existing patch made by
> nozaki-san to implement this feature?
> ftp://ftp.netbsd.org/pub/NetBSD/misc/tnozaki/patch-mbsnrtowcs

Because it never made the list? I'm also not sure if it is really
correct, e.g. the (not) resetting of mbstate at the end of input.

Joerg
Index: include/wchar.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/wchar.h,v
retrieving revision 1.37
diff -u -p -r1.37 wchar.h
--- include/wchar.h     19 Apr 2013 23:45:15 -0000      1.37
+++ include/wchar.h     25 Apr 2013 14:00:44 -0000
@@ -212,6 +212,11 @@ typedef struct _locale             *locale_t;
 #  define __LOCALE_T_DECLARED
 #  endif
 __BEGIN_DECLS
+size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t,
+           size_t, mbstate_t * __restrict);
+size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t,
+           size_t, mbstate_t * __restrict);
+
 int    wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
 size_t wcsxfrm_l(wchar_t *, const wchar_t *, size_t, locale_t);
 int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
@@ -246,9 +251,13 @@ size_t     mbrtowc_l(wchar_t * __restrict, c
 int    mbsinit_l(const mbstate_t *, locale_t);
 size_t mbsrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t,
            mbstate_t * __restrict, locale_t);
+size_t mbsnrtowcs_l(wchar_t * __restrict, const char ** __restrict, size_t,
+           size_t, mbstate_t * __restrict, locale_t);
 size_t wcrtomb_l(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t);
 size_t wcsrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t,
            mbstate_t * __restrict, locale_t);
+size_t wcsnrtombs_l(char * __restrict, const wchar_t ** __restrict, size_t,
+           size_t, mbstate_t * __restrict, locale_t);
 int    wctob_l(wint_t, locale_t);
 
 int fwprintf_l(FILE * __restrict, locale_t, const wchar_t * __restrict, ...);
Index: lib/libc/citrus/citrus_ctype.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype.c,v
retrieving revision 1.6
diff -u -p -r1.6 citrus_ctype.c
--- lib/libc/citrus/citrus_ctype.c      19 Nov 2011 18:34:21 -0000      1.6
+++ lib/libc/citrus/citrus_ctype.c      25 Apr 2013 14:00:44 -0000
@@ -93,6 +93,8 @@ _initctypemodule(_citrus_ctype_t cc, cha
                /* FALLTHROUGH */
        case 0x00000002:
                /* FALLTHROUGH */
+               cc->cc_ops->co_mbsnrtowcs = &_citrus_ctype_mbsnrtowcs_fallback;
+               cc->cc_ops->co_wcsnrtombs = &_citrus_ctype_wcsnrtombs_fallback;
        default:
                break;
        }
@@ -106,10 +108,12 @@ _initctypemodule(_citrus_ctype_t cc, cha
            cc->cc_ops->co_mbrtowc == NULL ||
            cc->cc_ops->co_mbsinit == NULL ||
            cc->cc_ops->co_mbsrtowcs == NULL ||
+           cc->cc_ops->co_mbsnrtowcs == NULL ||
            cc->cc_ops->co_mbstowcs == NULL ||
            cc->cc_ops->co_mbtowc == NULL ||
            cc->cc_ops->co_wcrtomb == NULL ||
            cc->cc_ops->co_wcsrtombs == NULL ||
+           cc->cc_ops->co_wcsnrtombs == NULL ||
            cc->cc_ops->co_wcstombs == NULL ||
            cc->cc_ops->co_wctomb == NULL ||
            cc->cc_ops->co_btowc == NULL ||
Index: lib/libc/citrus/citrus_ctype.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype.h,v
retrieving revision 1.2
diff -u -p -r1.2 citrus_ctype.h
--- lib/libc/citrus/citrus_ctype.h      5 Mar 2003 20:18:15 -0000       1.2
+++ lib/libc/citrus/citrus_ctype.h      25 Apr 2013 16:36:53 -0000
@@ -95,6 +95,16 @@ _citrus_ctype_mbsrtowcs(_citrus_ctype_t 
 }
 
 static __inline int
+_citrus_ctype_mbsnrtowcs(_citrus_ctype_t cc, wchar_t *pwcs, const char **s,
+                       size_t in, size_t n, void *pspriv, size_t *nresult)
+{
+
+       _DIAGASSERT(cc && cc->cc_ops && cc->cc_ops->co_mbsnrtowcs && nresult);
+       return (*cc->cc_ops->co_mbsnrtowcs)(cc, pwcs, s, in, n,
+                                          pspriv, nresult);
+}
+
+static __inline int
 _citrus_ctype_mbstowcs(_citrus_ctype_t cc, wchar_t *pwcs, const char *s,
                       size_t n, size_t *nresult)
 {
@@ -133,6 +143,16 @@ _citrus_ctype_wcsrtombs(_citrus_ctype_t 
 }
 
 static __inline int
+_citrus_ctype_wcsnrtombs(_citrus_ctype_t cc, char *s, const wchar_t **ppwcs,
+                       size_t in, size_t n, void *pspriv, size_t *nresult)
+{
+
+       _DIAGASSERT(cc && cc->cc_ops && cc->cc_ops->co_wcsnrtombs && nresult);
+       return (*cc->cc_ops->co_wcsnrtombs)(cc, s, ppwcs, in, n,
+                                          pspriv, nresult);
+}
+
+static __inline int
 _citrus_ctype_wcstombs(_citrus_ctype_t cc, char *s, const wchar_t *wcs,
                       size_t n, size_t *nresult)
 {
Index: lib/libc/citrus/citrus_ctype_fallback.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype_fallback.c,v
retrieving revision 1.2
diff -u -p -r1.2 citrus_ctype_fallback.c
--- lib/libc/citrus/citrus_ctype_fallback.c     27 Jun 2003 14:52:25 -0000      
1.2
+++ lib/libc/citrus/citrus_ctype_fallback.c     25 Apr 2013 16:40:32 -0000
@@ -35,6 +35,7 @@ __RCSID("$NetBSD: citrus_ctype_fallback.
 
 #include <sys/types.h>
 #include <assert.h>
+#include <errno.h>
 #include <wchar.h>
 #include <stdio.h>
 #include <string.h>
@@ -108,3 +109,114 @@ _citrus_ctype_wctob_fallback(_citrus_cty
 
        return 0;
 }
+
+/*
+ * for ABI version >= 0x00000003
+ */ 
+int
+_citrus_ctype_mbsnrtowcs_fallback(_citrus_ctype_rec_t * __restrict cc,
+    wchar_t * __restrict pwcs, const char ** __restrict s, size_t in,
+    size_t n, void * __restrict psenc, size_t * __restrict nresult)
+{
+       int err;
+       size_t cnt, siz;
+       const char *s0, *se;
+
+       _DIAGASSERT(nresult != 0);
+       _DIAGASSERT(psenc != NULL);
+       _DIAGASSERT(s == NULL);
+       _DIAGASSERT(*s == NULL);
+
+       /* if pwcs is NULL, ignore n */
+       if (pwcs == NULL)
+               n = 1; /* arbitrary >0 value */
+
+       err = 0;
+       cnt = 0;
+       se = *s + in;
+       s0 = *s; /* to keep *s unchanged for now, use copy instead. */
+       while (s0 < se && n > 0) {
+               err = _citrus_ctype_mbrtowc(cc, pwcs, s0, (size_t)(se - s0),
+                   psenc, &siz);
+               if (siz == (size_t)-2)
+                       err = EILSEQ;
+               if (err) {
+                       cnt = (size_t)-1;
+                       goto bye;
+               }
+               switch (siz) {
+               case 0:
+                       if (pwcs)
+                               memset(psenc, 0, sizeof(mbstate_t));
+                       s0 = 0;
+                       goto bye;
+               default:
+                       if (pwcs) {
+                               pwcs++;
+                               n--;
+                       }
+                       cnt++;
+                       break;
+               }
+       }
+bye:
+       if (pwcs)
+               *s = s0;
+
+       *nresult = cnt;
+
+       return err;
+}
+
+int
+_citrus_ctype_wcsnrtombs_fallback(_citrus_ctype_rec_t * __restrict cc,
+    char * __restrict s, const wchar_t ** __restrict pwcs, size_t in,
+    size_t n, void * __restrict psenc, size_t * __restrict nresult)
+{
+       size_t cnt = 0;
+       int err;
+       char buf[MB_LEN_MAX];
+       size_t siz;
+       const wchar_t* pwcs0;
+       mbstate_t state;
+
+       pwcs0 = *pwcs;
+
+       if (!s)
+               n = 1;
+
+       while (in > 0 && n > 0) {
+               memcpy(&state, psenc, sizeof(state));
+               err = _citrus_ctype_wcrtomb(cc, buf, *pwcs0, psenc, &siz);
+               if (siz == (size_t)-1) {
+                       *nresult = siz;
+                       return (err);
+               }
+
+               if (s) {
+                       if (n < siz) {
+                               memcpy(psenc, &state, sizeof(state));
+                               break;
+                       }
+                       memcpy(s, buf, siz);
+                       s += siz;
+                       n -= siz;
+               }
+               cnt += siz;
+               if (!*pwcs0) {
+                       if (s) {
+                               memset(psenc, 0, sizeof(state));
+                       }
+                       pwcs0 = 0;
+                       cnt--; /* don't include terminating null */
+                       break;
+               }
+               pwcs0++;
+               --in;
+       }
+       if (s)
+               *pwcs = pwcs0;
+
+       *nresult = cnt;
+       return (0);
+}
Index: lib/libc/citrus/citrus_ctype_fallback.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype_fallback.h,v
retrieving revision 1.1
diff -u -p -r1.1 citrus_ctype_fallback.h
--- lib/libc/citrus/citrus_ctype_fallback.h     5 Mar 2003 20:18:15 -0000       
1.1
+++ lib/libc/citrus/citrus_ctype_fallback.h     25 Apr 2013 16:40:36 -0000
@@ -35,4 +35,16 @@ int _citrus_ctype_btowc_fallback(_citrus
 int _citrus_ctype_wctob_fallback(_citrus_ctype_rec_t * __restrict,
                                 wint_t, int * __restrict);
 
+/* fallback functions for 0x00000003 */
+int _citrus_ctype_mbsnrtowcs_fallback(_citrus_ctype_rec_t * __restrict,
+                                     wchar_t * __restrict,
+                                     const char ** __restrict, size_t,
+                                     size_t, void * __restrict,
+                                     size_t * __restrict);
+int _citrus_ctype_wcsnrtombs_fallback(_citrus_ctype_rec_t * __restrict,
+                                    char * __restrict,
+                                    const wchar_t ** __restrict, size_t,
+                                    size_t, void * __restrict,
+                                    size_t * __restrict);
+
 #endif
Index: lib/libc/citrus/citrus_ctype_local.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype_local.h,v
retrieving revision 1.3
diff -u -p -r1.3 citrus_ctype_local.h
--- lib/libc/citrus/citrus_ctype_local.h        9 Feb 2008 14:56:20 -0000       
1.3
+++ lib/libc/citrus/citrus_ctype_local.h        25 Apr 2013 17:37:00 -0000
@@ -60,6 +60,11 @@ static int   _citrus_##_e_##_ctype_mbsrtow
                                         const char ** __restrict,            \
                                         size_t, void * __restrict,           \
                                         size_t * __restrict);                \
+static int     _citrus_##_e_##_ctype_mbsnrtowcs(_citrus_ctype_rec_t * 
__restrict, \
+                                        wchar_t * __restrict,                \
+                                        const char ** __restrict,            \
+                                        size_t, size_t, void * __restrict,   \
+                                        size_t * __restrict);                \
 static int     _citrus_##_e_##_ctype_mbstowcs(void * __restrict,             \
                                        wchar_t * __restrict,                 \
                                        const char * __restrict,              \
@@ -77,6 +82,11 @@ static int   _citrus_##_e_##_ctype_wcsrtom
                                         const wchar_t ** __restrict,         \
                                         size_t, void * __restrict,           \
                                         size_t * __restrict);                \
+static int     _citrus_##_e_##_ctype_wcsnrtombs(_citrus_ctype_rec_t * 
__restrict, \
+                                        char * __restrict,                   \
+                                        const wchar_t ** __restrict,         \
+                                        size_t, size_t, void * __restrict,   \
+                                        size_t * __restrict);                \
 static int     _citrus_##_e_##_ctype_wcstombs(void * __restrict,             \
                                        char * __restrict,                    \
                                        const wchar_t * __restrict,           \
@@ -107,7 +117,9 @@ _citrus_ctype_ops_rec_t _citrus_##_e_##_
        /* co_wcstombs */       &_citrus_##_e_##_ctype_wcstombs,        \
        /* co_wctomb */         &_citrus_##_e_##_ctype_wctomb,          \
        /* co_btowc */          &_citrus_##_e_##_ctype_btowc,           \
-       /* co_wctob */          &_citrus_##_e_##_ctype_wctob            \
+       /* co_wctob */          &_citrus_##_e_##_ctype_wctob,           \
+       /* co_mbsnrtowcs */     &_citrus_##_e_##_ctype_mbsnrtowcs,      \
+       /* co_wcsnrtombs */     &_citrus_##_e_##_ctype_wcsnrtombs,      \
 }
 
 typedef struct _citrus_ctype_ops_rec   _citrus_ctype_ops_rec_t;
@@ -129,7 +141,10 @@ typedef int        (*_citrus_ctype_mbsinit_t)
        (void * __restrict, const void * __restrict, int * __restrict);
 typedef int    (*_citrus_ctype_mbsrtowcs_t)
        (void * __restrict, wchar_t * __restrict, const char ** __restrict,
-        size_t, void * __restrict,
+        size_t, void * __restrict, size_t * __restrict);
+typedef int    (*_citrus_ctype_mbsnrtowcs_t)
+       (_citrus_ctype_rec_t * __restrict, wchar_t * __restrict,
+        const char ** __restrict, size_t, size_t, void * __restrict,
         size_t * __restrict);
 typedef int    (*_citrus_ctype_mbstowcs_t)
        (void * __restrict, wchar_t * __restrict, const char * __restrict,
@@ -143,6 +158,10 @@ typedef int        (*_citrus_ctype_wcrtomb_t)
 typedef int    (*_citrus_ctype_wcsrtombs_t)
        (void * __restrict, char * __restrict, const wchar_t ** __restrict,
         size_t, void * __restrict, size_t * __restrict);
+typedef int    (*_citrus_ctype_wcsnrtombs_t)
+       (_citrus_ctype_rec_t * __restrict, char * __restrict,
+        const wchar_t ** __restrict, size_t, size_t, void * __restrict,
+        size_t * __restrict);
 typedef int    (*_citrus_ctype_wcstombs_t)
        (void * __restrict, char * __restrict, const wchar_t * __restrict,
         size_t, size_t * __restrict);
@@ -152,13 +171,17 @@ typedef int       (*_citrus_ctype_btowc_t)
        (_citrus_ctype_rec_t * __restrict, int, wint_t * __restrict);
 typedef int    (*_citrus_ctype_wctob_t)
        (_citrus_ctype_rec_t * __restrict, wint_t, int * __restrict);
+#include "citrus_ctype_fallback.h"
 
 /*
  * ABI Version change log:
  *   0x00000001
  *     initial version
  *   0x00000002
- *     ops record:     btowc and wctob are added.
+ *     ops record:     btowc and wctob added.
+ *     ctype record:   unchanged.
+ *   0x00000003
+ *     ops record:     mbsnrtowcs and wcsnrtombs added.
  *     ctype record:   unchanged.
  */
 #define _CITRUS_CTYPE_ABI_VERSION      0x00000002
@@ -182,6 +205,9 @@ struct _citrus_ctype_ops_rec {
        /* version 0x00000002 */
        _citrus_ctype_btowc_t           co_btowc;
        _citrus_ctype_wctob_t           co_wctob;
+       /* version 0x00000003 */
+       _citrus_ctype_mbsnrtowcs_t      co_mbsnrtowcs;
+       _citrus_ctype_wcsnrtombs_t      co_wcsnrtombs;
 };
 
 #define _CITRUS_DEFAULT_CTYPE_NAME     "NONE"
Index: lib/libc/citrus/citrus_ctype_template.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_ctype_template.h,v
retrieving revision 1.35
diff -u -p -r1.35 citrus_ctype_template.h
--- lib/libc/citrus/citrus_ctype_template.h     9 Feb 2008 14:56:20 -0000       
1.35
+++ lib/libc/citrus/citrus_ctype_template.h     25 Apr 2013 16:39:46 -0000
@@ -85,8 +85,10 @@
  *           mbrtowc
  *           mbtowc
  *           mbsrtowcs
+ *           mbsnrtowcs
  *           wcrtomb
  *           wcsrtombs
+ *           wcsnrtombs
  *           wctomb
  *     These need to be keeped in the ctype encoding information structure,
  *     pointed by "cei".
@@ -282,6 +284,64 @@ bye:
        return err;
 }
 
+static int
+_FUNCNAME(mbsnrtowcs_priv)(_ENCODING_INFO * __restrict ei,
+                         wchar_t * __restrict pwcs,
+                         const char ** __restrict s, size_t in,
+                         size_t n, _ENCODING_STATE * __restrict psenc,
+                         size_t * __restrict nresult)
+{
+       int err;
+       size_t cnt, siz;
+       const char *s0, *se;
+
+       _DIAGASSERT(nresult != 0);
+       _DIAGASSERT(ei != NULL);
+       _DIAGASSERT(psenc != NULL);
+       _DIAGASSERT(s == NULL);
+       _DIAGASSERT(*s == NULL);
+
+       /* if pwcs is NULL, ignore n */
+       if (pwcs == NULL)
+               n = 1; /* arbitrary >0 value */
+
+       err = 0;
+       cnt = 0;
+       se = *s + in;
+       s0 = *s; /* to keep *s unchanged for now, use copy instead. */
+       while (s0 < se && n > 0) {
+               err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, se - s0,
+                                             psenc, &siz);
+               if (siz == (size_t)-2)
+                       err = EILSEQ;
+               if (err) {
+                       cnt = (size_t)-1;
+                       goto bye;
+               }
+               switch (siz) {
+               case 0:
+                       if (pwcs) {
+                               _FUNCNAME(init_state)(ei, psenc);
+                       }
+                       s0 = 0;
+                       goto bye;
+               default:
+                       if (pwcs) {
+                               pwcs++;
+                               n--;
+                       }
+                       cnt++;
+                       break;
+               }
+       }
+bye:
+       if (pwcs)
+               *s = s0;
+
+       *nresult = cnt;
+
+       return err;
+}
 
 static int
 _FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO * __restrict ei, char * __restrict s,
@@ -289,6 +349,66 @@ _FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO
                          size_t n, _ENCODING_STATE * __restrict psenc,
                          size_t * __restrict nresult)
 {
+       int err;
+       char buf[MB_LEN_MAX];
+       size_t cnt, siz;
+       const wchar_t* pwcs0;
+#if _ENCODING_IS_STATE_DEPENDENT
+       _ENCODING_STATE state;
+#endif
+
+       pwcs0 = *pwcs;
+
+       cnt = 0;
+       if (!s)
+               n = 1;
+
+       while (n > 0) {
+#if _ENCODING_IS_STATE_DEPENDENT
+               state = *psenc;
+#endif
+               err = _FUNCNAME(wcrtomb_priv)(ei, buf, sizeof(buf),
+                                             *pwcs0, psenc, &siz);
+               if (siz == (size_t)-1) {
+                       *nresult = siz;
+                       return (err);
+               }
+
+               if (s) {
+                       if (n < siz) {
+#if _ENCODING_IS_STATE_DEPENDENT
+                               *psenc = state;
+#endif
+                               break;
+                       }
+                       memcpy(s, buf, siz);
+                       s += siz;
+                       n -= siz;
+               }
+               cnt += siz;
+               if (!*pwcs0) {
+                       if (s) {
+                               _FUNCNAME(init_state)(ei, psenc);
+                       }
+                       pwcs0 = 0;
+                       cnt--; /* don't include terminating null */
+                       break;
+               }
+               pwcs0++;
+       }
+       if (s)
+               *pwcs = pwcs0;
+
+       *nresult = cnt;
+       return (0);
+}
+
+static int
+_FUNCNAME(wcsnrtombs_priv)(_ENCODING_INFO * __restrict ei, char * __restrict s,
+                         const wchar_t ** __restrict pwcs, size_t in,
+                         size_t n, _ENCODING_STATE * __restrict psenc,
+                         size_t * __restrict nresult)
+{
        int cnt = 0, err;
        char buf[MB_LEN_MAX];
        size_t siz;
@@ -302,7 +422,7 @@ _FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO
        if (!s)
                n = 1;
 
-       while (n > 0) {
+       while (in > 0 && n > 0) {
 #if _ENCODING_IS_STATE_DEPENDENT
                state = *psenc;
 #endif
@@ -334,6 +454,7 @@ _FUNCNAME(wcsrtombs_priv)(_ENCODING_INFO
                        break;
                }
                pwcs0++;
+               --in;
        }
        if (s)
                *pwcs = pwcs0;
@@ -525,6 +646,27 @@ _FUNCNAME(ctype_mbsrtowcs)(void * __rest
        return (err);
 }
 
+static int __used
+_FUNCNAME(ctype_mbsnrtowcs)(_citrus_ctype_rec_t * __restrict cc, wchar_t * 
__restrict pwcs,
+                          const char ** __restrict s, size_t in, size_t n,
+                          void * __restrict pspriv,
+                          size_t * __restrict nresult)
+{
+       void *cl = cc->cc_closure;
+       _ENCODING_STATE *psenc;
+       _ENCODING_INFO *ei;
+       int err = 0;
+
+       _DIAGASSERT(cl != NULL);
+
+       ei = _CEI_TO_EI(_TO_CEI(cl));
+       _RESTART_BEGIN(mbsnrtowcs, _TO_CEI(cl), pspriv, psenc);
+       err = _FUNCNAME(mbsnrtowcs_priv)(ei, pwcs, s, in, n, psenc, nresult);
+       _RESTART_END(mbsnrtowcs, _TO_CEI(cl), pspriv, psenc);
+
+       return (err);
+}
+
 static int
 _FUNCNAME(ctype_mbstowcs)(void * __restrict cl, wchar_t * __restrict pwcs,
                          const char * __restrict s, size_t n,
@@ -637,6 +779,29 @@ _FUNCNAME(ctype_wcsrtombs)(void * __rest
        return err;
 }
 
+static int __used
+/*ARGSUSED*/
+_FUNCNAME(ctype_wcsnrtombs)(_citrus_ctype_rec_t * __restrict cc,
+                          char * __restrict s,
+                          const wchar_t ** __restrict pwcs, size_t in,
+                          size_t n, void * __restrict pspriv,
+                          size_t * __restrict nresult)
+{
+       void *cl = cc->cc_closure;
+       _ENCODING_STATE *psenc;
+       _ENCODING_INFO *ei;
+       int err = 0;
+
+       _DIAGASSERT(cl != NULL);
+
+       ei = _CEI_TO_EI(_TO_CEI(cl));
+       _RESTART_BEGIN(wcsnrtombs, _TO_CEI(cl), pspriv, psenc);
+       err = _FUNCNAME(wcsnrtombs_priv)(ei, s, pwcs, in, n, psenc, nresult);
+       _RESTART_END(wcsnrtombs, _TO_CEI(cl), pspriv, psenc);
+
+       return err;
+}
+
 static int
 /*ARGSUSED*/
 _FUNCNAME(ctype_wcstombs)(void * __restrict cl, char * __restrict s,
Index: lib/libc/citrus/citrus_none.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/citrus_none.c,v
retrieving revision 1.18
diff -u -p -r1.18 citrus_none.c
--- lib/libc/citrus/citrus_none.c       14 Jun 2008 16:01:07 -0000      1.18
+++ lib/libc/citrus/citrus_none.c       25 Apr 2013 17:37:40 -0000
@@ -185,6 +185,47 @@ _citrus_NONE_ctype_mbsrtowcs(void * __re
 }
 
 static int
+/*ARGSUSED*/
+_citrus_NONE_ctype_mbsnrtowcs(_citrus_ctype_rec_t * __restrict cc,
+                            wchar_t * __restrict pwcs,
+                            const char ** __restrict s, size_t in, size_t n,
+                            void * __restrict pspriv,
+                            size_t * __restrict nresult)
+{
+       int cnt;
+       const char *s0;
+
+       /* if pwcs is NULL, ignore n */
+       if (pwcs == NULL)
+               n = 1; /* arbitrary >0 value */
+
+       cnt = 0;
+       s0 = *s; /* to keep *s unchanged for now, use copy instead. */
+       while (in > 0 && n > 0) {
+               if (pwcs != NULL) {
+                       *pwcs = (wchar_t)(unsigned char)*s0;
+               }
+               if (*s0 == '\0') {
+                       s0 = NULL;
+                       break;
+               }
+               s0++;
+               --in;
+               if (pwcs != NULL) {
+                       pwcs++;
+                       n--;
+               }
+               cnt++;
+       }
+       if (pwcs)
+               *s = s0;
+
+       *nresult = (size_t)cnt;
+
+       return (0);
+}
+
+static int
 _citrus_NONE_ctype_mbstowcs(void * __restrict cl, wchar_t * __restrict wcs,
                            const char * __restrict s, size_t n,
                            size_t * __restrict nresult)
@@ -282,6 +323,48 @@ _citrus_NONE_ctype_wcsrtombs(void * __re
 }
 
 static int
+/*ARGSUSED*/
+_citrus_NONE_ctype_wcsnrtombs(_citrus_ctype_rec_t * __restrict cc,
+                            char * __restrict s,
+                            const wchar_t ** __restrict pwcs, size_t in,
+                            size_t n, void * __restrict pspriv,
+                            size_t * __restrict nresult)
+{
+       size_t count;
+       const wchar_t *pwcs0;
+
+       pwcs0 = *pwcs;
+       count = 0;
+
+       if (s == NULL)
+               n = 1;
+
+       while (in > 0 && n > 0) {
+               if ((*pwcs0 & ~0xFFU) != 0) {
+                       *nresult = (size_t)-1;
+                       return (EILSEQ);
+               }
+               if (s != NULL) {
+                       *s++ = (char)*pwcs0;
+                       n--;
+               }
+               if (*pwcs0 == L'\0') {
+                       pwcs0 = NULL;
+                       break;
+               }
+               count++;
+               pwcs0++;
+               --in;
+       }
+       if (s != NULL)
+               *pwcs = pwcs0;
+
+       *nresult = count;
+
+       return (0);
+}
+
+static int
 _citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s,
                            const wchar_t * __restrict pwcs, size_t n,
                            size_t * __restrict nresult)
Index: lib/libc/citrus/modules/citrus_big5.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_big5.c,v
retrieving revision 1.13
diff -u -p -r1.13 citrus_big5.c
--- lib/libc/citrus/modules/citrus_big5.c       23 May 2011 14:53:46 -0000      
1.13
+++ lib/libc/citrus/modules/citrus_big5.c       25 Apr 2013 14:00:44 -0000
@@ -115,8 +115,10 @@ typedef struct {
                _BIG5State      s_mbrtowc;
                _BIG5State      s_mbtowc;
                _BIG5State      s_mbsrtowcs;
+               _BIG5State      s_mbsnrtowcs;
                _BIG5State      s_wcrtomb;
                _BIG5State      s_wcsrtombs;
+               _BIG5State      s_wcsnrtombs;
                _BIG5State      s_wctomb;
        } states;
 } _BIG5CTypeInfo;
Index: lib/libc/citrus/modules/citrus_dechanyu.c
===================================================================
RCS file: 
/home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_dechanyu.c,v
retrieving revision 1.4
diff -u -p -r1.4 citrus_dechanyu.c
--- lib/libc/citrus/modules/citrus_dechanyu.c   19 Nov 2011 18:20:13 -0000      
1.4
+++ lib/libc/citrus/modules/citrus_dechanyu.c   25 Apr 2013 14:00:44 -0000
@@ -71,8 +71,10 @@ typedef struct {
                _DECHanyuState  s_mbrtowc;
                _DECHanyuState  s_mbtowc;
                _DECHanyuState  s_mbsrtowcs;
+               _DECHanyuState  s_mbsnrtowcs;
                _DECHanyuState  s_wcrtomb;
                _DECHanyuState  s_wcsrtombs;
+               _DECHanyuState  s_wcsnrtombs;
                _DECHanyuState  s_wctomb;
        } states;
 } _DECHanyuCTypeInfo;
Index: lib/libc/citrus/modules/citrus_euc.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_euc.c,v
retrieving revision 1.14
diff -u -p -r1.14 citrus_euc.c
--- lib/libc/citrus/modules/citrus_euc.c        11 Jan 2009 02:46:24 -0000      
1.14
+++ lib/libc/citrus/modules/citrus_euc.c        25 Apr 2013 14:00:44 -0000
@@ -107,8 +107,10 @@ typedef struct {
                _EUCState       s_mbrtowc;
                _EUCState       s_mbtowc;
                _EUCState       s_mbsrtowcs;
+               _EUCState       s_mbsnrtowcs;
                _EUCState       s_wcrtomb;
                _EUCState       s_wcsrtombs;
+               _EUCState       s_wcsnrtombs;
                _EUCState       s_wctomb;
        } states;
 } _EUCCTypeInfo;
Index: lib/libc/citrus/modules/citrus_euctw.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_euctw.c,v
retrieving revision 1.11
diff -u -p -r1.11 citrus_euctw.c
--- lib/libc/citrus/modules/citrus_euctw.c      14 Jun 2008 16:01:07 -0000      
1.11
+++ lib/libc/citrus/modules/citrus_euctw.c      25 Apr 2013 14:00:44 -0000
@@ -98,8 +98,10 @@ typedef struct {
                _EUCTWState     s_mbrtowc;
                _EUCTWState     s_mbtowc;
                _EUCTWState     s_mbsrtowcs;
+               _EUCTWState     s_mbsnrtowcs;
                _EUCTWState     s_wcrtomb;
                _EUCTWState     s_wcsrtombs;
+               _EUCTWState     s_wcsnrtombs;
                _EUCTWState     s_wctomb;
        } states;
 } _EUCTWCTypeInfo;
Index: lib/libc/citrus/modules/citrus_gbk2k.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_gbk2k.c,v
retrieving revision 1.7
diff -u -p -r1.7 citrus_gbk2k.c
--- lib/libc/citrus/modules/citrus_gbk2k.c      14 Jun 2008 16:01:07 -0000      
1.7
+++ lib/libc/citrus/modules/citrus_gbk2k.c      25 Apr 2013 14:00:44 -0000
@@ -72,8 +72,10 @@ typedef struct {
                _GBK2KState     s_mbrtowc;
                _GBK2KState     s_mbtowc;
                _GBK2KState     s_mbsrtowcs;
+               _GBK2KState     s_mbsnrtowcs;
                _GBK2KState     s_wcrtomb;
                _GBK2KState     s_wcsrtombs;
+               _GBK2KState     s_wcsnrtombs;
                _GBK2KState     s_wctomb;
        } states;
 } _GBK2KCTypeInfo;
Index: lib/libc/citrus/modules/citrus_hz.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_hz.c,v
retrieving revision 1.2
diff -u -p -r1.2 citrus_hz.c
--- lib/libc/citrus/modules/citrus_hz.c 14 Jun 2008 16:01:07 -0000      1.2
+++ lib/libc/citrus/modules/citrus_hz.c 25 Apr 2013 14:00:44 -0000
@@ -143,8 +143,10 @@ typedef struct {
                _HZState        s_mbrtowc;
                _HZState        s_mbtowc;
                _HZState        s_mbsrtowcs;
+               _HZState        s_mbsnrtowcs;
                _HZState        s_wcrtomb;
                _HZState        s_wcsrtombs;
+               _HZState        s_wcsnrtombs;
                _HZState        s_wctomb;
        } states;
 } _HZCTypeInfo;
Index: lib/libc/citrus/modules/citrus_iso2022.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_iso2022.c,v
retrieving revision 1.22
diff -u -p -r1.22 citrus_iso2022.c
--- lib/libc/citrus/modules/citrus_iso2022.c    10 Oct 2011 22:45:45 -0000      
1.22
+++ lib/libc/citrus/modules/citrus_iso2022.c    25 Apr 2013 14:00:44 -0000
@@ -133,8 +133,10 @@ typedef struct {
                _ISO2022State   s_mbrtowc;
                _ISO2022State   s_mbtowc;
                _ISO2022State   s_mbsrtowcs;
+               _ISO2022State   s_mbsnrtowcs;
                _ISO2022State   s_wcrtomb;
                _ISO2022State   s_wcsrtombs;
+               _ISO2022State   s_wcsnrtombs;
                _ISO2022State   s_wctomb;
        } states;
 } _ISO2022CTypeInfo;
Index: lib/libc/citrus/modules/citrus_johab.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_johab.c,v
retrieving revision 1.4
diff -u -p -r1.4 citrus_johab.c
--- lib/libc/citrus/modules/citrus_johab.c      14 Jun 2008 16:01:07 -0000      
1.4
+++ lib/libc/citrus/modules/citrus_johab.c      25 Apr 2013 14:00:44 -0000
@@ -71,8 +71,10 @@ typedef struct {
                _JOHABState     s_mbrtowc;
                _JOHABState     s_mbtowc;
                _JOHABState     s_mbsrtowcs;
+               _JOHABState     s_mbsnrtowcs;
                _JOHABState     s_wcrtomb;
                _JOHABState     s_wcsrtombs;
+               _JOHABState     s_wcsnrtombs;
                _JOHABState     s_wctomb;
        } states;
 } _JOHABCTypeInfo;
Index: lib/libc/citrus/modules/citrus_mskanji.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_mskanji.c,v
retrieving revision 1.13
diff -u -p -r1.13 citrus_mskanji.c
--- lib/libc/citrus/modules/citrus_mskanji.c    14 Jun 2008 16:01:08 -0000      
1.13
+++ lib/libc/citrus/modules/citrus_mskanji.c    25 Apr 2013 14:00:44 -0000
@@ -107,8 +107,10 @@ typedef struct {
                _MSKanjiState   s_mbrtowc;
                _MSKanjiState   s_mbtowc;
                _MSKanjiState   s_mbsrtowcs;
+               _MSKanjiState   s_mbsnrtowcs;
                _MSKanjiState   s_wcrtomb;
                _MSKanjiState   s_wcsrtombs;
+               _MSKanjiState   s_wcsnrtombs;
                _MSKanjiState   s_wctomb;
        } states;
 } _MSKanjiCTypeInfo;
Index: lib/libc/citrus/modules/citrus_ues.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_ues.c,v
retrieving revision 1.3
diff -u -p -r1.3 citrus_ues.c
--- lib/libc/citrus/modules/citrus_ues.c        12 Feb 2012 13:51:29 -0000      
1.3
+++ lib/libc/citrus/modules/citrus_ues.c        25 Apr 2013 14:00:44 -0000
@@ -68,8 +68,10 @@ typedef struct {
                _UESState       s_mbrtowc;
                _UESState       s_mbtowc;
                _UESState       s_mbsrtowcs;
+               _UESState       s_mbsnrtowcs;
                _UESState       s_wcrtomb;
                _UESState       s_wcsrtombs;
+               _UESState       s_wcsnrtombs;
                _UESState       s_wctomb;
        } states;
 } _UESCTypeInfo;
Index: lib/libc/citrus/modules/citrus_utf7.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_utf7.c,v
retrieving revision 1.5
diff -u -p -r1.5 citrus_utf7.c
--- lib/libc/citrus/modules/citrus_utf7.c       23 Aug 2006 12:57:24 -0000      
1.5
+++ lib/libc/citrus/modules/citrus_utf7.c       25 Apr 2013 14:00:44 -0000
@@ -79,8 +79,10 @@ typedef struct {
                _UTF7State      s_mbrtowc;
                _UTF7State      s_mbtowc;
                _UTF7State      s_mbsrtowcs;
+               _UTF7State      s_mbsnrtowcs;
                _UTF7State      s_wcrtomb;
                _UTF7State      s_wcsrtombs;
+               _UTF7State      s_wcsnrtombs;
                _UTF7State      s_wctomb;
        } states;
 } _UTF7CTypeInfo;
Index: lib/libc/citrus/modules/citrus_utf8.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_utf8.c,v
retrieving revision 1.17
diff -u -p -r1.17 citrus_utf8.c
--- lib/libc/citrus/modules/citrus_utf8.c       14 Jun 2008 16:01:08 -0000      
1.17
+++ lib/libc/citrus/modules/citrus_utf8.c       25 Apr 2013 14:00:44 -0000
@@ -111,8 +111,10 @@ typedef struct {
                _UTF8State      s_mbrtowc;
                _UTF8State      s_mbtowc;
                _UTF8State      s_mbsrtowcs;
+               _UTF8State      s_mbsnrtowcs;
                _UTF8State      s_wcrtomb;
                _UTF8State      s_wcsrtombs;
+               _UTF8State      s_wcsnrtombs;
                _UTF8State      s_wctomb;
        } states;
 } _UTF8CTypeInfo;
Index: lib/libc/citrus/modules/citrus_viqr.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_viqr.c,v
retrieving revision 1.5
diff -u -p -r1.5 citrus_viqr.c
--- lib/libc/citrus/modules/citrus_viqr.c       19 Nov 2011 18:20:13 -0000      
1.5
+++ lib/libc/citrus/modules/citrus_viqr.c       25 Apr 2013 14:00:44 -0000
@@ -234,8 +234,10 @@ typedef struct {
                _VIQRState      s_mbrtowc;
                _VIQRState      s_mbtowc;
                _VIQRState      s_mbsrtowcs;
+               _VIQRState      s_mbsnrtowcs;
                _VIQRState      s_wcrtomb;
                _VIQRState      s_wcsrtombs;
+               _VIQRState      s_wcsnrtombs;
                _VIQRState      s_wctomb;
        } states;
 } _VIQRCTypeInfo;
Index: lib/libc/citrus/modules/citrus_zw.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/citrus/modules/citrus_zw.c,v
retrieving revision 1.4
diff -u -p -r1.4 citrus_zw.c
--- lib/libc/citrus/modules/citrus_zw.c 14 Jun 2008 16:01:08 -0000      1.4
+++ lib/libc/citrus/modules/citrus_zw.c 25 Apr 2013 14:00:44 -0000
@@ -77,8 +77,10 @@ typedef struct {
                _ZWState        s_mbrtowc;
                _ZWState        s_mbtowc;
                _ZWState        s_mbsrtowcs;
+               _ZWState        s_mbsnrtowcs;
                _ZWState        s_wcrtomb;
                _ZWState        s_wcsrtombs;
+               _ZWState        s_wcsnrtombs;
                _ZWState        s_wctomb;
        } states;
 } _ZWCTypeInfo;
Index: lib/libc/locale/multibyte_amd1.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/locale/multibyte_amd1.c,v
retrieving revision 1.11
diff -u -p -r1.11 multibyte_amd1.c
--- lib/libc/locale/multibyte_amd1.c    19 Apr 2013 14:35:33 -0000      1.11
+++ lib/libc/locale/multibyte_amd1.c    25 Apr 2013 14:21:09 -0000
@@ -163,6 +163,32 @@ mbsrtowcs(wchar_t *pwcs, const char **s,
 }
 
 size_t
+mbsnrtowcs_l(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps,
+    locale_t loc)
+{
+       size_t ret;
+       int err0;
+
+       if (loc == NULL)
+               loc = _C_locale;
+
+       _fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
+
+       err0 = _citrus_ctype_mbsnrtowcs(_ps_to_ctype(ps), pwcs, s, in, n,
+                                       _ps_to_private(ps), &ret);
+       if (err0)
+               errno = err0;
+
+       return ret;
+}
+
+size_t
+mbsnrtowcs(wchar_t *pwcs, const char **s, size_t in, size_t n, mbstate_t *ps)
+{
+       return mbsnrtowcs_l(pwcs, s, in, n, ps, *_current_locale());
+}
+
+size_t
 wcrtomb_l(char *s, wchar_t wc, mbstate_t *ps, locale_t loc)
 {
        size_t ret;
@@ -213,6 +239,32 @@ wcsrtombs(char *s, const wchar_t **ppwcs
        return wcsrtombs_l(s, ppwcs, n, ps, *_current_locale());
 }
 
+size_t
+wcsnrtombs_l(char *s, const wchar_t **ppwcs, size_t in, size_t n, mbstate_t 
*ps,
+    locale_t loc)
+{
+       size_t ret;
+       int err0;
+
+       if (loc == NULL)
+               loc = _C_locale;
+
+       _fixup_ps(_RUNE_LOCALE(loc), ps, s == NULL);
+
+       err0 = _citrus_ctype_wcsnrtombs(_ps_to_ctype(ps), s, ppwcs, in, n,
+                                       _ps_to_private(ps), &ret);
+       if (err0)
+               errno = err0;
+
+       return ret;
+}
+
+size_t
+wcsnrtombs(char *s, const wchar_t **ppwcs, size_t in, size_t n, mbstate_t *ps)
+{
+       return wcsnrtombs_l(s, ppwcs, in, n, ps, *_current_locale());
+}
+
 wint_t
 btowc_l(int c, locale_t loc)
 {


Home | Main Index | Thread Index | Old Index