#include "stdio" scanf(fs) /* standard routine */ char *fs; { int getc(); int ungetc(); return _input(stdin, &fs, getc, ungetc); } fscanf(fp, fs) /* standard routine */ char *fp, *fs; { int getc(); int ungetc(); return _input(fp, &fs, getc, ungetc); } sscanf(s,fs) /* standard routine */ char *s, *fs; { int _mread(); int _mungetc(); return _input(&s, &fs, _mread, _mungetc); } _input(fp, parms, read, ungetc) /* input routine for */ /* scanf, sscanf, fscanf */ char *fp; /* pointer to input */ char **parms; /* pointer to addr of parameters */ int (*read)(); /* character read function */ int (*ungetc)(); /* character unget function */ { union { /* buffer for numeric & string storage */ int integer; char string[81]; } buffer; char *format; /* format string pointer */ char c; /* format string character */ char **ptr; /* pointer to pointer */ int base; /* number base */ int value; /* binary value of digit */ int pflag; /* real precision flag */ int asflag; /* assignment supression flag */ int sflag; /* sign flag */ int ch; /* input character */ int temp; /* temporary storage */ int i; /* loop counter */ int count; /* character count */ int width; /* maximum field width */ int status; /* status returned from the read */ int valid; /* valid real number format */ int (*acc)(); /* pointer to accumulate function */ int (*neg)(); /* pointer to negate function */ int (*asn)(); /* pointer to assign function */ int _digit(); /* decode digit function */ int _dint(); /* decode integer function */ int _dlong(); /* decode long function */ int _negint(); /* negate integer function */ int _neglong(); /* negate long function */ int _aint(); /* assign integer function */ int _along(); /* assign long function */ int _atoi(); /* convert string to integer */ int isspace(); /* whitespace function */ int isdigit(); /* digit function */ STRING *stods(); /* convert string to dynamic string */ format = *parms--; /* format points to format string */ count = 0; /* number of parameters read */ while (c = *format++) { if (isspace(c)) continue; /* skip white space */ if (c != '%') { while (isspace(ch = (*read)(fp))); if (ch == c) continue; else return (ch == EOF) ? EOF : count; } pflag = sflag = asflag = 0; if ((*format) == '*') { /* check for assignment suppression */ ++asflag; ++format; } acc = _dint; neg = _negint; asn = _aint; width = isdigit(*format) ? _atoi(&format) : -1; if (toupper(*format) == 'L') { /* check for double precision */ ++pflag; ++format; acc = _dlong; neg = _neglong; asn = _along; } c = *format++; switch (toupper(c)) { case 'H': /* signed decimal */ pflag++; case 'D': case 'U': base = 10; goto decode; case 'O': /* unsigned octal */ base = 8; goto decode; case 'X': /* unsigned hexadecimal */ base = 16; decode: for (i=0; i<5; ++i) buffer.string[i] = '\0'; while ((ch=(*read)(fp))==' ' || ch == '\t' || ch == '\n'); if (ch == EOF) return EOF; if (width && (ch == '+' || ch == '-')) { if (ch == '-') ++sflag; ch = (*read)(fp); --width; } if (width && base == 16 && ch == '0') { temp = (*read)(fp); --width; if (toupper(temp) == 'X' && width) { ch = (*read)(fp); --width; } else { (*ungetc)(temp, fp); ++width; } } if ((value = _digit(ch, base)) == -1) return count; while (width && (value != -1)) { (*acc)(&buffer.integer, value, base); ch = (*read)(fp); --width; value = _digit(ch,base); } (*ungetc)(ch, fp); if (sflag) (*neg)(&buffer.integer); if (!asflag) { (*asn)(&buffer.integer, *parms, pflag); ++count; --parms; } break; case 'S': /* string */ while ((ch=(*read)(fp))==' ' || ch == '\t' || ch == '\n'); if (ch == EOF) return EOF; while (width && ch != ' ' && ch != '\t' && ch != '\n' && ch != EOF) { if (!asflag) *(*parms)++ = ch; ch = (*read)(fp); --width; } (*ungetc)(ch, fp); if (!asflag) { *(*parms) = '\0'; ++count; --parms; } break; case 'C': /* character */ if ((ch = (*read)(fp)) == EOF) return EOF; else if (!asflag) { *(*parms) = ch; ++count; --parms; } break; case 'E': case 'F': /* floating point */ while ((ch=(*read)(fp))==' ' || ch == '\t' || ch == '\n'); if (ch == EOF) return EOF; i = 0; valid = 0; if (width && (ch == '+' || ch == '-')) { buffer.string[i++] = ch; ch = (*read)(fp); --width; } while (width && ch >= '0' && ch <= '9') { buffer.string[i++] = ch; ch = (*read)(fp); --width; ++valid; } if (width && ch == '.') { buffer.string[i++] = ch; ch = (*read)(fp); --width; while (width && ch >= '0' && ch <= '9') { buffer.string[i++] = ch; ch = (*read)(fp); --width; ++valid; } } if (width && (ch == 'E' || ch == 'e' || ch == 'D')) { if (!valid) return count; valid = 0; buffer.string[i++] = 'E'; ch = (*read)(fp); --width; if (width && (ch == '+' || ch == '-')) { buffer.string[i++] = ch; ch = (*read)(fp); --width; } while (width && isdigit(ch)) { buffer.string[i++] = ch; ch = (*read)(fp); --width; ++valid; } } (*ungetc)(ch, fp); if (!valid) return count; buffer.string[i] = '\0'; if (!asflag) { _dreal(buffer.string, *parms, pflag); ++count; --parms; } break; case 'Y': /* dynamic string */ while ((ch=(*read)(fp))==' ' || ch == '\t' || ch == '\n'); if (ch == EOF) return EOF; i = 0; while (width && ch != ' ' && ch != '\t' && ch != '\n' && ch != EOF) { if (i < 80) buffer.string[i++] = ch; ch = (*read)(fp); --width; } buffer.string[i] = '\0'; (*ungetc)(ch,fp); if (!asflag) { ptr = *parms; *ptr = stods(buffer.string); ++count; --parms; } break; default : return count; } } return count; } _negint(iptr) /* negate integer */ int *iptr; /* pointer to integer */ { *iptr = -*iptr; } _aint(iptr1, iptr2, pflag) /* assign integer */ int *iptr1; /* pointer to fp */ int *iptr2; /* pointer to destination */ int pflag; /* short integer flag */ { short *sptr; if (pflag) { sptr = iptr2; *sptr = *iptr1; } else *iptr2 = *iptr1; } _neglong(lptr) /* negate long */ long *lptr; /* pointer to long integer */ { *lptr = -*lptr; } _along(lptr1, lptr2) /* assign long */ long *lptr1; /* pointer to fp */ long *lptr2; /* pointer to destination */ { *lptr2 = *lptr1; } _digit(ch, base) /* decode ch to binary */ int ch; /* character to decode */ int base; /* number base */ { if (ch >= '0' && ch <= '9') ch -= 48; else if (isalpha(ch = toupper(ch))) ch -= 55; else return -1; if (ch < base) return ch; else return -1; } _dint(iptr, digit, base) /* decode an integer */ int *iptr; /* pointer to integer */ int digit; /* digit to add to integer */ int base; /* number base */ { *iptr = *iptr * base + digit; } _dlong(lptr, digit, base) /* decode a long */ long *lptr; /* pointer to long */ int digit; /* digit to add to long */ int base; /* number base */ { *lptr = *lptr * base + digit; } _dreal(s, fptr, pflag) /* decode a real */ char *s; /* pointer to decode string */ float *fptr; /* pointer to float */ int pflag; /* precision flag */ { double atof(); /* string to double function */ double *dptr; /* pointer to double */ if (pflag) { dptr = fptr; *dptr = atof(s); } else *fptr = (float) atof(s); } _mread(s) /* read character from string */ char **s; /* pointer to string */ { if (*(*s) != '\0') return *(*s)++; else return EOF; } _mungetc(c,s) /* unget character to string */ int c; /* dumy parameter */ char **s; /* pointer to string pointer */ { --(*s); return c; }