/*LINTLIBRARY*/ #include <stdio.h> #include <ctype.h> #define SPC 01 #define STP 02 #define SHORT 0 #define REGULAR 1 #define LONG 2 #define INT 0 #define FLOAT 1 char *_getccl(); char _sctab[128] = { 0,0,0,0,0,0,0,0, 0,SPC,SPC,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, SPC,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, }; _doscan(iop, fmt, argp) FILE *iop; register char *fmt; register int **argp; { register int ch; int nmatch, len, ch1; int **ptr, fileended, size; nmatch = 0; fileended = 0; while(1) switch(ch = *fmt++) { case '\0': return(nmatch); case '%': if((ch = *fmt++) == '%') goto def; ptr = 0; if(ch != '*') ptr = argp++; else ch = *fmt++; len = 0; size = REGULAR; while(isdigit(ch)) { len = len*10 + ch - '0'; ch = *fmt++; } if(len == 0) len = 30000; if(ch == 'l') { size = LONG; ch = *fmt++; } else if(ch == 'h') { size = SHORT; ch = *fmt++; } else if(ch == '[') fmt = _getccl(fmt); if(isupper(ch)) { size = LONG; ch = _tolower(ch); } if(ch == '\0') return(-1); if(_innum(ptr, ch, len, size, iop, &fileended) && ptr) nmatch++; if(fileended) return(nmatch? nmatch: -1); break; case ' ': case '\n': case '\t': while((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n') ; if(ch1 != EOF) ungetc(ch1, iop); break; default: def: ch1 = getc(iop); if(ch1 != ch) { if(ch1 == EOF) return(-1); ungetc(ch1, iop); return(nmatch); } } } _innum(ptr, type, len, size, iop, eofptr) int **ptr, *eofptr; struct _iobuf *iop; { extern double atof(); register char *np; char numbuf[64]; register c, base; int expseen, scale, negflg, c1, ndigit; long lcval; if(type == 'c' || type == 's' || type == '[') return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr)); lcval = 0; ndigit = 0; scale = INT; if(type == 'e' || type == 'f') scale = FLOAT; base = 10; if(type == 'o') base = 8; else if(type == 'x') base = 16; np = numbuf; expseen = 0; negflg = 0; while((c = getc(iop)) == ' ' || c == '\t' || c == '\n'); if(c == '-') { negflg++; *np++ = c; c = getc(iop); len--; } else if(c == '+') { len--; c = getc(iop); } for( ; --len >= 0; *np++ = c, c = getc(iop)) { if(isdigit(c) || base == 16 && isxdigit(c)) { ndigit++; if(base == 8) lcval <<= 3; else if(base == 10) lcval = ((lcval<<2) + lcval)<<1; else lcval <<= 4; c1 = c; if(isdigit(c)) c -= '0'; else if('a' <= c && c <= 'f') c -= 'a'-10; else c -= 'A'-10; lcval += c; c = c1; continue; } else if(c == '.') { if(base != 10 || scale == INT) break; ndigit++; continue; } else if((c == 'e' || c == 'E') && expseen == 0) { if(base != 10 || scale == INT || ndigit == 0) break; expseen++; *np++ = c; c = getc(iop); if(c != '+' && c != '-' && !isdigit(c)) break; } else break; } if(negflg) lcval = -lcval; if(c != EOF) { ungetc(c, iop); *eofptr = 0; } else *eofptr = 1; if(ptr == NULL || np == numbuf) return(0); *np++ = 0; switch((scale<<4) | size) { case (FLOAT<<4) | SHORT: case (FLOAT<<4) | REGULAR: **(float **)ptr = atof(numbuf); break; case (FLOAT<<4) | LONG: **(double **)ptr = atof(numbuf); break; case (INT<<4) | SHORT: **(short **)ptr = lcval; break; case (INT<<4) | REGULAR: **(int **)ptr = lcval; break; case (INT<<4) | LONG: **(long **)ptr = lcval; break; } return(1); } _instr(ptr, type, len, iop, eofptr) register char *ptr; register struct _iobuf *iop; int *eofptr; { register ch; register char *optr; int ignstp; *eofptr = 0; optr = ptr; if(type == 'c' && len == 30000) len = 1; ignstp = 0; if(type == 's') ignstp = SPC; while(_sctab[ch = getc(iop)] & ignstp) if(ch == EOF) break; ignstp = SPC; if(type == 'c') ignstp = 0; else if(type == '[') ignstp = STP; while(ch != EOF && (_sctab[ch] & ignstp) == 0) { if(ptr) *ptr++ = ch; if(--len <= 0) break; ch = getc(iop); } if(ch != EOF) { if(len > 0) ungetc(ch, iop); *eofptr = 0; } else *eofptr = 1; if(ptr && (ptr != optr || type == '[')) { if(type != 'c') *ptr++ = '\0'; return(1); } return(0); } char * _getccl(s) register char *s; { register c, t; t = 0; if(*s == '^') { t++; s++; } for(c = 0; c < 128; c++) if(t) _sctab[c] &= ~STP; else _sctab[c] |= STP; while(((c = *s++) & 0177) != ']') { if(t) _sctab[c++] |= STP; else _sctab[c++] &= ~STP; if(c == 0) return(--s); } return(s); }