Bell 32V development
authorTom London <tbl@research.uucp>
Mon, 22 Jan 1979 05:18:46 +0000 (00:18 -0500)
committerTom London <tbl@research.uucp>
Mon, 22 Jan 1979 05:18:46 +0000 (00:18 -0500)
Work on file usr/src/libc/stdio/doscan.c

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/libc/stdio/doscan.c [new file with mode: 0644]

diff --git a/usr/src/libc/stdio/doscan.c b/usr/src/libc/stdio/doscan.c
new file mode 100644 (file)
index 0000000..bafc4ab
--- /dev/null
@@ -0,0 +1,275 @@
+#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);
+}