X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/59e0d9fe772464b93d835d2a2964457702469a43..224c70764cab4e0e39a26aaf3ad3016552f62f55:/stdio/FreeBSD/vfscanf.c.patch diff --git a/stdio/FreeBSD/vfscanf.c.patch b/stdio/FreeBSD/vfscanf.c.patch index 75f89cc..54d9799 100644 --- a/stdio/FreeBSD/vfscanf.c.patch +++ b/stdio/FreeBSD/vfscanf.c.patch @@ -1,17 +1,77 @@ ---- vfscanf.c.orig Tue Nov 18 16:48:06 2003 -+++ vfscanf.c Tue Nov 18 17:35:55 2003 -@@ -99,7 +99,9 @@ +--- vfscanf.c.orig 2004-11-25 11:38:35.000000000 -0800 ++++ vfscanf.c 2005-05-20 00:46:37.000000000 -0700 +@@ -40,6 +40,8 @@ + #include + __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.37 2004/05/02 10:55:05 das Exp $"); + ++#include "xlocale_private.h" ++ + #include "namespace.h" + #include + #include +@@ -97,10 +99,21 @@ + #define CT_INT 3 /* %[dioupxX] conversion */ #define CT_FLOAT 4 /* %[efgEFG] conversion */ - static const u_char *__sccl(char *, const u_char *); +-static const u_char *__sccl(char *, const u_char *); -static int parsefloat(FILE *, char *, char *); -+#ifdef FLOATING_POINT -+static int parsefloat(FILE *, char **, size_t); -+#endif /* FLOATING_POINT */ ++static const u_char *__sccl(char *, const u_char *, locale_t); ++#ifndef NO_FLOATING_POINT ++static int parsefloat(FILE *, char **, size_t, locale_t); ++#endif /* !NO_FLOATING_POINT */ ++/* ++ * For ppc, we need to have the 64-bit long double version defining storage for ++ * __scanfdebug, to be compatible with 10.3. For ppc64 and i386, we want the ++ * storage defined in the only version. ++ */ ++#if defined(__ppc__) && !defined(BUILDING_VARIANT) ++extern int __scanfdebug; ++#else /* !__ppc__ || BUILDING_VARIANT */ int __scanfdebug = 0; ++#endif /* __ppc__ && !BUILDING_VARIANT */ + + __weak_reference(__vfscanf, vfscanf); -@@ -133,7 +135,6 @@ +@@ -108,12 +121,24 @@ + * __vfscanf - MT-safe version + */ + int +-__vfscanf(FILE *fp, char const *fmt0, va_list ap) ++__vfscanf(FILE * __restrict fp, char const * __restrict fmt0, va_list ap) ++{ ++ int ret; ++ ++ FLOCKFILE(fp); ++ ret = __svfscanf_l(fp, __current_locale(), fmt0, ap); ++ FUNLOCKFILE(fp); ++ return (ret); ++} ++ ++int ++vfscanf_l(FILE * __restrict fp, locale_t loc, char const * __restrict fmt0, va_list ap) + { + int ret; + ++ NORMALIZE_LOCALE(loc); + FLOCKFILE(fp); +- ret = __svfscanf(fp, fmt0, ap); ++ ret = __svfscanf_l(fp, loc, fmt0, ap); + FUNLOCKFILE(fp); + return (ret); + } +@@ -121,8 +146,8 @@ + /* + * __svfscanf - non-MT-safe version of __vfscanf + */ +-int +-__svfscanf(FILE *fp, const char *fmt0, va_list ap) ++__private_extern__ int ++__svfscanf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_list ap) + { + const u_char *fmt = (const u_char *)fmt0; + int c; /* character from format, or conversion */ +@@ -132,7 +157,6 @@ int flags; /* flags as defined above */ char *p0; /* saves original value of p when necessary */ int nassigned; /* number of fields assigned */ @@ -19,15 +79,68 @@ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ char ccltab[256]; /* character class table for %[...] */ -@@ -150,7 +151,6 @@ +@@ -140,24 +164,29 @@ + wchar_t *wcp; /* handy wide character pointer */ + wchar_t *wcp0; /* saves original value of wcp */ + size_t nconv; /* length of multibyte sequence converted */ ++ int index; /* %index$, zero if unset */ ++ va_list ap_orig; /* to reset ap to first argument */ + static const mbstate_t initial; + mbstate_t mbs; ++ int mb_cur_max; + + /* `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 }; + ++ NORMALIZE_LOCALE(loc); ++ mb_cur_max = MB_CUR_MAX_L(loc); ORIENT(fp, -1); nassigned = 0; - nconversions = 0; nread = 0; ++ va_copy(ap_orig, ap); for (;;) { c = *fmt++; -@@ -288,7 +288,6 @@ + if (c == 0) + return (nassigned); +- if (isspace(c)) { +- while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) ++ if (isspace_l(c, loc)) { ++ while ((fp->_r > 0 || __srefill(fp) == 0) && isspace_l(*fp->_p, loc)) + nread++, fp->_r--, fp->_p++; + continue; + } +@@ -181,6 +210,18 @@ + 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; +@@ -267,7 +308,7 @@ + break; + + case '[': +- fmt = __sccl(ccltab, fmt); ++ fmt = __sccl(ccltab, fmt, loc); + flags |= NOSKIP; + c = CT_CCL; + break; +@@ -288,7 +329,6 @@ break; case 'n': @@ -35,7 +148,34 @@ if (flags & SUPPRESS) /* ??? */ continue; if (flags & SHORTSHORT) -@@ -421,7 +420,6 @@ +@@ -330,7 +370,7 @@ + * that suppress this. + */ + if ((flags & NOSKIP) == 0) { +- while (isspace(*fp->_p)) { ++ while (isspace_l(*fp->_p, loc)) { + nread++; + if (--fp->_r > 0) + fp->_p++; +@@ -360,7 +400,7 @@ + wcp = NULL; + n = 0; + while (width != 0) { +- if (n == MB_CUR_MAX) { ++ if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } +@@ -368,7 +408,7 @@ + fp->_p++; + fp->_r--; + mbs = initial; +- nconv = mbrtowc(wcp, buf, n, &mbs); ++ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; +@@ -421,7 +461,6 @@ nread += r; nassigned++; } @@ -43,7 +183,36 @@ break; case CT_CCL: -@@ -525,7 +523,6 @@ +@@ -440,7 +479,7 @@ + n = 0; + nchars = 0; + while (width != 0) { +- if (n == MB_CUR_MAX) { ++ if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } +@@ -448,7 +487,7 @@ + fp->_p++; + fp->_r--; + mbs = initial; +- nconv = mbrtowc(wcp, buf, n, &mbs); ++ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; +@@ -456,8 +495,8 @@ + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { +- if (wctob(*wcp) != EOF && +- !ccltab[wctob(*wcp)]) { ++ if (wctob_l(*wcp, loc) != EOF && ++ !ccltab[wctob_l(*wcp, loc)]) { + while (n != 0) { + n--; + __ungetc(buf[n], +@@ -525,7 +564,6 @@ nassigned++; } nread += n; @@ -51,7 +220,54 @@ break; case CT_STRING: -@@ -607,7 +604,6 @@ +@@ -540,8 +578,8 @@ + else + wcp = &twc; + n = 0; +- while (!isspace(*fp->_p) && width != 0) { +- if (n == MB_CUR_MAX) { ++ while (width != 0) { ++ if (n == mb_cur_max) { + fp->_flags |= __SERR; + goto input_failure; + } +@@ -549,7 +587,7 @@ + fp->_p++; + fp->_r--; + mbs = initial; +- nconv = mbrtowc(wcp, buf, n, &mbs); ++ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc); + if (nconv == (size_t)-1) { + fp->_flags |= __SERR; + goto input_failure; +@@ -557,7 +595,7 @@ + if (nconv == 0) + *wcp = L'\0'; + if (nconv != (size_t)-2) { +- if (iswspace(*wcp)) { ++ if (iswspace_l(*wcp, loc)) { + while (n != 0) { + n--; + __ungetc(buf[n], +@@ -585,7 +623,7 @@ + } + } else if (flags & SUPPRESS) { + n = 0; +- while (!isspace(*fp->_p)) { ++ while (!isspace_l(*fp->_p, loc)) { + n++, fp->_r--, fp->_p++; + if (--width == 0) + break; +@@ -595,7 +633,7 @@ + nread += n; + } else { + p0 = p = va_arg(ap, char *); +- while (!isspace(*fp->_p)) { ++ while (!isspace_l(*fp->_p, loc)) { + fp->_r--; + *p++ = *fp->_p++; + if (--width == 0) +@@ -607,7 +645,6 @@ nread += p - p0; nassigned++; } @@ -59,14 +275,26 @@ continue; case CT_INT: -@@ -758,39 +754,42 @@ +@@ -738,9 +775,9 @@ + + *p = 0; + if ((flags & UNSIGNED) == 0) +- res = strtoimax(buf, (char **)NULL, base); ++ res = strtoimax_l(buf, (char **)NULL, base, loc); + else +- res = strtoumax(buf, (char **)NULL, base); ++ res = strtoumax_l(buf, (char **)NULL, base, loc); + if (flags & POINTER) + *va_arg(ap, void **) = + (void *)(uintptr_t)res; +@@ -763,43 +800,48 @@ nassigned++; } nread += p - buf; - nconversions++; break; - #ifdef FLOATING_POINT + #ifndef NO_FLOATING_POINT case CT_FLOAT: + { + char *pbuf; @@ -74,23 +302,20 @@ - if (width == 0 || width > sizeof(buf) - 1) - width = sizeof(buf) - 1; - if ((width = parsefloat(fp, buf, buf + width)) == 0) -+ if ((width = parsefloat(fp, &pbuf, width)) == 0) { -+ if (pbuf) -+ free(pbuf); ++ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0) goto match_failure; -+ } if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { - long double res = strtold(buf, &p); -+ long double res = strtold(pbuf, &p); ++ long double res = strtold_l(pbuf, &p, loc); *va_arg(ap, long double *) = res; } else if (flags & LONG) { - double res = strtod(buf, &p); -+ double res = strtod(pbuf, &p); ++ double res = strtod_l(pbuf, &p, loc); *va_arg(ap, double *) = res; } else { - float res = strtof(buf, &p); -+ float res = strtof(pbuf, &p); ++ float res = strtof_l(pbuf, &p, loc); *va_arg(ap, float *) = res; } - if (__scanfdebug && p - buf != width) @@ -100,10 +325,9 @@ } nread += width; - nconversions++; -+ free(pbuf); break; + } - #endif /* FLOATING_POINT */ + #endif /* !NO_FLOATING_POINT */ } } input_failure: @@ -112,33 +336,122 @@ match_failure: return (nassigned); } -@@ -910,7 +909,7 @@ - #ifdef FLOATING_POINT ++int ++__svfscanf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) ++{ ++ return __svfscanf_l(fp, __current_locale(), fmt0, ap); ++} ++ + /* + * Fill in the given table from the scanset at the given format + * (just after `['). Return a pointer to the character past the +@@ -807,9 +849,10 @@ + * considered part of the scanset. + */ + static const u_char * +-__sccl(tab, fmt) ++__sccl(tab, fmt, loc) + char *tab; + const u_char *fmt; ++ locale_t loc; + { + int c, n, v, i; + +@@ -845,6 +888,7 @@ + return (fmt - 1); + + case '-': ++ { + /* + * A scanset of the form + * [01+-] +@@ -865,8 +909,8 @@ + */ + n = *fmt; + if (n == ']' +- || (__collate_load_error ? n < c : +- __collate_range_cmp (n, c) < 0 ++ || (loc->__collate_load_error ? n < c : ++ __collate_range_cmp (n, c, loc) < 0 + ) + ) { + c = '-'; +@@ -874,14 +918,14 @@ + } + fmt++; + /* fill in the range */ +- if (__collate_load_error) { ++ if (loc->__collate_load_error) { + do { + tab[++c] = v; + } while (c < n); + } else { + for (i = 0; i < 256; i ++) +- if ( __collate_range_cmp (c, i) < 0 +- && __collate_range_cmp (i, n) <= 0 ++ if ( __collate_range_cmp (c, i, loc) < 0 ++ && __collate_range_cmp (i, n, loc) <= 0 + ) + tab[i] = v; + } +@@ -901,7 +945,7 @@ + return (fmt); + #endif + break; +- ++ } + case ']': /* end of scanset */ + return (fmt); + +@@ -915,18 +959,42 @@ + + #ifndef NO_FLOATING_POINT static int -parsefloat(FILE *fp, char *buf, char *end) -+parsefloat(FILE *fp, char **buf, size_t width) ++parsefloat(FILE *fp, char **buf, size_t width, locale_t loc) { char *commit, *p; int infnanpos = 0; -@@ -921,7 +920,16 @@ + enum { + S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX, +- S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS ++ S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS, S_DECIMAL_POINT + } state = S_START; unsigned char c; - char decpt = *localeconv()->decimal_point; +- char decpt = *localeconv()->decimal_point; ++ unsigned char *decpt = (unsigned char *)localeconv_l(loc)->decimal_point; ++ char *decpt_start; _Bool gotmantdig = 0, ishex = 0; -+ char *b, *e; +- ++ static char *b = NULL; ++ static size_t bsiz = 0; ++ char *e; + size_t s; - -+ s = (width == 0 ? BUF : width + 1); -+ b = (char *)malloc(s); -+ if (b == NULL) { -+ *buf = NULL; -+ return 0; ++ ++ if (bsiz = 0) { ++ b = (char *)malloc(BUF); ++ if (b == NULL) { ++ *buf = NULL; ++ return 0; ++ } ++ bsiz = BUF; ++ } ++ s = (width == 0 ? BUF : (width + 1)); ++ if (s > bsiz) { ++ b = (char *)reallocf(b, s); ++ 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 -@@ -931,8 +939,8 @@ +@@ -936,8 +1004,8 @@ * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ @@ -149,25 +462,94 @@ c = *fp->_p; reswitch: switch (state) { -@@ -1046,6 +1054,17 @@ +@@ -997,7 +1065,7 @@ + if (c == ')') { + commit = p; + infnanpos = -2; +- } else if (!isalnum(c) && c != '_') ++ } else if (!isalnum_l(c, loc) && c != '_') + goto parsedone; + break; + } +@@ -1013,16 +1081,33 @@ + goto reswitch; + } + case S_DIGITS: +- if ((ishex && isxdigit(c)) || isdigit(c)) ++ if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) + gotmantdig = 1; + else { +- state = S_FRAC; +- if (c != decpt) +- goto reswitch; ++ state = S_DECIMAL_POINT; ++ decpt_start = p; ++ goto reswitch; + } + if (gotmantdig) + commit = p; + break; ++ case S_DECIMAL_POINT: ++ if (*decpt == 0) { ++ if (gotmantdig) ++ commit = p - 1; ++ state = S_FRAC; ++ goto reswitch; ++ } ++ if (*decpt++ == c) ++ break; ++ /* not decimal point */ ++ state = S_FRAC; ++ if (decpt_start == p) ++ goto reswitch; ++ while (decpt_start < --p) ++ __ungetc(*(u_char *)p, fp); ++ c = *(u_char *)p; ++ goto reswitch; + case S_FRAC: + if (((c == 'E' || c == 'e') && !ishex) || + ((c == 'P' || c == 'p') && ishex)) { +@@ -1030,7 +1115,7 @@ + goto parsedone; + else + state = S_EXP; +- } else if ((ishex && isxdigit(c)) || isdigit(c)) { ++ } else if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) { + commit = p; + gotmantdig = 1; + } else +@@ -1043,7 +1128,7 @@ + else + goto reswitch; + case S_EXPDIGITS: +- if (isdigit(c)) ++ if (isdigit_l(c, loc)) + commit = p; + else + goto parsedone; +@@ -1051,6 +1136,21 @@ default: abort(); } + if (p >= e) { -+ size_t diff = (p - b); ++ ssize_t diff = (p - b); ++ ssize_t com = (commit - b); + s += BUF; + b = (char *)reallocf(b, s); + if (b == NULL) { ++ bsiz = 0; + *buf = NULL; + return 0; + } ++ bsiz = s; + e = b + (s - 1); + p = b + diff; ++ commit = b + com; + } *p++ = c; if (--fp->_r > 0) fp->_p++; -@@ -1057,6 +1076,7 @@ +@@ -1062,6 +1162,7 @@ while (commit < --p) __ungetc(*(u_char *)p, fp); *++commit = '\0';