fixed character count in doscan
This commit is contained in:
parent
fbe4a79045
commit
21f1ef5a6c
1 changed files with 74 additions and 79 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue