1*9416Smckusick static char sccsid[] = "@(#)vfscanf.c 4.2 (Berkeley) 82/12/03"; 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 169415Smckusick char *_getccl(); 179415Smckusick 189415Smckusick char _sctab[128] = { 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 1009415Smckusick _innum(ptr, type, len, size, iop, eofptr) 1019415Smckusick int **ptr, *eofptr; 1029415Smckusick struct _iobuf *iop; 1039415Smckusick { 1049415Smckusick extern double atof(); 1059415Smckusick register char *np; 1069415Smckusick char numbuf[64]; 1079415Smckusick register c, base; 1089415Smckusick int expseen, scale, negflg, c1, ndigit; 1099415Smckusick long lcval; 1109415Smckusick 1119415Smckusick if (type=='c' || type=='s' || type=='[') 1129415Smckusick return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr)); 1139415Smckusick lcval = 0; 1149415Smckusick ndigit = 0; 1159415Smckusick scale = INT; 1169415Smckusick if (type=='e'||type=='f') 1179415Smckusick scale = FLOAT; 1189415Smckusick base = 10; 1199415Smckusick if (type=='o') 1209415Smckusick base = 8; 1219415Smckusick else if (type=='x') 1229415Smckusick base = 16; 1239415Smckusick np = numbuf; 1249415Smckusick expseen = 0; 1259415Smckusick negflg = 0; 1269415Smckusick while ((c = getc(iop))==' ' || c=='\t' || c=='\n'); 1279415Smckusick if (c=='-') { 1289415Smckusick negflg++; 1299415Smckusick *np++ = c; 1309415Smckusick c = getc(iop); 1319415Smckusick len--; 1329415Smckusick } else if (c=='+') { 1339415Smckusick len--; 1349415Smckusick c = getc(iop); 1359415Smckusick } 1369415Smckusick for ( ; --len>=0; *np++ = c, c = getc(iop)) { 1379415Smckusick if (isdigit(c) 1389415Smckusick || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) { 1399415Smckusick ndigit++; 1409415Smckusick if (base==8) 1419415Smckusick lcval <<=3; 1429415Smckusick else if (base==10) 1439415Smckusick lcval = ((lcval<<2) + lcval)<<1; 1449415Smckusick else 1459415Smckusick lcval <<= 4; 1469415Smckusick c1 = c; 1479415Smckusick if (isdigit(c)) 1489415Smckusick c -= '0'; 1499415Smckusick else if ('a'<=c && c<='f') 1509415Smckusick c -= 'a'-10; 1519415Smckusick else 1529415Smckusick c -= 'A'-10; 1539415Smckusick lcval += c; 1549415Smckusick c = c1; 1559415Smckusick continue; 1569415Smckusick } else if (c=='.') { 1579415Smckusick if (base!=10 || scale==INT) 1589415Smckusick break; 1599415Smckusick ndigit++; 1609415Smckusick continue; 1619415Smckusick } else if ((c=='e'||c=='E') && expseen==0) { 1629415Smckusick if (base!=10 || scale==INT || ndigit==0) 1639415Smckusick break; 1649415Smckusick expseen++; 1659415Smckusick *np++ = c; 1669415Smckusick c = getc(iop); 1679415Smckusick if (c!='+'&&c!='-'&&('0'>c||c>'9')) 1689415Smckusick break; 1699415Smckusick } else 1709415Smckusick break; 1719415Smckusick } 1729415Smckusick if (negflg) 1739415Smckusick lcval = -lcval; 1749415Smckusick if (c != EOF) { 1759415Smckusick ungetc(c, iop); 1769415Smckusick *eofptr = 0; 1779415Smckusick } else 1789415Smckusick *eofptr = 1; 179*9416Smckusick if (ptr==NULL || np==numbuf || (negflg && np==numbuf+1) )/* gene dykes*/ 1809415Smckusick return(0); 1819415Smckusick *np++ = 0; 1829415Smckusick switch((scale<<4) | size) { 1839415Smckusick 1849415Smckusick case (FLOAT<<4) | SHORT: 1859415Smckusick case (FLOAT<<4) | REGULAR: 1869415Smckusick **(float **)ptr = atof(numbuf); 1879415Smckusick break; 1889415Smckusick 1899415Smckusick case (FLOAT<<4) | LONG: 1909415Smckusick **(double **)ptr = atof(numbuf); 1919415Smckusick break; 1929415Smckusick 1939415Smckusick case (INT<<4) | SHORT: 1949415Smckusick **(short **)ptr = lcval; 1959415Smckusick break; 1969415Smckusick 1979415Smckusick case (INT<<4) | REGULAR: 1989415Smckusick **(int **)ptr = lcval; 1999415Smckusick break; 2009415Smckusick 2019415Smckusick case (INT<<4) | LONG: 2029415Smckusick **(long **)ptr = lcval; 2039415Smckusick break; 2049415Smckusick } 2059415Smckusick return(1); 2069415Smckusick } 2079415Smckusick 2089415Smckusick _instr(ptr, type, len, iop, eofptr) 2099415Smckusick register char *ptr; 2109415Smckusick register struct _iobuf *iop; 2119415Smckusick int *eofptr; 2129415Smckusick { 2139415Smckusick register ch; 2149415Smckusick register char *optr; 2159415Smckusick int ignstp; 2169415Smckusick 2179415Smckusick *eofptr = 0; 2189415Smckusick optr = ptr; 2199415Smckusick if (type=='c' && len==30000) 2209415Smckusick len = 1; 2219415Smckusick ignstp = 0; 2229415Smckusick if (type=='s') 2239415Smckusick ignstp = SPC; 2249415Smckusick while (_sctab[ch = getc(iop)] & ignstp) 2259415Smckusick if (ch==EOF) 2269415Smckusick break; 2279415Smckusick ignstp = SPC; 2289415Smckusick if (type=='c') 2299415Smckusick ignstp = 0; 2309415Smckusick else if (type=='[') 2319415Smckusick ignstp = STP; 2329415Smckusick while (ch!=EOF && (_sctab[ch]&ignstp)==0) { 2339415Smckusick if (ptr) 2349415Smckusick *ptr++ = ch; 2359415Smckusick if (--len <= 0) 2369415Smckusick break; 2379415Smckusick ch = getc(iop); 2389415Smckusick } 2399415Smckusick if (ch != EOF) { 2409415Smckusick if (len > 0) 2419415Smckusick ungetc(ch, iop); 2429415Smckusick *eofptr = 0; 2439415Smckusick } else 2449415Smckusick *eofptr = 1; 2459415Smckusick if (ptr && ptr!=optr) { 2469415Smckusick if (type!='c') 2479415Smckusick *ptr++ = '\0'; 2489415Smckusick return(1); 2499415Smckusick } 2509415Smckusick return(0); 2519415Smckusick } 2529415Smckusick 2539415Smckusick char * 2549415Smckusick _getccl(s) 2559415Smckusick register char *s; 2569415Smckusick { 2579415Smckusick register c, t; 2589415Smckusick 2599415Smckusick t = 0; 2609415Smckusick if (*s == '^') { 2619415Smckusick t++; 2629415Smckusick s++; 2639415Smckusick } 2649415Smckusick for (c = 0; c < 128; c++) 2659415Smckusick if (t) 2669415Smckusick _sctab[c] &= ~STP; 2679415Smckusick else 2689415Smckusick _sctab[c] |= STP; 2699415Smckusick while (((c = *s++)&0177) != ']') { 2709415Smckusick if (t) 2719415Smckusick _sctab[c++] |= STP; 2729415Smckusick else 2739415Smckusick _sctab[c++] &= ~STP; 2749415Smckusick if (c==0) 2759415Smckusick return(--s); 2769415Smckusick } 2779415Smckusick return(s); 2789415Smckusick } 279