1*9415Smckusick static char sccsid[] = "@(#)vfscanf.c 4.1 (Berkeley) 82/12/03"; 2*9415Smckusick 3*9415Smckusick /* @(#)doscan.c 4.1 (Berkeley) 12/21/80 */ 4*9415Smckusick #include <stdio.h> 5*9415Smckusick #include <ctype.h> 6*9415Smckusick 7*9415Smckusick #define SPC 01 8*9415Smckusick #define STP 02 9*9415Smckusick 10*9415Smckusick #define SHORT 0 11*9415Smckusick #define REGULAR 1 12*9415Smckusick #define LONG 2 13*9415Smckusick #define INT 0 14*9415Smckusick #define FLOAT 1 15*9415Smckusick 16*9415Smckusick char *_getccl(); 17*9415Smckusick 18*9415Smckusick char _sctab[128] = { 19*9415Smckusick 0,0,0,0,0,0,0,0, 20*9415Smckusick 0,SPC,SPC,0,0,0,0,0, 21*9415Smckusick 0,0,0,0,0,0,0,0, 22*9415Smckusick 0,0,0,0,0,0,0,0, 23*9415Smckusick SPC,0,0,0,0,0,0,0, 24*9415Smckusick 0,0,0,0,0,0,0,0, 25*9415Smckusick 0,0,0,0,0,0,0,0, 26*9415Smckusick 0,0,0,0,0,0,0,0, 27*9415Smckusick }; 28*9415Smckusick 29*9415Smckusick _doscan(iop, fmt, argp) 30*9415Smckusick FILE *iop; 31*9415Smckusick register char *fmt; 32*9415Smckusick register int **argp; 33*9415Smckusick { 34*9415Smckusick register int ch; 35*9415Smckusick int nmatch, len, ch1; 36*9415Smckusick int **ptr, fileended, size; 37*9415Smckusick 38*9415Smckusick nmatch = 0; 39*9415Smckusick fileended = 0; 40*9415Smckusick for (;;) switch (ch = *fmt++) { 41*9415Smckusick case '\0': 42*9415Smckusick return (nmatch); 43*9415Smckusick case '%': 44*9415Smckusick if ((ch = *fmt++) == '%') 45*9415Smckusick goto def; 46*9415Smckusick ptr = 0; 47*9415Smckusick if (ch != '*') 48*9415Smckusick ptr = argp++; 49*9415Smckusick else 50*9415Smckusick ch = *fmt++; 51*9415Smckusick len = 0; 52*9415Smckusick size = REGULAR; 53*9415Smckusick while (isdigit(ch)) { 54*9415Smckusick len = len*10 + ch - '0'; 55*9415Smckusick ch = *fmt++; 56*9415Smckusick } 57*9415Smckusick if (len == 0) 58*9415Smckusick len = 30000; 59*9415Smckusick if (ch=='l') { 60*9415Smckusick size = LONG; 61*9415Smckusick ch = *fmt++; 62*9415Smckusick } else if (ch=='h') { 63*9415Smckusick size = SHORT; 64*9415Smckusick ch = *fmt++; 65*9415Smckusick } else if (ch=='[') 66*9415Smckusick fmt = _getccl(fmt); 67*9415Smckusick if (isupper(ch)) { 68*9415Smckusick ch = tolower(ch); 69*9415Smckusick size = LONG; 70*9415Smckusick } 71*9415Smckusick if (ch == '\0') 72*9415Smckusick return(-1); 73*9415Smckusick if (_innum(ptr, ch, len, size, iop, &fileended) && ptr) 74*9415Smckusick nmatch++; 75*9415Smckusick if (fileended) 76*9415Smckusick return(nmatch? nmatch: -1); 77*9415Smckusick break; 78*9415Smckusick 79*9415Smckusick case ' ': 80*9415Smckusick case '\n': 81*9415Smckusick case '\t': 82*9415Smckusick while ((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n') 83*9415Smckusick ; 84*9415Smckusick if (ch1 != EOF) 85*9415Smckusick ungetc(ch1, iop); 86*9415Smckusick break; 87*9415Smckusick 88*9415Smckusick default: 89*9415Smckusick def: 90*9415Smckusick ch1 = getc(iop); 91*9415Smckusick if (ch1 != ch) { 92*9415Smckusick if (ch1==EOF) 93*9415Smckusick return(-1); 94*9415Smckusick ungetc(ch1, iop); 95*9415Smckusick return(nmatch); 96*9415Smckusick } 97*9415Smckusick } 98*9415Smckusick } 99*9415Smckusick 100*9415Smckusick _innum(ptr, type, len, size, iop, eofptr) 101*9415Smckusick int **ptr, *eofptr; 102*9415Smckusick struct _iobuf *iop; 103*9415Smckusick { 104*9415Smckusick extern double atof(); 105*9415Smckusick register char *np; 106*9415Smckusick char numbuf[64]; 107*9415Smckusick register c, base; 108*9415Smckusick int expseen, scale, negflg, c1, ndigit; 109*9415Smckusick long lcval; 110*9415Smckusick 111*9415Smckusick if (type=='c' || type=='s' || type=='[') 112*9415Smckusick return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr)); 113*9415Smckusick lcval = 0; 114*9415Smckusick ndigit = 0; 115*9415Smckusick scale = INT; 116*9415Smckusick if (type=='e'||type=='f') 117*9415Smckusick scale = FLOAT; 118*9415Smckusick base = 10; 119*9415Smckusick if (type=='o') 120*9415Smckusick base = 8; 121*9415Smckusick else if (type=='x') 122*9415Smckusick base = 16; 123*9415Smckusick np = numbuf; 124*9415Smckusick expseen = 0; 125*9415Smckusick negflg = 0; 126*9415Smckusick while ((c = getc(iop))==' ' || c=='\t' || c=='\n'); 127*9415Smckusick if (c=='-') { 128*9415Smckusick negflg++; 129*9415Smckusick *np++ = c; 130*9415Smckusick c = getc(iop); 131*9415Smckusick len--; 132*9415Smckusick } else if (c=='+') { 133*9415Smckusick len--; 134*9415Smckusick c = getc(iop); 135*9415Smckusick } 136*9415Smckusick for ( ; --len>=0; *np++ = c, c = getc(iop)) { 137*9415Smckusick if (isdigit(c) 138*9415Smckusick || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) { 139*9415Smckusick ndigit++; 140*9415Smckusick if (base==8) 141*9415Smckusick lcval <<=3; 142*9415Smckusick else if (base==10) 143*9415Smckusick lcval = ((lcval<<2) + lcval)<<1; 144*9415Smckusick else 145*9415Smckusick lcval <<= 4; 146*9415Smckusick c1 = c; 147*9415Smckusick if (isdigit(c)) 148*9415Smckusick c -= '0'; 149*9415Smckusick else if ('a'<=c && c<='f') 150*9415Smckusick c -= 'a'-10; 151*9415Smckusick else 152*9415Smckusick c -= 'A'-10; 153*9415Smckusick lcval += c; 154*9415Smckusick c = c1; 155*9415Smckusick continue; 156*9415Smckusick } else if (c=='.') { 157*9415Smckusick if (base!=10 || scale==INT) 158*9415Smckusick break; 159*9415Smckusick ndigit++; 160*9415Smckusick continue; 161*9415Smckusick } else if ((c=='e'||c=='E') && expseen==0) { 162*9415Smckusick if (base!=10 || scale==INT || ndigit==0) 163*9415Smckusick break; 164*9415Smckusick expseen++; 165*9415Smckusick *np++ = c; 166*9415Smckusick c = getc(iop); 167*9415Smckusick if (c!='+'&&c!='-'&&('0'>c||c>'9')) 168*9415Smckusick break; 169*9415Smckusick } else 170*9415Smckusick break; 171*9415Smckusick } 172*9415Smckusick if (negflg) 173*9415Smckusick lcval = -lcval; 174*9415Smckusick if (c != EOF) { 175*9415Smckusick ungetc(c, iop); 176*9415Smckusick *eofptr = 0; 177*9415Smckusick } else 178*9415Smckusick *eofptr = 1; 179*9415Smckusick if (ptr==NULL || np==numbuf) 180*9415Smckusick return(0); 181*9415Smckusick *np++ = 0; 182*9415Smckusick switch((scale<<4) | size) { 183*9415Smckusick 184*9415Smckusick case (FLOAT<<4) | SHORT: 185*9415Smckusick case (FLOAT<<4) | REGULAR: 186*9415Smckusick **(float **)ptr = atof(numbuf); 187*9415Smckusick break; 188*9415Smckusick 189*9415Smckusick case (FLOAT<<4) | LONG: 190*9415Smckusick **(double **)ptr = atof(numbuf); 191*9415Smckusick break; 192*9415Smckusick 193*9415Smckusick case (INT<<4) | SHORT: 194*9415Smckusick **(short **)ptr = lcval; 195*9415Smckusick break; 196*9415Smckusick 197*9415Smckusick case (INT<<4) | REGULAR: 198*9415Smckusick **(int **)ptr = lcval; 199*9415Smckusick break; 200*9415Smckusick 201*9415Smckusick case (INT<<4) | LONG: 202*9415Smckusick **(long **)ptr = lcval; 203*9415Smckusick break; 204*9415Smckusick } 205*9415Smckusick return(1); 206*9415Smckusick } 207*9415Smckusick 208*9415Smckusick _instr(ptr, type, len, iop, eofptr) 209*9415Smckusick register char *ptr; 210*9415Smckusick register struct _iobuf *iop; 211*9415Smckusick int *eofptr; 212*9415Smckusick { 213*9415Smckusick register ch; 214*9415Smckusick register char *optr; 215*9415Smckusick int ignstp; 216*9415Smckusick 217*9415Smckusick *eofptr = 0; 218*9415Smckusick optr = ptr; 219*9415Smckusick if (type=='c' && len==30000) 220*9415Smckusick len = 1; 221*9415Smckusick ignstp = 0; 222*9415Smckusick if (type=='s') 223*9415Smckusick ignstp = SPC; 224*9415Smckusick while (_sctab[ch = getc(iop)] & ignstp) 225*9415Smckusick if (ch==EOF) 226*9415Smckusick break; 227*9415Smckusick ignstp = SPC; 228*9415Smckusick if (type=='c') 229*9415Smckusick ignstp = 0; 230*9415Smckusick else if (type=='[') 231*9415Smckusick ignstp = STP; 232*9415Smckusick while (ch!=EOF && (_sctab[ch]&ignstp)==0) { 233*9415Smckusick if (ptr) 234*9415Smckusick *ptr++ = ch; 235*9415Smckusick if (--len <= 0) 236*9415Smckusick break; 237*9415Smckusick ch = getc(iop); 238*9415Smckusick } 239*9415Smckusick if (ch != EOF) { 240*9415Smckusick if (len > 0) 241*9415Smckusick ungetc(ch, iop); 242*9415Smckusick *eofptr = 0; 243*9415Smckusick } else 244*9415Smckusick *eofptr = 1; 245*9415Smckusick if (ptr && ptr!=optr) { 246*9415Smckusick if (type!='c') 247*9415Smckusick *ptr++ = '\0'; 248*9415Smckusick return(1); 249*9415Smckusick } 250*9415Smckusick return(0); 251*9415Smckusick } 252*9415Smckusick 253*9415Smckusick char * 254*9415Smckusick _getccl(s) 255*9415Smckusick register char *s; 256*9415Smckusick { 257*9415Smckusick register c, t; 258*9415Smckusick 259*9415Smckusick t = 0; 260*9415Smckusick if (*s == '^') { 261*9415Smckusick t++; 262*9415Smckusick s++; 263*9415Smckusick } 264*9415Smckusick for (c = 0; c < 128; c++) 265*9415Smckusick if (t) 266*9415Smckusick _sctab[c] &= ~STP; 267*9415Smckusick else 268*9415Smckusick _sctab[c] |= STP; 269*9415Smckusick while (((c = *s++)&0177) != ']') { 270*9415Smckusick if (t) 271*9415Smckusick _sctab[c++] |= STP; 272*9415Smckusick else 273*9415Smckusick _sctab[c++] &= ~STP; 274*9415Smckusick if (c==0) 275*9415Smckusick return(--s); 276*9415Smckusick } 277*9415Smckusick return(s); 278*9415Smckusick } 279