fixed character count in doscan

This commit is contained in:
eck 1990-07-11 09:08:33 +00:00
parent fbe4a79045
commit 21f1ef5a6c

View file

@ -173,7 +173,8 @@ _doscan(register FILE *stream, const char *format, va_list ap)
int conv = 0; /* # of conversions */ int conv = 0; /* # of conversions */
int base; /* conversion base */ int base; /* conversion base */
unsigned long val; /* an integer value */ unsigned long val; /* an integer value */
char *str, *tmp_string; /* temporary pointers */ register char *str; /* temporary pointer */
char *tmp_string; /* ditto */
unsigned width; /* width of field */ unsigned width; /* width of field */
int flags; /* some flags */ int flags; /* some flags */
int reverse; /* reverse the checking in [...] */ int reverse; /* reverse the checking in [...] */
@ -188,7 +189,7 @@ _doscan(register FILE *stream, const char *format, va_list ap)
while (1) { while (1) {
if (isspace(*format)) { if (isspace(*format)) {
while (isspace(*format)) while (isspace(*format))
++format; /* skip whitespace */ format++; /* skip whitespace */
ic = getc(stream); ic = getc(stream);
nrchars++; nrchars++;
while (isspace (ic)) { while (isspace (ic)) {
@ -200,19 +201,16 @@ _doscan(register FILE *stream, const char *format, va_list ap)
} }
if (!*format) break; /* end of format */ if (!*format) break; /* end of format */
ic = getc(stream);
nrchars++;
if (ic == EOF)
return conv ? done : EOF;
if (*format != '%') { if (*format != '%') {
if (ic != *format) ic = getc(stream);
break; /* matching error */ nrchars++;
++format; if (ic != *format++) break; /* error */
continue; continue;
} }
++format; format++;
if (*format == '%') { if (*format == '%') {
ic = getc(stream);
nrchars++;
if (ic == '%') { if (ic == '%') {
format++; format++;
continue; continue;
@ -221,7 +219,7 @@ _doscan(register FILE *stream, const char *format, va_list ap)
} }
flags = 0; flags = 0;
if (*format == '*') { if (*format == '*') {
++format; format++;
flags |= FL_NOASSIGN; flags |= FL_NOASSIGN;
} }
if (isdigit (*format)) { if (isdigit (*format)) {
@ -237,21 +235,23 @@ _doscan(register FILE *stream, const char *format, va_list ap)
} }
kind = *format; kind = *format;
if ((kind != 'c') && (kind != '[') && (kind != 'n')) { if ((kind != 'c') && (kind != '[') && (kind != 'n')) {
while (ic != EOF && isspace(ic)) { do {
ic = getc(stream); ic = getc(stream);
nrchars++; nrchars++;
} } while (isspace(ic));
if (ic == EOF) return conv ? done : EOF; if (ic == EOF) break; /* outer while */
} else if (kind != 'n') { /* %c or %[ */
ic = getc(stream);
if (ic == EOF) break; /* outer while */
nrchars++;
} }
conv++;
switch (kind) { switch (kind) {
default: default:
if (kind == ic) continue; /* not recognized, like %q */
return conv || (ic != EOF) ? done : EOF;
break; break;
case 'n': case 'n':
if (ic != EOF) ungetc(ic, stream); if (!(flags & FL_NOASSIGN)) { /* silly, though */
nrchars--;
if (!(flags & FL_NOASSIGN)) {
if (flags & FL_SHORT) if (flags & FL_SHORT)
*va_arg(ap, short *) = (short) nrchars; *va_arg(ap, short *) = (short) nrchars;
else if (flags & FL_LONG) else if (flags & FL_LONG)
@ -270,16 +270,22 @@ _doscan(register FILE *stream, const char *format, va_list ap)
case 'u': /* unsigned */ case 'u': /* unsigned */
case 'x': /* hexadecimal */ case 'x': /* hexadecimal */
case 'X': /* ditto */ case 'X': /* ditto */
if (!(flags & FL_WIDTHSPEC)) if (!(flags & FL_WIDTHSPEC) || width > NUMLEN)
width = NUMLEN; width = NUMLEN;
if (!width) { if (!width) return done;
if (ic != EOF) ungetc(ic, stream);
return done;
}
str = o_collect(ic, stream, kind, width, &base); str = o_collect(ic, stream, kind, width, &base);
if (str < inp_buf if (str < inp_buf
|| (str == inp_buf && *str == '-')) return done; || (str == inp_buf
nrchars += str - inp_buf + 1; && (*str == '-'
|| *str == '+'))) return done;
/*
* Although the length of the number is str-inp_buf+1
* we don't add the 1 since we counted it already
*/
nrchars += str - inp_buf;
if (!(flags & FL_NOASSIGN)) { if (!(flags & FL_NOASSIGN)) {
if (kind == 'd' || kind == 'i') if (kind == 'd' || kind == 'i')
val = strtol(inp_buf, &tmp_string, base); val = strtol(inp_buf, &tmp_string, base);
@ -291,23 +297,18 @@ _doscan(register FILE *stream, const char *format, va_list ap)
*va_arg(ap, unsigned short *) = (unsigned short) val; *va_arg(ap, unsigned short *) = (unsigned short) val;
else else
*va_arg(ap, unsigned *) = (unsigned) val; *va_arg(ap, unsigned *) = (unsigned) val;
done++;
} }
break; break;
case 'c': case 'c':
if (!(flags & FL_WIDTHSPEC)) if (!(flags & FL_WIDTHSPEC))
width = 1; width = 1;
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
tmp_string = va_arg(ap, char *); str = va_arg(ap, char *);
if (!width) { if (!width) return done;
if (ic != EOF) ungetc(ic, stream);
return done;
}
if (!(flags & FL_NOASSIGN) && (ic != EOF))
++done;
while (width && ic != EOF) { while (width && ic != EOF) {
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
*tmp_string++ = (char) ic; *str++ = (char) ic;
if (--width) { if (--width) {
ic = getc(stream); ic = getc(stream);
nrchars++; nrchars++;
@ -319,21 +320,16 @@ _doscan(register FILE *stream, const char *format, va_list ap)
nrchars--; nrchars--;
} }
break; break;
case 's': case 's':
if (!(flags & FL_WIDTHSPEC)) if (!(flags & FL_WIDTHSPEC))
width = 0xffff; width = 0xffff;
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
tmp_string = va_arg(ap, char *); str = va_arg(ap, char *);
if (!width) { if (!width) return done;
if (ic != EOF) ungetc(ic,stream);
return done;
}
if (!(flags & FL_NOASSIGN))
++done;
while (width && ic != EOF && !isspace(ic)) { while (width && ic != EOF && !isspace(ic)) {
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
*tmp_string++ = (char) ic; *str++ = (char) ic;
if (--width) { if (--width) {
ic = getc(stream); ic = getc(stream);
nrchars++; nrchars++;
@ -341,33 +337,29 @@ _doscan(register FILE *stream, const char *format, va_list ap)
} }
/* terminate the string */ /* terminate the string */
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
*tmp_string = '\0'; *str = '\0';
if (width) { if (width) {
if (ic != EOF) ungetc(ic,stream); if (ic != EOF) ungetc(ic,stream);
nrchars--; nrchars--;
} }
break; break;
case '[': case '[':
{ int old_nrchars;
if (!(flags & FL_WIDTHSPEC)) if (!(flags & FL_WIDTHSPEC))
width = 0xffff; width = 0xffff;
if (!width) return done;
if (!width) { if ( *++format == '^' ) {
if (ic != EOF) ungetc(ic, stream);
return done;
}
if ( *(++format) == '^' ) {
reverse = 1; reverse = 1;
format++; format++;
} else } else
reverse = 0; reverse = 0;
for (tmp_string = Xtable; tmp_string < &Xtable[NR_CHARS] for (str = Xtable; str < &Xtable[NR_CHARS]
; tmp_string++) ; str++)
*tmp_string = 0; *str = 0;
if (*format == ']') Xtable[*format++] = 1; if (*format == ']') Xtable[*format++] = 1;
while (*format && *format != ']') { while (*format && *format != ']') {
Xtable[*format++] = 1; Xtable[*format++] = 1;
if (*format == '-') { if (*format == '-') {
@ -385,51 +377,53 @@ _doscan(register FILE *stream, const char *format, va_list ap)
else Xtable['-'] = 1; else Xtable['-'] = 1;
} }
} }
if (!*format) { if (!*format) return done;
if (ic != EOF) ungetc(ic,stream);
return done;
}
old_nrchars = nrchars; if (!(Xtable[ic] ^ reverse)) return done;
if (!(flags & FL_NOASSIGN))
tmp_string = va_arg(ap, char *);
if (ic == EOF || !(Xtable[ic] ^ reverse)) {
if (ic != EOF) ungetc(ic, stream);
return done;
}
while (width && ic != EOF && (Xtable[ic] ^ reverse)) { if (!(flags & FL_NOASSIGN))
str = va_arg(ap, char *);
do {
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
*tmp_string++ = (char) ic; *str++ = (char) ic;
if (--width) { if (--width) {
ic = getc(stream); ic = getc(stream);
nrchars++; nrchars++;
} }
} } while (width && ic != EOF && (Xtable[ic] ^ reverse));
if (width) { if (width) {
if (ic != EOF) ungetc(ic, stream); if (ic != EOF) ungetc(ic, stream);
nrchars--; nrchars--;
} }
if (!(flags & FL_NOASSIGN)) { /* terminate string */ if (!(flags & FL_NOASSIGN)) { /* terminate string */
*tmp_string = '\0'; *str = '\0';
++done;
} }
break; break;
}
#ifndef NOFLOAT: #ifndef NOFLOAT:
case 'e': case 'e':
case 'E': case 'E':
case 'f': case 'f':
case 'g': case 'g':
case 'G': case 'G':
if (!(flags & FL_WIDTHSPEC)) width = NUMLEN; if (!(flags & FL_WIDTHSPEC) || width > NUMLEN)
if (width > NUMLEN) width = NUMLEN; width = NUMLEN;
if (!width) return done; if (!width) return done;
str = f_collect(ic, stream, width); str = f_collect(ic, stream, width);
if (str < inp_buf if (str < inp_buf
|| (str == inp_buf && *str == '-')) return done; || (str == inp_buf
nrchars += str - inp_buf + 1; && (*str == '-'
|| *str == '+'))) return done;
/*
* Although the length of the number is str-inp_buf+1
* we don't add the 1 since we counted it already
*/
nrchars += str - inp_buf;
if (!(flags & FL_NOASSIGN)) { if (!(flags & FL_NOASSIGN)) {
ld_val = strtod(inp_buf, &tmp_string); ld_val = strtod(inp_buf, &tmp_string);
if (flags & FL_LONGDOUBLE) if (flags & FL_LONGDOUBLE)
@ -439,12 +433,13 @@ _doscan(register FILE *stream, const char *format, va_list ap)
*va_arg(ap, double *) = (double) ld_val; *va_arg(ap, double *) = (double) ld_val;
else else
*va_arg(ap, float *) = (float) ld_val; *va_arg(ap, float *) = (float) ld_val;
done++;
} }
break; break;
#endif #endif
} /* end switch */ } /* end switch */
++format; conv++;
if (!(flags & FL_NOASSIGN) && kind != 'n') done++;
format++;
} }
return conv || (ic != EOF) ? done : EOF; return conv || (ic != EOF) ? done : EOF;
} }