Cygwin: mbsnrtowci: like mbsnrtowcs, just for wint_t

Deviation from standard: If the input is broken, the output will be
broken.  I. e., we just copy the current byte over into the wint_t
destination and try to pick up on the next byte.  This is in line
with the way fnmatch works.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2023-03-01 10:44:52 +01:00
parent 9870f1d1ff
commit 149cabea82
2 changed files with 61 additions and 0 deletions

View File

@ -52,6 +52,14 @@ size_t wirtomb (char *, wint_t, mbstate_t *);
a UTF-32 value. Defined in strfuncs.cc */ a UTF-32 value. Defined in strfuncs.cc */
extern size_t mbrtowi (wint_t *, const char *, size_t, mbstate_t *); extern size_t mbrtowi (wint_t *, const char *, size_t, mbstate_t *);
/* replacement function for mbsnrtowcs, returning a wint_t representing
a UTF-32 value. Defined in strfuncs.cc.
Deviation from standard: If the input is broken, the output will be
broken. I. e., we just copy the current byte over into the wint_t
destination and try to pick up on the next byte. This is in line
with the way fnmatch works. */
extern size_t mbsnrtowci(wint_t *, const char **, size_t, size_t, mbstate_t *);
/* convert wint_t string to char string, but *only* if the string consists /* convert wint_t string to char string, but *only* if the string consists
entirely of ASCII chars */ entirely of ASCII chars */
static inline void static inline void

View File

@ -180,6 +180,59 @@ mbrtowi (wint_t *pwi, const char *s, size_t n, mbstate_t *ps)
return len; return len;
} }
extern "C" size_t
mbsnrtowci(wint_t *dst, const char **src, size_t nms, size_t len, mbstate_t *ps)
{
wint_t *ptr = dst;
const char *tmp_src;
size_t max;
size_t count = 0;
size_t bytes;
if (dst == NULL)
{
/* Ignore original len value and do not alter src pointer if the
dst pointer is NULL. */
len = (size_t)-1;
tmp_src = *src;
src = &tmp_src;
}
max = len;
while (len > 0)
{
bytes = mbrtowi (ptr, *src, MB_CUR_MAX, ps);
if (bytes > 0)
{
*src += bytes;
nms -= bytes;
++count;
ptr = (dst == NULL) ? NULL : ptr + 1;
--len;
}
else if (bytes == 0)
{
*src = NULL;
return count;
}
else
{
/* Deviation from standard: If the input is broken, the output
will be broken. I. e., we just copy the current byte over
into the wint_t destination and try to pick up on the next
byte. This is in line with the way fnmatch works. */
ps->__count = 0;
if (dst)
{
*ptr++ = (const wint_t) *(*src)++;
++count;
--nms;
--len;
}
}
}
return (size_t) max;
}
/* The SJIS, JIS and eucJP conversion in newlib does not use UTF as /* The SJIS, JIS and eucJP conversion in newlib does not use UTF as
wchar_t character representation. That's unfortunate for us since wchar_t character representation. That's unfortunate for us since
we require UTF for the OS. What we do here is to have our own we require UTF for the OS. What we do here is to have our own