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