1*17951Sserge static char sccsid[] = "@(#)vfscanf.c 4.3 (Berkeley) 85/02/13"; 29415Smckusick 39415Smckusick /* @(#)doscan.c 4.1 (Berkeley) 12/21/80 */ 49415Smckusick #include <stdio.h> 59415Smckusick #include <ctype.h> 69415Smckusick 79415Smckusick #define SPC 01 89415Smckusick #define STP 02 99415Smckusick 109415Smckusick #define SHORT 0 119415Smckusick #define REGULAR 1 129415Smckusick #define LONG 2 139415Smckusick #define INT 0 149415Smckusick #define FLOAT 1 159415Smckusick 16*17951Sserge static char *_getccl(); 179415Smckusick 18*17951Sserge static char _sctab[256] = { 199415Smckusick 0,0,0,0,0,0,0,0, 209415Smckusick 0,SPC,SPC,0,0,0,0,0, 219415Smckusick 0,0,0,0,0,0,0,0, 229415Smckusick 0,0,0,0,0,0,0,0, 239415Smckusick SPC,0,0,0,0,0,0,0, 249415Smckusick 0,0,0,0,0,0,0,0, 259415Smckusick 0,0,0,0,0,0,0,0, 269415Smckusick 0,0,0,0,0,0,0,0, 279415Smckusick }; 289415Smckusick 299415Smckusick _doscan(iop, fmt, argp) 309415Smckusick FILE *iop; 319415Smckusick register char *fmt; 329415Smckusick register int **argp; 339415Smckusick { 349415Smckusick register int ch; 359415Smckusick int nmatch, len, ch1; 369415Smckusick int **ptr, fileended, size; 379415Smckusick 389415Smckusick nmatch = 0; 399415Smckusick fileended = 0; 409415Smckusick for (;;) switch (ch = *fmt++) { 419415Smckusick case '\0': 429415Smckusick return (nmatch); 439415Smckusick case '%': 449415Smckusick if ((ch = *fmt++) == '%') 459415Smckusick goto def; 469415Smckusick ptr = 0; 479415Smckusick if (ch != '*') 489415Smckusick ptr = argp++; 499415Smckusick else 509415Smckusick ch = *fmt++; 519415Smckusick len = 0; 529415Smckusick size = REGULAR; 539415Smckusick while (isdigit(ch)) { 549415Smckusick len = len*10 + ch - '0'; 559415Smckusick ch = *fmt++; 569415Smckusick } 579415Smckusick if (len == 0) 589415Smckusick len = 30000; 599415Smckusick if (ch=='l') { 609415Smckusick size = LONG; 619415Smckusick ch = *fmt++; 629415Smckusick } else if (ch=='h') { 639415Smckusick size = SHORT; 649415Smckusick ch = *fmt++; 659415Smckusick } else if (ch=='[') 669415Smckusick fmt = _getccl(fmt); 679415Smckusick if (isupper(ch)) { 689415Smckusick ch = tolower(ch); 699415Smckusick size = LONG; 709415Smckusick } 719415Smckusick if (ch == '\0') 729415Smckusick return(-1); 739415Smckusick if (_innum(ptr, ch, len, size, iop, &fileended) && ptr) 749415Smckusick nmatch++; 759415Smckusick if (fileended) 769415Smckusick return(nmatch? nmatch: -1); 779415Smckusick break; 789415Smckusick 799415Smckusick case ' ': 809415Smckusick case '\n': 819415Smckusick case '\t': 829415Smckusick while ((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n') 839415Smckusick ; 849415Smckusick if (ch1 != EOF) 859415Smckusick ungetc(ch1, iop); 869415Smckusick break; 879415Smckusick 889415Smckusick default: 899415Smckusick def: 909415Smckusick ch1 = getc(iop); 919415Smckusick if (ch1 != ch) { 929415Smckusick if (ch1==EOF) 939415Smckusick return(-1); 949415Smckusick ungetc(ch1, iop); 959415Smckusick return(nmatch); 969415Smckusick } 979415Smckusick } 989415Smckusick } 999415Smckusick 100*17951Sserge static 1019415Smckusick _innum(ptr, type, len, size, iop, eofptr) 1029415Smckusick int **ptr, *eofptr; 103*17951Sserge FILE *iop; 1049415Smckusick { 1059415Smckusick extern double atof(); 1069415Smckusick register char *np; 1079415Smckusick char numbuf[64]; 1089415Smckusick register c, base; 1099415Smckusick int expseen, scale, negflg, c1, ndigit; 1109415Smckusick long lcval; 1119415Smckusick 1129415Smckusick if (type=='c' || type=='s' || type=='[') 1139415Smckusick return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr)); 1149415Smckusick lcval = 0; 1159415Smckusick ndigit = 0; 1169415Smckusick scale = INT; 1179415Smckusick if (type=='e'||type=='f') 1189415Smckusick scale = FLOAT; 1199415Smckusick base = 10; 1209415Smckusick if (type=='o') 1219415Smckusick base = 8; 1229415Smckusick else if (type=='x') 1239415Smckusick base = 16; 1249415Smckusick np = numbuf; 1259415Smckusick expseen = 0; 1269415Smckusick negflg = 0; 1279415Smckusick while ((c = getc(iop))==' ' || c=='\t' || c=='\n'); 1289415Smckusick if (c=='-') { 1299415Smckusick negflg++; 1309415Smckusick *np++ = c; 1319415Smckusick c = getc(iop); 1329415Smckusick len--; 1339415Smckusick } else if (c=='+') { 1349415Smckusick len--; 1359415Smckusick c = getc(iop); 1369415Smckusick } 1379415Smckusick for ( ; --len>=0; *np++ = c, c = getc(iop)) { 1389415Smckusick if (isdigit(c) 1399415Smckusick || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) { 1409415Smckusick ndigit++; 1419415Smckusick if (base==8) 1429415Smckusick lcval <<=3; 1439415Smckusick else if (base==10) 1449415Smckusick lcval = ((lcval<<2) + lcval)<<1; 1459415Smckusick else 1469415Smckusick lcval <<= 4; 1479415Smckusick c1 = c; 1489415Smckusick if (isdigit(c)) 1499415Smckusick c -= '0'; 1509415Smckusick else if ('a'<=c && c<='f') 1519415Smckusick c -= 'a'-10; 1529415Smckusick else 1539415Smckusick c -= 'A'-10; 1549415Smckusick lcval += c; 1559415Smckusick c = c1; 1569415Smckusick continue; 1579415Smckusick } else if (c=='.') { 1589415Smckusick if (base!=10 || scale==INT) 1599415Smckusick break; 1609415Smckusick ndigit++; 1619415Smckusick continue; 1629415Smckusick } else if ((c=='e'||c=='E') && expseen==0) { 1639415Smckusick if (base!=10 || scale==INT || ndigit==0) 1649415Smckusick break; 1659415Smckusick expseen++; 1669415Smckusick *np++ = c; 1679415Smckusick c = getc(iop); 1689415Smckusick if (c!='+'&&c!='-'&&('0'>c||c>'9')) 1699415Smckusick break; 1709415Smckusick } else 1719415Smckusick break; 1729415Smckusick } 1739415Smckusick if (negflg) 1749415Smckusick lcval = -lcval; 1759415Smckusick if (c != EOF) { 1769415Smckusick ungetc(c, iop); 1779415Smckusick *eofptr = 0; 1789415Smckusick } else 1799415Smckusick *eofptr = 1; 1809416Smckusick if (ptr==NULL || np==numbuf || (negflg && np==numbuf+1) )/* gene dykes*/ 1819415Smckusick return(0); 1829415Smckusick *np++ = 0; 1839415Smckusick switch((scale<<4) | size) { 1849415Smckusick 1859415Smckusick case (FLOAT<<4) | SHORT: 1869415Smckusick case (FLOAT<<4) | REGULAR: 1879415Smckusick **(float **)ptr = atof(numbuf); 1889415Smckusick break; 1899415Smckusick 1909415Smckusick case (FLOAT<<4) | LONG: 1919415Smckusick **(double **)ptr = atof(numbuf); 1929415Smckusick break; 1939415Smckusick 1949415Smckusick case (INT<<4) | SHORT: 1959415Smckusick **(short **)ptr = lcval; 1969415Smckusick break; 1979415Smckusick 1989415Smckusick case (INT<<4) | REGULAR: 1999415Smckusick **(int **)ptr = lcval; 2009415Smckusick break; 2019415Smckusick 2029415Smckusick case (INT<<4) | LONG: 2039415Smckusick **(long **)ptr = lcval; 2049415Smckusick break; 2059415Smckusick } 2069415Smckusick return(1); 2079415Smckusick } 2089415Smckusick 209*17951Sserge static 2109415Smckusick _instr(ptr, type, len, iop, eofptr) 2119415Smckusick register char *ptr; 212*17951Sserge register FILE *iop; 2139415Smckusick int *eofptr; 2149415Smckusick { 2159415Smckusick register ch; 2169415Smckusick register char *optr; 2179415Smckusick int ignstp; 2189415Smckusick 2199415Smckusick *eofptr = 0; 2209415Smckusick optr = ptr; 2219415Smckusick if (type=='c' && len==30000) 2229415Smckusick len = 1; 2239415Smckusick ignstp = 0; 2249415Smckusick if (type=='s') 2259415Smckusick ignstp = SPC; 226*17951Sserge while ((ch = getc(iop)) != EOF && _sctab[ch] & ignstp) 227*17951Sserge ; 2289415Smckusick ignstp = SPC; 2299415Smckusick if (type=='c') 2309415Smckusick ignstp = 0; 2319415Smckusick else if (type=='[') 2329415Smckusick ignstp = STP; 2339415Smckusick while (ch!=EOF && (_sctab[ch]&ignstp)==0) { 2349415Smckusick if (ptr) 2359415Smckusick *ptr++ = ch; 2369415Smckusick if (--len <= 0) 2379415Smckusick break; 2389415Smckusick ch = getc(iop); 2399415Smckusick } 2409415Smckusick if (ch != EOF) { 2419415Smckusick if (len > 0) 2429415Smckusick ungetc(ch, iop); 2439415Smckusick *eofptr = 0; 2449415Smckusick } else 2459415Smckusick *eofptr = 1; 2469415Smckusick if (ptr && ptr!=optr) { 2479415Smckusick if (type!='c') 2489415Smckusick *ptr++ = '\0'; 2499415Smckusick return(1); 2509415Smckusick } 2519415Smckusick return(0); 2529415Smckusick } 2539415Smckusick 254*17951Sserge static char * 2559415Smckusick _getccl(s) 256*17951Sserge register unsigned char *s; 2579415Smckusick { 2589415Smckusick register c, t; 2599415Smckusick 2609415Smckusick t = 0; 2619415Smckusick if (*s == '^') { 2629415Smckusick t++; 2639415Smckusick s++; 2649415Smckusick } 265*17951Sserge for (c = 0; c < (sizeof _sctab / sizeof _sctab[0]); c++) 2669415Smckusick if (t) 2679415Smckusick _sctab[c] &= ~STP; 2689415Smckusick else 2699415Smckusick _sctab[c] |= STP; 270*17951Sserge if ((c = *s) == ']' || c == '-') { /* first char is special */ 2719415Smckusick if (t) 272*17951Sserge _sctab[c] |= STP; 2739415Smckusick else 274*17951Sserge _sctab[c] &= ~STP; 275*17951Sserge s++; 276*17951Sserge } 277*17951Sserge while ((c = *s++) != ']') { 2789415Smckusick if (c==0) 279*17951Sserge return((char *)--s); 280*17951Sserge else if (c == '-' && *s != ']' && s[-2] < *s) { 281*17951Sserge for (c = s[-2] + 1; c < *s; c++) 282*17951Sserge if (t) 283*17951Sserge _sctab[c] |= STP; 284*17951Sserge else 285*17951Sserge _sctab[c] &= ~STP; 286*17951Sserge } else if (t) 287*17951Sserge _sctab[c] |= STP; 288*17951Sserge else 289*17951Sserge _sctab[c] &= ~STP; 2909415Smckusick } 291*17951Sserge return((char *)s); 2929415Smckusick } 293