home *** CD-ROM | disk | FTP | other *** search
- #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;
- 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);
- }
-