Loading...
stdio/FreeBSD/vfwscanf.c.patch Libc-391.5.21 /dev/null
--- Libc/Libc-391.5.21/stdio/FreeBSD/vfwscanf.c.patch
+++ /dev/null
@@ -1,537 +0,0 @@
---- vfwscanf.c.orig	2004-11-25 11:38:36.000000000 -0800
-+++ vfwscanf.c	2005-02-23 16:25:00.000000000 -0800
-@@ -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);
-+				__ungetwc(wi, fp, loc);
- 				goto input_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,49 @@
- 				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) {
-+				if (pbuf)
-+					free(pbuf);
- 				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++;
-+			free(pbuf);
- 			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 +766,18 @@
- 		S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
- 	} state = S_START;
- 	wchar_t c;
--	wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point;
-+	wchar_t decpt = (wchar_t)(unsigned char)*localeconv_l(loc)->decimal_point;
- 	_Bool gotmantdig = 0, ishex = 0;
-+	wchar_t *b, *e;
-+	size_t s;
- 
-+	s = (width == 0 ? BUF : width + 1);
-+	b = (wchar_t *)malloc(s * sizeof(wchar_t));
-+	if (b == 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 +787,10 @@
- 	 * 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)
-+	for (p = b; width == 0 || p < e; ) {
-+		if ((c = __fgetwc(fp, loc)) == WEOF)
- 			break;
- reswitch:
- 		switch (state) {
-@@ -808,7 +850,7 @@
- 				if (c == ')') {
- 					commit = p;
- 					infnanpos = -2;
--				} else if (!iswalnum(c) && c != '_')
-+				} else if (!iswalnum_l(c, loc) && c != '_')
- 					goto parsedone;
- 				break;
- 			}
-@@ -824,7 +866,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 +883,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 +896,7 @@
- 			else
- 				goto reswitch;
- 		case S_EXPDIGITS:
--			if (iswdigit(c))
-+			if (iswdigit_l(c, loc))
- 				commit = p;
- 			else
- 				goto parsedone;
-@@ -862,16 +904,28 @@
- 		default:
- 			abort();
- 		}
-+		if (p >= e) {
-+			size_t diff = (p - b);
-+			s += BUF;
-+			b = (wchar_t *)reallocf(b, s * sizeof(wchar_t));
-+			if (b == NULL) {
-+				*buf = NULL;
-+				return 0;
-+			}
-+			e = b + (s - 1);
-+			p = b + diff;
-+		}
- 		*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