summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-08-31 14:16:12 +0000
committertjr <tjr@FreeBSD.org>2002-08-31 14:16:12 +0000
commitca719015df3d7025ed5dab68f072529d15e9bde1 (patch)
treeae8df1a0ce3a83d40f146b0d2bcd6befaa55ce7f /lib
parent624d02ba22e582550b9128552e7d8ceba6c3748b (diff)
downloadFreeBSD-src-ca719015df3d7025ed5dab68f072529d15e9bde1.zip
FreeBSD-src-ca719015df3d7025ed5dab68f072529d15e9bde1.tar.gz
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
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/locale/mbstowcs.c25
-rw-r--r--lib/libc/locale/wcstombs.c29
2 files changed, 48 insertions, 6 deletions
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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stddef.h>
@@ -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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stddef.h>
@@ -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);
}
OpenPOWER on IntegriCloud