/* @(#)doscan.c 2.1 SCCS id keyword */ #include #include #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; for (;;) 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') { ch = *fmt++; size = LONG; } else if (ch=='h') { size = SHORT; ch = *fmt++; } else if (ch=='[') fmt = _getccl(fmt); if (isupper(ch)) { ch = tolower(ch); size = LONG; } 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 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) { ndigit++; if (base==8) lcval <<=3; else if (base==10) lcval = ((lcval<<2) + lcval)<<1; else lcval <<= 4; c1 = c; if ('0'<=c && c<='9') 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!='-'&&('0'>c||c>'9')) 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) { 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); }