Loading...
--- Libc/Libc-498.1.7/stdio/FreeBSD/vfwscanf.c.patch
+++ /dev/null
@@ -1,556 +0,0 @@
---- vfwscanf.c.orig 2004-11-25 11:38:36.000000000 -0800
-+++ vfwscanf.c 2005-05-20 00:24:42.000000000 -0700
-@@ -42,6 +42,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 @@
- #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 @@
-
- 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 @@
- /*
- * 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 @@
- 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,27 +163,30 @@
- 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 != '%')
-@@ -180,15 +201,27 @@
- switch (c) {
- case '%':
- literal:
-- if ((wi = __fgetwc(fp)) == WEOF)
-+ if ((wi = __fgetwc(fp, loc)) == 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 +340,6 @@
- break;
-
- case 'n':
-- nconversions++;
- if (flags & SUPPRESS) /* ??? */
- continue;
- if (flags & SHORTSHORT)
-@@ -343,11 +375,11 @@
- * 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 +396,7 @@
- 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 +412,19 @@
- 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 +442,6 @@
- if (!(flags & SUPPRESS))
- nassigned++;
- }
-- nconversions++;
- break;
-
- case CT_CCL:
-@@ -420,20 +451,20 @@
- /* 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 +475,16 @@
- 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 +499,15 @@
- 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 +515,39 @@
- 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 +562,12 @@
- nread++;
- }
- if (wi != WEOF)
-- __ungetwc(wi, fp);
-+ __ungetwc(wi, fp, loc);
- if (!(flags & SUPPRESS)) {
- *mbp = 0;
- nassigned++;
- }
- }
-- nconversions++;
- continue;
-
- case CT_INT:
-@@ -546,7 +577,7 @@
- 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 +661,7 @@
- * for a number. Stop accumulating digits.
- */
- if (c != WEOF)
-- __ungetwc(c, fp);
-+ __ungetwc(c, fp, loc);
- break;
- ok:
- /*
-@@ -646,22 +677,22 @@
- */
- 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 +715,45 @@
- 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)
-+ if (__scanfdebug && p - pbuf != width)
- abort();
- 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
- 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 +762,33 @@
- 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;
--
-+ static wchar_t *b = NULL;
-+ static size_t bsiz = 0;
-+ wchar_t *e;
-+ size_t s;
-+
-+ if (bsiz == 0) {
-+ b = (wchar_t *)malloc(BUF * sizeof(wchar_t));
-+ if (b == NULL) {
-+ *buf = NULL;
-+ return 0;
-+ }
-+ bsiz = BUF;
-+ }
-+ s = (width == 0 ? bsiz : (width + 1));
-+ if (s > bsiz) {
-+ b = (wchar_t *)reallocf(b, s * sizeof(wchar_t));
-+ if (b == NULL) {
-+ bsiz = 0;
-+ *buf = NULL;
-+ return 0;
-+ }
-+ bsiz = s;
-+ }
-+ 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 +798,12 @@
- * 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 +863,7 @@
- if (c == ')') {
- commit = p;
- infnanpos = -2;
-- } else if (!iswalnum(c) && c != '_')
-+ } else if (!iswalnum_l(c, loc) && c != '_')
- goto parsedone;
- break;
- }
-@@ -824,7 +879,7 @@
- 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 +896,7 @@
- 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,7 +909,7 @@
- else
- goto reswitch;
- case S_EXPDIGITS:
-- if (iswdigit(c))
-+ if (iswdigit_l(c, loc))
- commit = p;
- else
- goto parsedone;
-@@ -862,16 +917,32 @@
- default:
- abort();
- }
-+ if (p >= e) {
-+ ssize_t diff = (p - b);
-+ ssize_t com = (commit - b);
-+ s += BUF;
-+ b = (wchar_t *)reallocf(b, s * sizeof(wchar_t));
-+ if (b == NULL) {
-+ bsiz = 0;
-+ *buf = NULL;
-+ return 0;
-+ }
-+ bsiz = s;
-+ e = b + (s - 1);
-+ p = b + diff;
-+ commit = b + com;
-+ }
- *p++ = c;
- c = WEOF;
- }
-
- 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