Loading...
--- Libc/Libc-594.1.4/stdio/FreeBSD/vfwscanf.c.patch
+++ /dev/null
@@ -1,560 +0,0 @@
---- vfwscanf.c.orig 2009-02-15 03:11:22.000000000 -0800
-+++ vfwscanf.c 2009-02-16 00:10:06.000000000 -0800
-@@ -42,6 +42,8 @@ static char sccsid[] = "@(#)vfscanf.c 8.
- #include <sys/cdefs.h>
- __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwscanf.c,v 1.12 2004/05/02 20:13:29 obrien Exp $");
-
-+#include "xlocale_private.h"
-+
- #include "namespace.h"
- #include <ctype.h>
- #include <inttypes.h>
-@@ -98,7 +100,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v
- #define CT_INT 3 /* %[dioupxX] conversion */
- #define CT_FLOAT 4 /* %[efgEFG] conversion */
-
--static int parsefloat(FILE *, wchar_t *, wchar_t *);
-+#ifndef NO_FLOATING_POINT
-+static int parsefloat(FILE *, wchar_t **, size_t, locale_t loc);
-+#endif /* !NO_FLOATING_POINT */
-
- extern int __scanfdebug;
-
-@@ -116,7 +120,21 @@ vfwscanf(FILE * __restrict fp, const wch
-
- FLOCKFILE(fp);
- ORIENT(fp, 1);
-- ret = __vfwscanf(fp, fmt, ap);
-+ ret = __vfwscanf(fp, __current_locale(), fmt, ap);
-+ FUNLOCKFILE(fp);
-+ return (ret);
-+}
-+
-+int
-+vfwscanf_l(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt,
-+ va_list ap)
-+{
-+ int ret;
-+
-+ NORMALIZE_LOCALE(loc);
-+ FLOCKFILE(fp);
-+ ORIENT(fp, 1);
-+ ret = __vfwscanf(fp, loc, fmt, ap);
- FUNLOCKFILE(fp);
- return (ret);
- }
-@@ -124,8 +142,9 @@ vfwscanf(FILE * __restrict fp, const wch
- /*
- * Non-MT-safe version.
- */
--int
--__vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap)
-+__private_extern__ int
-+__vfwscanf(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt,
-+ va_list ap)
- {
- wint_t c; /* character from format, or conversion */
- size_t width; /* field width, or 0 */
-@@ -134,7 +153,6 @@ __vfwscanf(FILE * __restrict fp, const w
- int flags; /* flags as defined above */
- wchar_t *p0; /* saves original value of p when necessary */
- int nassigned; /* number of fields assigned */
-- int nconversions; /* number of conversions */
- int nread; /* number of characters consumed from fp */
- int base; /* base argument to conversion function */
- wchar_t buf[BUF]; /* buffer for numeric conversions */
-@@ -145,31 +163,37 @@ __vfwscanf(FILE * __restrict fp, const w
- 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 */
-+ int index; /* for %index$ */
-+ va_list ap_orig; /* to reset ap to first argument */
- static const mbstate_t initial;
- mbstate_t mbs;
-+ int mb_cur_max = MB_CUR_MAX_L(loc);
-
- /* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] =
- { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
-
- nassigned = 0;
-- nconversions = 0;
- nread = 0;
- ccls = ccle = NULL;
-+ va_copy(ap_orig, ap);
- for (;;) {
- c = *fmt++;
- if (c == 0)
- return (nassigned);
-- if (iswspace(c)) {
-- while ((c = __fgetwc(fp)) != WEOF &&
-- iswspace(c))
-+ if (iswspace_l(c, loc)) {
-+ while ((c = __fgetwc(fp, loc)) != WEOF &&
-+ iswspace_l(c, loc))
- ;
- if (c != WEOF)
-- __ungetwc(c, fp);
-+ __ungetwc(c, fp, loc);
- continue;
- }
-- if (c != '%')
-+ if (c != '%') {
-+ if ((wi = __fgetwc(fp, loc)) == WEOF)
-+ goto input_failure;
- goto literal;
-+ }
- width = 0;
- flags = 0;
- /*
-@@ -179,16 +203,34 @@ __vfwscanf(FILE * __restrict fp, const w
- again: c = *fmt++;
- switch (c) {
- case '%':
-+ /* Consume leading white space */
-+ for(;;) {
-+ if ((wi = __fgetwc(fp, loc)) == WEOF)
-+ goto input_failure;
-+ if (!iswspace_l(wi, loc))
-+ break;
-+ nread++;
-+ }
- literal:
-- if ((wi = __fgetwc(fp)) == WEOF)
-- goto input_failure;
- if (wi != c) {
-- __ungetwc(wi, fp);
-- goto input_failure;
-+ __ungetwc(wi, fp, loc);
-+ goto match_failure;
- }
- nread++;
- continue;
-
-+ case '$':
-+ index = width;
-+ if (index < 1 || index > NL_ARGMAX || fmt[-3] != '%') {
-+ goto input_failure;
-+ }
-+ width = 0;
-+ va_end(ap);
-+ va_copy(ap, ap_orig); /* reset to %1$ */
-+ for (; index > 1; index--) {
-+ va_arg(ap, void*);
-+ }
-+ goto again;
- case '*':
- flags |= SUPPRESS;
- goto again;
-@@ -307,7 +349,6 @@ literal:
- break;
-
- case 'n':
-- nconversions++;
- if (flags & SUPPRESS) /* ??? */
- continue;
- if (flags & SHORTSHORT)
-@@ -343,11 +384,11 @@ literal:
- * that suppress this.
- */
- if ((flags & NOSKIP) == 0) {
-- while ((wi = __fgetwc(fp)) != WEOF && iswspace(wi))
-+ while ((wi = __fgetwc(fp, loc)) != WEOF && iswspace_l(wi, loc))
- nread++;
- if (wi == WEOF)
- goto input_failure;
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- }
-
- /*
-@@ -364,7 +405,7 @@ literal:
- p = va_arg(ap, wchar_t *);
- n = 0;
- while (width-- != 0 &&
-- (wi = __fgetwc(fp)) != WEOF) {
-+ (wi = __fgetwc(fp, loc)) != WEOF) {
- if (!(flags & SUPPRESS))
- *p++ = (wchar_t)wi;
- n++;
-@@ -380,19 +421,19 @@ literal:
- n = 0;
- mbs = initial;
- while (width != 0 &&
-- (wi = __fgetwc(fp)) != WEOF) {
-- if (width >= MB_CUR_MAX &&
-+ (wi = __fgetwc(fp, loc)) != WEOF) {
-+ if (width >= mb_cur_max &&
- !(flags & SUPPRESS)) {
-- nconv = wcrtomb(mbp, wi, &mbs);
-+ nconv = wcrtomb_l(mbp, wi, &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- } else {
-- nconv = wcrtomb(mbbuf, wi,
-- &mbs);
-+ nconv = wcrtomb_l(mbbuf, wi,
-+ &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- if (nconv > width) {
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- break;
- }
- if (!(flags & SUPPRESS))
-@@ -410,7 +451,6 @@ literal:
- if (!(flags & SUPPRESS))
- nassigned++;
- }
-- nconversions++;
- break;
-
- case CT_CCL:
-@@ -420,20 +460,20 @@ literal:
- /* take only those things in the class */
- if ((flags & SUPPRESS) && (flags & LONG)) {
- n = 0;
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width-- != 0 && INCCL(wi))
- n++;
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- if (n == 0)
- goto match_failure;
- } else if (flags & LONG) {
- p0 = p = va_arg(ap, wchar_t *);
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width-- != 0 && INCCL(wi))
- *p++ = (wchar_t)wi;
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- n = p - p0;
- if (n == 0)
- goto match_failure;
-@@ -444,16 +484,16 @@ literal:
- mbp = va_arg(ap, char *);
- n = 0;
- mbs = initial;
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width != 0 && INCCL(wi)) {
-- if (width >= MB_CUR_MAX &&
-+ if (width >= mb_cur_max &&
- !(flags & SUPPRESS)) {
-- nconv = wcrtomb(mbp, wi, &mbs);
-+ nconv = wcrtomb_l(mbp, wi, &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- } else {
-- nconv = wcrtomb(mbbuf, wi,
-- &mbs);
-+ nconv = wcrtomb_l(mbbuf, wi,
-+ &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- if (nconv > width)
-@@ -468,14 +508,15 @@ literal:
- n++;
- }
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
-+ if (n == 0)
-+ goto match_failure;
- if (!(flags & SUPPRESS)) {
- *mbp = 0;
- nassigned++;
- }
- }
- nread += n;
-- nconversions++;
- break;
-
- case CT_STRING:
-@@ -483,39 +524,39 @@ literal:
- if (width == 0)
- width = (size_t)~0;
- if ((flags & SUPPRESS) && (flags & LONG)) {
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width-- != 0 &&
-- !iswspace(wi))
-+ !iswspace_l(wi, loc))
- nread++;
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- } else if (flags & LONG) {
- p0 = p = va_arg(ap, wchar_t *);
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width-- != 0 &&
-- !iswspace(wi)) {
-+ !iswspace_l(wi, loc)) {
- *p++ = (wchar_t)wi;
- nread++;
- }
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- *p = '\0';
- nassigned++;
- } else {
- if (!(flags & SUPPRESS))
- mbp = va_arg(ap, char *);
- mbs = initial;
-- while ((wi = __fgetwc(fp)) != WEOF &&
-+ while ((wi = __fgetwc(fp, loc)) != WEOF &&
- width != 0 &&
-- !iswspace(wi)) {
-- if (width >= MB_CUR_MAX &&
-+ !iswspace_l(wi, loc)) {
-+ if (width >= mb_cur_max &&
- !(flags & SUPPRESS)) {
-- nconv = wcrtomb(mbp, wi, &mbs);
-+ nconv = wcrtomb_l(mbp, wi, &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- } else {
-- nconv = wcrtomb(mbbuf, wi,
-- &mbs);
-+ nconv = wcrtomb_l(mbbuf, wi,
-+ &mbs, loc);
- if (nconv == (size_t)-1)
- goto input_failure;
- if (nconv > width)
-@@ -530,13 +571,12 @@ literal:
- nread++;
- }
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- if (!(flags & SUPPRESS)) {
- *mbp = 0;
- nassigned++;
- }
- }
-- nconversions++;
- continue;
-
- case CT_INT:
-@@ -546,7 +586,7 @@ literal:
- width = sizeof(buf) / sizeof(*buf) - 1;
- flags |= SIGNOK | NDIGITS | NZDIGITS;
- for (p = buf; width; width--) {
-- c = __fgetwc(fp);
-+ c = __fgetwc(fp, loc);
- /*
- * Switch on the character; `goto ok'
- * if we accept it as a part of number.
-@@ -630,7 +670,7 @@ literal:
- * for a number. Stop accumulating digits.
- */
- if (c != WEOF)
-- __ungetwc(c, fp);
-+ __ungetwc(c, fp, loc);
- break;
- ok:
- /*
-@@ -646,22 +686,22 @@ literal:
- */
- if (flags & NDIGITS) {
- if (p > buf)
-- __ungetwc(*--p, fp);
-+ __ungetwc(*--p, fp, loc);
- goto match_failure;
- }
- c = p[-1];
- if (c == 'x' || c == 'X') {
- --p;
-- __ungetwc(c, fp);
-+ __ungetwc(c, fp, loc);
- }
- if ((flags & SUPPRESS) == 0) {
- uintmax_t res;
-
- *p = 0;
- if ((flags & UNSIGNED) == 0)
-- res = wcstoimax(buf, NULL, base);
-+ res = wcstoimax_l(buf, NULL, base, loc);
- else
-- res = wcstoumax(buf, NULL, base);
-+ res = wcstoumax_l(buf, NULL, base, loc);
- if (flags & POINTER)
- *va_arg(ap, void **) =
- (void *)(uintptr_t)res;
-@@ -684,47 +724,47 @@ literal:
- nassigned++;
- }
- nread += p - buf;
-- nconversions++;
- break;
-
- #ifndef NO_FLOATING_POINT
- case CT_FLOAT:
-+ {
-+ wchar_t *pbuf;
- /* scan a floating point number as if by strtod */
-- if (width == 0 || width > sizeof(buf) /
-- sizeof(*buf) - 1)
-- width = sizeof(buf) / sizeof(*buf) - 1;
-- if ((width = parsefloat(fp, buf, buf + width)) == 0)
-+ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0)
- goto match_failure;
- if ((flags & SUPPRESS) == 0) {
- if (flags & LONGDBL) {
-- long double res = wcstold(buf, &p);
-+ long double res = wcstold_l(pbuf, &p, loc);
- *va_arg(ap, long double *) = res;
- } else if (flags & LONG) {
-- double res = wcstod(buf, &p);
-+ double res = wcstod_l(pbuf, &p, loc);
- *va_arg(ap, double *) = res;
- } else {
-- float res = wcstof(buf, &p);
-+ float res = wcstof_l(pbuf, &p, loc);
- *va_arg(ap, float *) = res;
- }
-- if (__scanfdebug && p - buf != width)
-- abort();
-+ if (__scanfdebug && p - pbuf != width)
-+ LIBC_ABORT("p - pbuf %ld != width %ld", (long)(p - pbuf), width);
- nassigned++;
- }
- nread += width;
-- nconversions++;
- break;
-+ }
- #endif /* !NO_FLOATING_POINT */
- }
- }
- input_failure:
-- return (nconversions != 0 ? nassigned : EOF);
-+ return (nassigned ? nassigned : EOF);
- match_failure:
- return (nassigned);
- }
-
- #ifndef NO_FLOATING_POINT
-+extern char *__parsefloat_buf(size_t s); /* see vfscanf-fbsd.c */
-+
- static int
--parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
-+parsefloat(FILE *fp, wchar_t **buf, size_t width, locale_t loc)
- {
- wchar_t *commit, *p;
- int infnanpos = 0;
-@@ -733,9 +773,19 @@ parsefloat(FILE *fp, wchar_t *buf, wchar
- S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
- } state = S_START;
- wchar_t c;
-- wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point;
-+ char *decimal_point;
-+ wchar_t decpt;
- _Bool gotmantdig = 0, ishex = 0;
--
-+ wchar_t *b;
-+ wchar_t *e;
-+ size_t s;
-+
-+ s = (width == 0 ? BUF : (width + 1));
-+ if ((b = (wchar_t *)__parsefloat_buf(s * sizeof(wchar_t))) == NULL) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ e = b + (s - 1);
- /*
- * We set commit = p whenever the string we have read so far
- * constitutes a valid representation of a floating point
-@@ -745,10 +795,12 @@ parsefloat(FILE *fp, wchar_t *buf, wchar
- * always necessary to read at least one character that doesn't
- * match; thus, we can't short-circuit "infinity" or "nan(...)".
- */
-- commit = buf - 1;
-+ commit = b - 1;
- c = WEOF;
-- for (p = buf; p < end; ) {
-- if ((c = __fgetwc(fp)) == WEOF)
-+ decimal_point = localeconv_l(loc)->decimal_point;
-+ mbtowc_l(&decpt, decimal_point, strlen(decimal_point), loc);
-+ for (p = b; width == 0 || p < e; ) {
-+ if ((c = __fgetwc(fp, loc)) == WEOF)
- break;
- reswitch:
- switch (state) {
-@@ -808,7 +860,7 @@ reswitch:
- if (c == ')') {
- commit = p;
- infnanpos = -2;
-- } else if (!iswalnum(c) && c != '_')
-+ } else if (!iswalnum_l(c, loc) && c != '_')
- goto parsedone;
- break;
- }
-@@ -824,7 +876,7 @@ reswitch:
- goto reswitch;
- }
- case S_DIGITS:
-- if ((ishex && iswxdigit(c)) || iswdigit(c))
-+ if ((ishex && iswxdigit_l(c, loc)) || iswdigit_l(c, loc))
- gotmantdig = 1;
- else {
- state = S_FRAC;
-@@ -841,7 +893,7 @@ reswitch:
- goto parsedone;
- else
- state = S_EXP;
-- } else if ((ishex && iswxdigit(c)) || iswdigit(c)) {
-+ } else if ((ishex && iswxdigit_l(c, loc)) || iswdigit_l(c, loc)) {
- commit = p;
- gotmantdig = 1;
- } else
-@@ -854,13 +906,26 @@ reswitch:
- else
- goto reswitch;
- case S_EXPDIGITS:
-- if (iswdigit(c))
-+ if (iswdigit_l(c, loc))
- commit = p;
- else
- goto parsedone;
- break;
- default:
-- abort();
-+ LIBC_ABORT("unknown state %d", state);
-+ }
-+ if (p >= e) {
-+ ssize_t diff = (p - b);
-+ ssize_t com = (commit - b);
-+ s += BUF;
-+ b = (wchar_t *)__parsefloat_buf(s * sizeof(wchar_t));
-+ if (b == NULL) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ e = b + (s - 1);
-+ p = b + diff;
-+ commit = b + com;
- }
- *p++ = c;
- c = WEOF;
-@@ -868,10 +933,11 @@ reswitch:
-
- parsedone:
- if (c != WEOF)
-- __ungetwc(c, fp);
-+ __ungetwc(c, fp, loc);
- while (commit < --p)
-- __ungetwc(*p, fp);
-+ __ungetwc(*p, fp, loc);
- *++commit = '\0';
-- return (commit - buf);
-+ *buf = b;
-+ return (commit - b);
- }
- #endif