1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

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
This commit is contained in:
Tim J. Robbins 2002-08-31 14:16:12 +00:00
parent 83e563275f
commit a5f76f1911
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=102701
2 changed files with 48 additions and 6 deletions

View File

@ -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);
}

View File

@ -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);
}