PWB1/sys/source/s4/stdio/doscan.c
#include "stdio.h"
#define SPC 01
#define STP 02
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)
register char *fmt;
register int *argp;
{
register int ch;
int nmatch, len, ch1;
int *ptr, fileended;
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;
while (ch>='0' && ch <='9') {
len = len*10 + ch - '0';
ch = *fmt++;
}
if (len == 0)
len = 30000;
if (ch=='l') {
ch = *fmt++;
if (ch>='a' && ch<='z')
ch =+ 'A'-'a';
} else if (ch=='[')
fmt = _getccl(fmt);
if (ch == '\0')
_error("scanf\n");
if (_innum(ptr, ch, len, iop, &fileended) && ptr)
nmatch++;
if (fileended)
return(nmatch? nmatch: -1);
break;
case ' ':
case '\n':
case '\t':
break;
default:
def:
if (ch != (ch1 = getc(iop)))
return(ch1==EOF? -1: nmatch);
}
}
_innum(ptr, type, len, iop, eofptr)
int *ptr, *eofptr;
struct _iobuf *iop;
{
extern double atof();
struct { double *dblptr;};
struct { long *longptr;};
struct { float *fltptr;};
register char *np;
char numbuf[64];
register c, base;
int expseen, scale, size, negflg, c1, ndigit;
long lcval;
if (type=='c' || type=='s' || type=='[')
return(_instr(ptr, type, len, iop, eofptr));
lcval = 0;
ndigit = 0;
size = 0;
if (type>='A' && type <='Z') {
size++;
type =+ 'a'-'A';
}
scale = 0;
if (type=='e'||type=='f')
scale++;
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 ('0'<=c && c<='9'
|| 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==0)
break;
ndigit++;
continue;
} else if ((c=='e'||c=='E') && expseen==0) {
if (base!=10 || scale==0 || 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;
if (scale==0)
if (size)
*ptr.longptr = lcval;
else
*ptr = lcval;
else
if (size)
*ptr.dblptr = atof(numbuf);
else
*ptr.fltptr = atof(numbuf);
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 (--len>=0 && ch>=0 && (_sctab[ch]&ignstp)==0) {
if (ptr)
*ptr++ = ch;
ch = getc(iop);
}
if (ch != EOF) {
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);
}