You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
5.3 KiB
302 lines
5.3 KiB
/* This is file DOSCAN.C */
|
|
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
|
|
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
|
|
** Rochester NH, 03867-2954, USA.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#ifdef linux
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#define SPC 01
|
|
#define STP 02
|
|
|
|
#define SHORT 0
|
|
#define REGULAR 1
|
|
#define LONG 2
|
|
#define INT 0
|
|
#define FLOAT 1
|
|
|
|
#ifdef linux
|
|
static char *_getccl(const char *s);
|
|
static int _innum(int **ptr, int type, int len, int size, FILE *iop,
|
|
int *eofptr);
|
|
static int _instr( char *ptr, int type, int len, FILE *iop,
|
|
int *eofptr);
|
|
#else
|
|
static char *_getccl(unsigned char *s);
|
|
#endif
|
|
|
|
static char _sctab[256] = {
|
|
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,
|
|
};
|
|
|
|
|
|
int
|
|
_doscan(FILE *iop, const char *fmt, void **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 = (void *)NULL;
|
|
if (ch != '*')
|
|
ptr = (int **) 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
static int
|
|
_innum(int **ptr, int type, int len, int size, FILE *iop, int *eofptr)
|
|
{
|
|
#ifndef linux
|
|
extern double atof();
|
|
#endif
|
|
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 || (negflg && np==numbuf+1) )/* gene dykes*/
|
|
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);
|
|
}
|
|
|
|
static int
|
|
_instr(char *ptr, int type, int len, FILE *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 ((ch = getc(iop)) != EOF && _sctab[ch] & ignstp)
|
|
;
|
|
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);
|
|
}
|
|
|
|
static char *
|
|
_getccl(register const char *s)
|
|
{
|
|
register c, t;
|
|
|
|
t = 0;
|
|
if (*s == '^') {
|
|
t++;
|
|
s++;
|
|
}
|
|
for (c = 0; c < (sizeof (_sctab) / sizeof (_sctab[0])); c++)
|
|
if (t)
|
|
_sctab[c] &= ~STP;
|
|
else
|
|
_sctab[c] |= STP;
|
|
if ((c = *s) == ']' || c == '-') { /* first char is special */
|
|
if (t)
|
|
_sctab[c] |= STP;
|
|
else
|
|
_sctab[c] &= ~STP;
|
|
s++;
|
|
}
|
|
while ((c = *s++) != ']') {
|
|
if (c==0)
|
|
return((char *)--s);
|
|
else if (c == '-' && *s != ']' && s[-2] < *s) {
|
|
for (c = s[-2] + 1; c < *s; c++)
|
|
if (t)
|
|
_sctab[c] |= STP;
|
|
else
|
|
_sctab[c] &= ~STP;
|
|
} else if (t)
|
|
_sctab[c] |= STP;
|
|
else
|
|
_sctab[c] &= ~STP;
|
|
}
|
|
return((char *)s);
|
|
}
|