From ca719015df3d7025ed5dab68f072529d15e9bde1 Mon Sep 17 00:00:00 2001 From: tjr Date: Sat, 31 Aug 2002 14:16:12 +0000 Subject: Implement the XSI extension which allows the destination string to be NULL, and returns the number of bytes that would be required to store the result of the conversion without storing anything. PR: 17694 --- lib/libc/locale/mbstowcs.c | 25 +++++++++++++++++++++++-- lib/libc/locale/wcstombs.c | 29 +++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 6 deletions(-) (limited to 'lib/libc') diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c index 5c60a5b..b473f89 100644 --- a/lib/libc/locale/mbstowcs.c +++ b/lib/libc/locale/mbstowcs.c @@ -37,6 +37,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -50,18 +51,38 @@ mbstowcs(pwcs, s, n) { char const *e; int cnt = 0; + rune_t r; - if (!pwcs || !s) + if (!s) { + errno = EINVAL; return (-1); + } + if (pwcs == NULL) { + /* Convert and count only, do not store. */ + while ((r = sgetrune(s, MB_LEN_MAX, &e)) != _INVALID_RUNE && + r != 0) { + s = e; + cnt++; + } + if (r == _INVALID_RUNE) { + errno = EILSEQ; + return (-1); + } + } + + /* Convert, store and count characters. */ while (n-- > 0) { *pwcs = sgetrune(s, MB_LEN_MAX, &e); - if (*pwcs == _INVALID_RUNE) + if (*pwcs == _INVALID_RUNE) { + errno = EILSEQ; return (-1); + } if (*pwcs++ == 0) break; s = e; ++cnt; } + return (cnt); } diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c index 987ec30..ed9397a 100644 --- a/lib/libc/locale/wcstombs.c +++ b/lib/libc/locale/wcstombs.c @@ -37,6 +37,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -48,26 +49,46 @@ wcstombs(s, pwcs, n) const wchar_t *pwcs; size_t n; { + char buf[MB_LEN_MAX]; char *e; int cnt, nb; - if (!pwcs || !s || n > INT_MAX) + if (!pwcs || n > INT_MAX) { + errno = EINVAL; return (-1); + } - nb = n; cnt = 0; + + if (s == NULL) { + /* Convert and count only, do not store. */ + while (*pwcs != L'\0') { + if (!sputrune(*pwcs++, buf, MB_LEN_MAX, &e)) { + errno = EILSEQ; + return (-1); + } + cnt += e - buf; + } + return (cnt); + } + + /* Convert, store and count characters. */ + nb = n; while (nb > 0) { if (*pwcs == 0) { *s = 0; break; } - if (!sputrune(*pwcs++, s, nb, &e)) - return (-1); /* encoding error */ + if (!sputrune(*pwcs++, s, nb, &e)) { + errno = EILSEQ; + return (-1); + } if (!e) /* too long */ return (cnt); cnt += e - s; nb -= e - s; s = e; } + return (cnt); } -- cgit v1.1