Prepare to handle trivial state-dependent encodings. Full support for
state-dependent encodings with locking shifts will come later if there is demand for it.
This commit is contained in:
parent
e97e856274
commit
93996f6d58
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=128002
@ -77,6 +77,8 @@ fgetwc(FILE *fp)
|
||||
static __inline wint_t
|
||||
__fgetwc_nbf(FILE *fp)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
char buf[MB_LEN_MAX];
|
||||
size_t n, nconv;
|
||||
int c;
|
||||
@ -90,7 +92,8 @@ __fgetwc_nbf(FILE *fp)
|
||||
break;
|
||||
}
|
||||
buf[n++] = (char)c;
|
||||
nconv = mbrtowc(&wc, buf, n, NULL);
|
||||
mbs = initial;
|
||||
nconv = mbrtowc(&wc, buf, n, &mbs);
|
||||
if (nconv == n)
|
||||
return (wc);
|
||||
else if (nconv == 0)
|
||||
|
@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
|
||||
wint_t
|
||||
__fputwc(wchar_t wc, FILE *fp)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
char buf[MB_LEN_MAX];
|
||||
size_t i, len;
|
||||
|
||||
@ -55,7 +57,8 @@ __fputwc(wchar_t wc, FILE *fp)
|
||||
*buf = (unsigned char)wc;
|
||||
len = 1;
|
||||
} else {
|
||||
if ((len = wcrtomb(buf, wc, NULL)) == (size_t)-1) {
|
||||
mbs = initial;
|
||||
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
return (WEOF);
|
||||
}
|
||||
|
@ -42,12 +42,15 @@ __FBSDID("$FreeBSD$");
|
||||
wint_t
|
||||
__ungetwc(wint_t wc, FILE *fp)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
char buf[MB_LEN_MAX];
|
||||
size_t len;
|
||||
|
||||
if (wc == WEOF)
|
||||
return (WEOF);
|
||||
if ((len = wcrtomb(buf, wc, NULL)) == (size_t)-1) {
|
||||
mbs = initial;
|
||||
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
return (WEOF);
|
||||
}
|
||||
|
@ -342,6 +342,8 @@ __ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs,
|
||||
static char *
|
||||
__wcsconv(wchar_t *wcsarg, int prec)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
char buf[MB_LEN_MAX];
|
||||
wchar_t *p;
|
||||
char *convbuf, *mbp;
|
||||
@ -354,8 +356,9 @@ __wcsconv(wchar_t *wcsarg, int prec)
|
||||
if (prec >= 0) {
|
||||
nbytes = 0;
|
||||
p = wcsarg;
|
||||
mbs = initial;
|
||||
for (;;) {
|
||||
clen = wcrtomb(buf, *p++, NULL);
|
||||
clen = wcrtomb(buf, *p++, &mbs);
|
||||
if (clen == 0 || clen == (size_t)-1 ||
|
||||
nbytes + clen > prec)
|
||||
break;
|
||||
@ -363,7 +366,8 @@ __wcsconv(wchar_t *wcsarg, int prec)
|
||||
}
|
||||
} else {
|
||||
p = wcsarg;
|
||||
nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, NULL);
|
||||
mbs = initial;
|
||||
nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
|
||||
if (nbytes == (size_t)-1)
|
||||
return (NULL);
|
||||
}
|
||||
@ -376,8 +380,9 @@ __wcsconv(wchar_t *wcsarg, int prec)
|
||||
*/
|
||||
mbp = convbuf;
|
||||
p = wcsarg;
|
||||
mbs = initial;
|
||||
while (mbp - convbuf < nbytes) {
|
||||
clen = wcrtomb(mbp, *p++, NULL);
|
||||
clen = wcrtomb(mbp, *p++, &mbs);
|
||||
if (clen == 0 || clen == (size_t)-1)
|
||||
break;
|
||||
mbp += clen;
|
||||
@ -793,10 +798,13 @@ reswitch: switch (ch) {
|
||||
/*FALLTHROUGH*/
|
||||
case 'c':
|
||||
if (flags & LONGINT) {
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
size_t mbseqlen;
|
||||
|
||||
mbs = initial;
|
||||
mbseqlen = wcrtomb(cp = buf,
|
||||
(wchar_t)GETARG(wint_t), NULL);
|
||||
(wchar_t)GETARG(wint_t), &mbs);
|
||||
if (mbseqlen == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
goto error;
|
||||
|
@ -142,6 +142,8 @@ __svfscanf(FILE *fp, const char *fmt0, va_list ap)
|
||||
wchar_t *wcp; /* handy wide character pointer */
|
||||
wchar_t *wcp0; /* saves original value of wcp */
|
||||
size_t nconv; /* length of multibyte sequence converted */
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
|
||||
/* `basefix' is used to avoid `if' tests in the integer scanner */
|
||||
static short basefix[17] =
|
||||
@ -367,7 +369,8 @@ again: c = *fmt++;
|
||||
buf[n++] = *fp->_p;
|
||||
fp->_p++;
|
||||
fp->_r--;
|
||||
nconv = mbrtowc(wcp, buf, n, NULL);
|
||||
mbs = initial;
|
||||
nconv = mbrtowc(wcp, buf, n, &mbs);
|
||||
if (nconv == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
goto input_failure;
|
||||
@ -446,7 +449,8 @@ again: c = *fmt++;
|
||||
buf[n++] = *fp->_p;
|
||||
fp->_p++;
|
||||
fp->_r--;
|
||||
nconv = mbrtowc(wcp, buf, n, NULL);
|
||||
mbs = initial;
|
||||
nconv = mbrtowc(wcp, buf, n, &mbs);
|
||||
if (nconv == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
goto input_failure;
|
||||
@ -546,7 +550,8 @@ again: c = *fmt++;
|
||||
buf[n++] = *fp->_p;
|
||||
fp->_p++;
|
||||
fp->_r--;
|
||||
nconv = mbrtowc(wcp, buf, n, NULL);
|
||||
mbs = initial;
|
||||
nconv = mbrtowc(wcp, buf, n, &mbs);
|
||||
if (nconv == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
goto input_failure;
|
||||
|
@ -164,6 +164,8 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
|
||||
static wint_t
|
||||
__xfputwc(wchar_t wc, FILE *fp)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
char buf[MB_LEN_MAX];
|
||||
struct __suio uio;
|
||||
struct __siov iov;
|
||||
@ -172,7 +174,8 @@ __xfputwc(wchar_t wc, FILE *fp)
|
||||
if ((fp->_flags & __SSTR) == 0)
|
||||
return (__fputwc(wc, fp));
|
||||
|
||||
if ((len = wcrtomb(buf, wc, NULL)) == (size_t)-1) {
|
||||
mbs = initial;
|
||||
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
|
||||
fp->_flags |= __SERR;
|
||||
return (WEOF);
|
||||
}
|
||||
@ -354,6 +357,8 @@ __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
|
||||
static wchar_t *
|
||||
__mbsconv(char *mbsarg, int prec)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
wchar_t *convbuf, *wcp;
|
||||
const char *p;
|
||||
size_t insize, nchars, nconv;
|
||||
@ -372,8 +377,9 @@ __mbsconv(char *mbsarg, int prec)
|
||||
*/
|
||||
p = mbsarg;
|
||||
insize = nchars = 0;
|
||||
mbs = initial;
|
||||
while (nchars != (size_t)prec) {
|
||||
nconv = mbrlen(p, MB_CUR_MAX, NULL);
|
||||
nconv = mbrlen(p, MB_CUR_MAX, &mbs);
|
||||
if (nconv == 0 || nconv == (size_t)-1 ||
|
||||
nconv == (size_t)-2)
|
||||
break;
|
||||
@ -396,8 +402,9 @@ __mbsconv(char *mbsarg, int prec)
|
||||
return (NULL);
|
||||
wcp = convbuf;
|
||||
p = mbsarg;
|
||||
mbs = initial;
|
||||
while (insize != 0) {
|
||||
nconv = mbrtowc(wcp, p, insize, NULL);
|
||||
nconv = mbrtowc(wcp, p, insize, &mbs);
|
||||
if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
|
||||
break;
|
||||
wcp++;
|
||||
|
@ -148,6 +148,8 @@ __vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
|
||||
char *mbp; /* multibyte string pointer for %c %s %[ */
|
||||
size_t nconv; /* number of bytes in mb. conversion */
|
||||
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
|
||||
/* `basefix' is used to avoid `if' tests in the integer scanner */
|
||||
static short basefix[17] =
|
||||
@ -379,16 +381,17 @@ again: c = *fmt++;
|
||||
if (!(flags & SUPPRESS))
|
||||
mbp = va_arg(ap, char *);
|
||||
n = 0;
|
||||
mbs = initial;
|
||||
while (width != 0 &&
|
||||
(wi = __fgetwc(fp)) != WEOF) {
|
||||
if (width >= MB_CUR_MAX &&
|
||||
!(flags & SUPPRESS)) {
|
||||
nconv = wcrtomb(mbp, wi, NULL);
|
||||
nconv = wcrtomb(mbp, wi, &mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
} else {
|
||||
nconv = wcrtomb(mbbuf, wi,
|
||||
NULL);
|
||||
&mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
if (nconv > width) {
|
||||
@ -443,16 +446,17 @@ again: c = *fmt++;
|
||||
if (!(flags & SUPPRESS))
|
||||
mbp = va_arg(ap, char *);
|
||||
n = 0;
|
||||
mbs = initial;
|
||||
while ((wi = __fgetwc(fp)) != WEOF &&
|
||||
width != 0 && INCCL(wi)) {
|
||||
if (width >= MB_CUR_MAX &&
|
||||
!(flags & SUPPRESS)) {
|
||||
nconv = wcrtomb(mbp, wi, NULL);
|
||||
nconv = wcrtomb(mbp, wi, &mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
} else {
|
||||
nconv = wcrtomb(mbbuf, wi,
|
||||
NULL);
|
||||
&mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
if (nconv > width)
|
||||
@ -503,17 +507,18 @@ again: c = *fmt++;
|
||||
} else {
|
||||
if (!(flags & SUPPRESS))
|
||||
mbp = va_arg(ap, char *);
|
||||
mbs = initial;
|
||||
while ((wi = __fgetwc(fp)) != WEOF &&
|
||||
width != 0 &&
|
||||
!iswspace(wi)) {
|
||||
if (width >= MB_CUR_MAX &&
|
||||
!(flags & SUPPRESS)) {
|
||||
nconv = wcrtomb(mbp, wi, NULL);
|
||||
nconv = wcrtomb(mbp, wi, &mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
} else {
|
||||
nconv = wcrtomb(mbbuf, wi,
|
||||
NULL);
|
||||
&mbs);
|
||||
if (nconv == (size_t)-1)
|
||||
goto input_failure;
|
||||
if (nconv > width)
|
||||
|
@ -43,6 +43,8 @@ int
|
||||
vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
|
||||
__va_list ap)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
FILE f;
|
||||
struct __sFILEX ext;
|
||||
char *mbp;
|
||||
@ -76,7 +78,8 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
|
||||
* XXX Undo the conversion from wide characters to multibyte that
|
||||
* fputwc() did in __vfwprintf().
|
||||
*/
|
||||
if (mbsrtowcs(s, (const char **)&mbp, n, NULL) == (size_t)-1) {
|
||||
mbs = initial;
|
||||
if (mbsrtowcs(s, (const char **)&mbp, n, &mbs) == (size_t)-1) {
|
||||
free(f._bf._base);
|
||||
errno = EILSEQ;
|
||||
return (-1);
|
||||
|
@ -64,6 +64,8 @@ int
|
||||
vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
|
||||
va_list ap)
|
||||
{
|
||||
static const mbstate_t initial;
|
||||
mbstate_t mbs;
|
||||
FILE f;
|
||||
struct __sFILEX ext;
|
||||
char *mbstr;
|
||||
@ -76,7 +78,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
|
||||
*/
|
||||
if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL)
|
||||
return (EOF);
|
||||
if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, NULL)) == (size_t)-1) {
|
||||
mbs = initial;
|
||||
if ((mlen = wcsrtombs(mbstr, &str, SIZE_T_MAX, &mbs)) == (size_t)-1) {
|
||||
free(mbstr);
|
||||
return (EOF);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user