tech-userlevel archive

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

Re: [PATCH] Support for mbsnrtowcs and wcsnrtomb



Hi!

Joerg Sonnenberger wrote:
> ...and now a version that passes extensive testing for the fallback as
> well...


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 18:41:44 -0000
@@ -108,3 +109,115 @@ _citrus_ctype_wctob_fallback(_citrus_cty
[...]

+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)
[...]
+       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;

How can this be correct?

if mbrtowc returns -2, it means there is not enough characters
(remaining in the buffer) to complete a conversion; however this is not
an error condition (yet); and clearly there is no "illegal sequence". In
such a case, mbs[n]rtowcs should stop at this point, leaving the rest of
the string for a further ("restartable") call; this is achieved by
returning *s=s0, i.e. updating the passed-in pointer to point to the
still-to-convert string; in other words, just
                        goto bye;
does the job here.

+               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--;
+                       }
+                       s0 += siz;
+                       cnt++;
+                       break;
+               }
+       }
+bye:
+       if (pwcs)
+               *s = s0;
+
+       *nresult = cnt;
+
+       return err;
+}

/* ... */

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
@@ -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)
[...]
+       while (s0 < se && n > 0) {
+               err = _FUNCNAME(mbrtowc_priv)(ei, pwcs, &s0, se - s0,
+                                             psenc, &siz);
+               if (siz == (size_t)-2)
+                       err = EILSEQ;

Same here.


Antoine


Home | Main Index | Thread Index | Old Index