+#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') {
+ size = LONG;
+ ch = *fmt++;
+ } 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 (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!='-'&&('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);
+}