diff options
Diffstat (limited to 'newlib/libc/machine/powerpc/vfscanf.c')
-rw-r--r-- | newlib/libc/machine/powerpc/vfscanf.c | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/newlib/libc/machine/powerpc/vfscanf.c b/newlib/libc/machine/powerpc/vfscanf.c index 47b0d1c61..602fd7735 100644 --- a/newlib/libc/machine/powerpc/vfscanf.c +++ b/newlib/libc/machine/powerpc/vfscanf.c @@ -224,8 +224,8 @@ _DEFUN (vfscanf, (fp, fmt, ap), _CONST char *fmt _AND va_list ap) { - CHECK_INIT(_REENT); - return __svfscanf_r (_REENT, fp, fmt, ap); + CHECK_INIT(fp); + return __svfscanf_r (fp->_data, fp, fmt, ap); } int @@ -803,7 +803,6 @@ __svfscanf_r (rptr, fp, fmt0, ap) case CT_INT: { unsigned int_width_left = 0; - int skips = 0; int_width = width; #ifdef hardway if (int_width == 0 || int_width > sizeof (buf) - 1) @@ -853,7 +852,6 @@ __svfscanf_r (rptr, fp, fmt0, ap) int_width_left--; int_width++; } - ++skips; goto skip; /* 1 through 7 always legal */ @@ -1011,7 +1009,7 @@ __svfscanf_r (rptr, fp, fmt0, ap) if (!(flags & VECTOR)) nassigned++; } - nread += p - buf + skips; + nread += p - buf; break; } @@ -1260,3 +1258,106 @@ match_failure: return nassigned; } +/* + * Fill in the given table from the scanset at the given format + * (just after `['). Return a pointer to the character past the + * closing `]'. The table has a 1 wherever characters should be + * considered part of the scanset. + */ + +/*static*/ +u_char * +__sccl (tab, fmt) + register char *tab; + register u_char *fmt; +{ + register int c, n, v; + + /* first `clear' the whole table */ + c = *fmt++; /* first char hat => negated scanset */ + if (c == '^') + { + v = 1; /* default => accept */ + c = *fmt++; /* get new first char */ + } + else + v = 0; /* default => reject */ + /* should probably use memset here */ + for (n = 0; n < 256; n++) + tab[n] = v; + if (c == 0) + return fmt - 1; /* format ended before closing ] */ + + /* + * Now set the entries corresponding to the actual scanset to the + * opposite of the above. + * + * The first character may be ']' (or '-') without being special; the + * last character may be '-'. + */ + + v = 1 - v; + for (;;) + { + tab[c] = v; /* take character c */ + doswitch: + n = *fmt++; /* and examine the next */ + switch (n) + { + + case 0: /* format ended too soon */ + return fmt - 1; + + case '-': + /* + * A scanset of the form [01+-] is defined as `the digit 0, the + * digit 1, the character +, the character -', but the effect of a + * scanset such as [a-zA-Z0-9] is implementation defined. The V7 + * Unix scanf treats `a-z' as `the letters a through z', but treats + * `a-a' as `the letter a, the character -, and the letter a'. + * + * For compatibility, the `-' is not considerd to define a range if + * the character following it is either a close bracket (required by + * ANSI) or is not numerically greater than the character we just + * stored in the table (c). + */ + n = *fmt; + if (n == ']' || n < c) + { + c = '-'; + break; /* resume the for(;;) */ + } + fmt++; + do + { /* fill in the range */ + tab[++c] = v; + } + while (c < n); +#if 1 /* XXX another disgusting compatibility hack */ + /* + * Alas, the V7 Unix scanf also treats formats such + * as [a-c-e] as `the letters a through e'. This too + * is permitted by the standard.... + */ + goto doswitch; +#else + c = *fmt++; + if (c == 0) + return fmt - 1; + if (c == ']') + return fmt; +#endif + + break; + + + case ']': /* end of scanset */ + return fmt; + + default: /* just another character */ + c = n; + break; + } + } + /* NOTREACHED */ +} |