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,

SODA Noriyuki wrote:
> 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

Sorry for the bad format (my mailer will reformat the lines); I hope it
will still be clear

diff -uNrBw libc.orig/citrus/citrus_ctype_fallback.c
libc/citrus/citrus_ctype_fallback.c
--- libc.orig/citrus/citrus_ctype_fallback.c    2003-06-27
23:52:25.000000000 +0900
+++ libc/citrus/citrus_ctype_fallback.c 2010-11-20 23:00:22.000000000 +0900
[...]
@@ -108,3 +105,107 @@
[...]
+_citrus_ctype_mbsnrtowcs_fallback(_citrus_ctype_rec_t * __restrict cc,
+    wchar_t * __restrict dst, const char ** __restrict src,
+    size_t slen, size_t dlen, void * __restrict ps, size_t * __restrict
nresult)
[...]
+       s = *src;
+       n = slen;
+       if (dst == NULL) {
+               while (n > 0) {
+                       err = _citrus_ctype_mbrtowc(cc,
+                           &dummy, s, n, ps, &len);
+                       if (err)
+                               goto ilseq;
+                       if (len == (size_t)-2 || dummy == L'\0')
+                               break;
+                       s += len, n -= len;
+               }
+       } else {
+               while (dlen > 0 && n > 0) {
+                       err = _citrus_ctype_mbrtowc(cc, dst, s, n, ps, &len);
+                       if (err)
+                               goto ilseq;
+                       if (len == (size_t)-2 || *dst == L'\0')
+                               break;
+                       ++dst, --dlen;
+                       s += len, n -= len;
+               }
+       }
+       *nresult = slen - n;
+       return 0;
+
+ilseq:
+       *nresult = (size_t)-1;
+       return err;
+}

Joerg pointed out that if dst!=NULL && *dst==L'\0' && ps!=NULL, the
mbstate_t object should be reset (in initial state); I understand this
is performed by *mbrtowc() function.

However, what I do not see is the updating of the value of *src when
dst!=NULL


+_FUNCNAME(mbsnrtowcs_priv)(_ENCODING_INFO * __restrict ei,
+    wchar_t * __restrict dst, const char ** __restrict src,
+    size_t slen, size_t dlen, _ENCODING_STATE * __restrict psenc,
+    size_t * __restrict nresult)
[...]

Same here

diff -uNrBw libc.orig/citrus/citrus_none.c libc/citrus/citrus_none.c
--- libc.orig/citrus/citrus_none.c      2008-06-15 01:01:07.000000000 +0900
+++ libc/citrus/citrus_none.c   2010-11-20 23:00:23.000000000 +0900
@@ -337,6 +337,87 @@
[...]
+_citrus_NONE_ctype_mbsnrtowcs(_citrus_ctype_rec_t * __restrict cc,
+    wchar_t * __restrict dst, const char ** __restrict src,
+    size_t slen, size_t dlen, void * __restrict pspriv,
+    size_t * __restrict nresult)
+{
+       const char *s;
[...]
+       if (dst == NULL) {
+               *nresult = strnlen(*src, slen);
+       } else {
+               s = *src;
+               while (slen > 0 && dlen > 0) {
+                       *dst = (wchar_t)(unsigned char)*s;
+                       if (*dst == L'\0')
+                               break;
+                       ++s, --slen;
+                       ++dst, --dlen;
+               }
+               *nresult = (size_t)(*src - s);
+       }
+       return 0;
+}

And same here; note that strnlen call is correct IMHO.


Antoine


Home | Main Index | Thread Index | Old Index