Index: /usr/src/lib/libc/stdio/vfscanf.c =================================================================== RCS file: /home/cvs/NetBSD/src/lib/libc/stdio/vfscanf.c,v retrieving revision 1.36 diff -u -r1.36 vfscanf.c --- /usr/src/lib/libc/stdio/vfscanf.c 30 Dec 2003 22:10:20 -0000 1.36 +++ /usr/src/lib/libc/stdio/vfscanf.c 25 Jul 2004 04:50:35 -0000 @@ -59,6 +59,12 @@ #include "floatio.h" #endif +#define WCHAR_T_SUPPORT +#ifdef WCHAR_T_SUPPORT +#include +#include +#endif + /* * Provide an external name for vfscanf. Note, we don't use the normal * namespace.h method; stdio routines explicitly use the internal name @@ -158,6 +164,14 @@ static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +#ifdef WCHAR_T_SUPPORT + /* for wchar_t support, %lc(%C), %ls(%S), %l[...] */ + wchar_t *wp, wtmp; + unsigned char mb; + size_t len; + mbstate_t st; +#endif + _DIAGASSERT(fp != NULL); _DIAGASSERT(fmt0 != NULL); @@ -165,8 +179,10 @@ nassigned = 0; nread = 0; +#ifdef __GNUC__ base = 0; /* XXX just to keep gcc happy */ ccfn = NULL; /* XXX just to keep gcc happy */ +#endif for (;;) { c = *fmt++; if (c == 0) { @@ -294,6 +310,12 @@ break; #endif +#ifdef WCHAR_T_SUPPORT + case 'S': + flags |= LONG; + /*FALLTHROUGH*/ +#endif + case 's': c = CT_STRING; break; @@ -304,6 +326,12 @@ c = CT_CCL; break; +#ifdef WCHAR_T_SUPPORT + case 'C': + flags |= LONG; + /*FALLTHROUGH*/ +#endif + case 'c': flags |= NOSKIP; c = CT_CHAR; @@ -389,6 +417,31 @@ /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; +#ifdef WCHAR_T_SUPPORT + if (flags & LONG) { + if (flags & SUPPRESS) + wp = NULL; + else { + wp = (wchar_t *)va_arg(ap, wchar_t *); + nassigned++; + } + memset(&st, 0, sizeof(st)); + do { + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + mb = *fp->_p++; fp->_r--; nread++; + len = mbrtowc(&wtmp, (const char *)&mb, + 1, &st); + if (errno) + goto input_failure; + if (len == (size_t)-2) + continue; + if (wp != NULL) + *wp++ = wtmp; + width--; + } while (width > 0); + } else { +#endif if (flags & SUPPRESS) { size_t sum = 0; for (;;) { @@ -418,6 +471,9 @@ nread += r; nassigned++; } +#ifdef WCHAR_T_SUPPORT + } +#endif break; case CT_CCL: @@ -425,6 +481,46 @@ if (width == 0) width = ~0U; /* `infinity' */ /* take only those things in the class */ +#ifdef WCHAR_T_SUPPORT + if (flags & LONG) { + if (flags & SUPPRESS) + wp = NULL; + else { + wp = (wchar_t *)va_arg(ap, wchar_t *); + nassigned++; + } + memset(&st, 0, sizeof(st)); + for (;;) { + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + if (ccltab[mb = *fp->_p]) { + fp->_p++; fp->_r--; nread++; + len = mbrtowc(&wtmp, + (const char *)&mb, 1, &st); + if (errno) + goto input_failure; + if (len == (size_t)-2) + continue; + width--; + } else { + if (mbsinit(&st) == 0) { + errno = EILSEQ; + goto input_failure; + } + wtmp = L'\0'; + } + if (wp != NULL) + *wp++ = wtmp; + if (wtmp == L'\0') + break; + if (width == 0) { + if (wp != NULL) + *wp++ = L'\0'; + break; + } + } + } else { +#endif if (flags & SUPPRESS) { n = 0; while (ccltab[*fp->_p]) { @@ -459,12 +555,55 @@ nassigned++; } nread += n; +#ifdef WCHAR_T_SUPPORT + } +#endif break; case CT_STRING: /* like CCL, but zero-length string OK, & no NOSKIP */ if (width == 0) width = ~0U; +#ifdef WCHAR_T_SUPPORT + if (flags & LONG) { + if (flags & SUPPRESS) + wp = NULL; + else { + wp = (wchar_t *)va_arg(ap, wchar_t *); + nassigned++; + } + memset(&st, 0, sizeof(st)); + for (;;) { + if (fp->_r <= 0 && __srefill(fp)) + goto input_failure; + if (!isspace(mb = *fp->_p)) { + fp->_p++; fp->_r--; nread++; + len = mbrtowc(&wtmp, + (const char *)&mb, 1, &st); + if (errno) + goto input_failure; + if (len == (size_t)-2) + continue; + width--; + } else { + if (mbsinit(&st) == 0) { + errno = EILSEQ; + goto input_failure; + } + wtmp = L'\0'; + } + if (wp != NULL) + *wp++ = wtmp; + if (wtmp == L'\0') + break; + if (width == 0) { + if (wp != NULL) + *wp++ = L'\0'; + break; + } + } + } else { +#endif if (flags & SUPPRESS) { n = 0; while (!isspace(*fp->_p)) { @@ -489,6 +628,9 @@ nread += p - p0; nassigned++; } +#ifdef WCHAR_T_SUPPORT + } +#endif continue; case CT_INT: