#ifndef lint
static char *moduleid =
- "@(#)$Header: /home/glen/git/file/cvs/file/src/apprentice.c,v 1.11 1992/05/22 17:49:23 ian Exp $";
+ "@(#)$Header: /home/glen/git/file/cvs/file/src/apprentice.c,v 1.12 1992/09/08 15:03:05 ian Exp $";
#endif /* lint */
-#define MAXSTR 500
#define EATAB {while (isascii(*l) && isspace(*l)) ++l;}
-extern char *progname;
-extern char *magicfile;
-extern int debug; /* option */
-extern int nmagic; /* number of valid magic[]s */
-extern long strtol();
-struct magic magic[MAXMAGIS];
+static int getvalue __P((struct magic *, char **));
+static int hextoint __P((int));
+static char *getstr __P((char *, char *, int, int *));
+static int parse __P((char *, int *, int));
-#if defined(__STDC__) || defined(__cplusplus)
-static int getvalue(struct magic *m, char **p);
-static int hextoint(int c);
-static char *getstr(char *s, char *p, int plen, int *slen);
-#else
-static int getvalue();
-static int hextoint();
-static char *getstr();
-#endif
+static int maxmagic = 0;
int
apprentice(fn, check)
int check; /* non-zero? checking-only run. */
{
FILE *f;
- char line[MAXSTR+1];
+ char line[BUFSIZ+1];
int errs = 0;
f = fopen(fn, "r");
exit(1);
}
+ maxmagic = MAXMAGIS;
+ if ((magic = (struct magic *) malloc(sizeof(struct magic) * maxmagic))
+ == NULL) {
+ (void) fprintf(stderr, "%s: Out of memory.\n", progname);
+ if (check)
+ return -1;
+ else
+ exit(1);
+ }
+
/* parse it */
if (check) /* print silly verbose header for USG compat. */
(void) printf("cont\toffset\ttype\topcode\tmask\tvalue\tdesc\n");
- while (fgets(line, MAXSTR, f) != NULL) {
+ for (lineno = 1;fgets(line, BUFSIZ, f) != NULL; lineno++) {
if (line[0]=='#') /* comment, do not parse */
continue;
if (strlen(line) <= 1) /* null line, garbage, etc */
/*
* parse one line from magic file, put into magic[index++] if valid
*/
-int
+static int
parse(l, ndx, check)
char *l;
int *ndx, check;
{
int i = 0, nd = *ndx;
- static int warned = 0;
struct magic *m;
- extern int errno;
-
- /*
- * TODO malloc the magic structures (linked list?) so this can't happen
- */
- if (nd+1 >= MAXMAGIS){
- if (warned++ == 0)
- warning(
-"magic table overflow - increase MAXMAGIS beyond %d in file/file.h\n",
- MAXMAGIS);
- return -1;
+ char *t, *s;
+
+ if (nd+1 >= maxmagic){
+ maxmagic += 20;
+ if ((magic = (struct magic *) realloc(magic,
+ sizeof(struct magic) *
+ maxmagic)) == NULL) {
+ (void) fprintf(stderr, "%s: Out of memory.\n", progname);
+ if (check)
+ return -1;
+ else
+ exit(1);
+ }
}
m = &magic[*ndx];
+ m->flag = 0;
if (*l == '>') {
++l; /* step over */
- m->contflag = 1;
- } else
- m->contflag = 0;
+ m->flag |= CONT;
+ }
+
+ if ((m->flag & CONT) && *l == '(') {
+ ++l; /* step over */
+ m->flag |= INDIR;
+ }
/* get offset, then skip over it */
-#ifdef OldWay
- m->offset = atoi(l);
- while (isascii(*l) && isdigit(*l))
+ m->offset = (int) strtol(l,&t,0);
+ if (l == t)
+ magwarn("offset %s invalid", l);
+ l = t;
+
+ if (m->flag & INDIR) {
+ m->in.type = LONG;
+ m->in.offset = 0;
+ /*
+ * read [.lbs][+-]nnnnn)
+ */
+ if (*l == '.') {
+ switch (*++l) {
+ case 'l':
+ m->in.type = LONG;
+ break;
+ case 's':
+ m->in.type = SHORT;
+ break;
+ case 'b':
+ m->in.type = BYTE;
+ break;
+ default:
+ magwarn("indirect offset type %c invalid", *l);
+ break;
+ }
+ l++;
+ }
+ s = l;
+ if (*l == '+' || *l == '-') l++;
+ if (isdigit((unsigned char)*l)) {
+ m->in.offset = strtol(l, &t, 0);
+ if (*s == '-') m->in.offset = - m->in.offset;
+ }
+ if (*t++ != ')')
+ magwarn("missing ')' in indirect offset");
+ l = t;
+ }
+
+
+ while (isascii((unsigned char)*l) && isdigit((unsigned char)*l))
++l;
-#else
- m->offset = (int) strtol(l,&l,0);
-#endif
EATAB;
-#define NBYTE 4
-#define NSHORT 5
-#define NLONG 4
+#define NBYTE 4
+#define NSHORT 5
+#define NLONG 4
#define NSTRING 6
+#define NDATE 4
+
/* get type, skip it */
if (strncmp(l, "byte", NBYTE)==0) {
m->type = BYTE;
} else if (strncmp(l, "string", NSTRING)==0) {
m->type = STRING;
l += NSTRING;
+ } else if (strncmp(l, "date", NDATE)==0) {
+ m->type = DATE;
+ l += NDATE;
} else {
- errno = 0;
- warning("type %s invalid", l);
+ magwarn("type %s invalid", l);
return -1;
}
if (*l == '&') {
}
/* FALL THROUGH */
default:
- if (*l == 'x' && isascii(l[1]) && isspace(l[1])) {
+ if (*l == 'x' && isascii((unsigned char)l[1]) &&
+ isspace((unsigned char)l[1])) {
m->reln = *l;
++l;
goto GetDesc; /* Bill The Cat */
/*
* TODO finish this macro and start using it!
* #define offsetcheck {if (offset > HOWMANY-1)
- * warning("offset too big"); }
+ * magwarn("offset too big"); }
*/
/*
case SHORT:
m->value.l = (short) strtol(*p,p,0);
break;
+ case DATE:
case LONG:
m->value.l = (long) strtol(*p,p,0);
break;
default:
- warning("can't happen: m->type=%d\n", m->type);
+ magwarn("can't happen: m->type=%d\n", m->type);
return -1;
}
}
register int val;
while ((c = *s++) != '\0') {
- if (isspace(c))
+ if (isspace((unsigned char) c))
break;
if (p >= pmax) {
fprintf(stderr, "String too long: %s\n", origs);
goto out;
default:
- *p++ = c;
+ *p++ = (char) c;
break;
case 'n':
}
else
--s;
- *p++ = val;
+ *p++ = (char)val;
break;
/* \x and up to 3 hex digits */
--s;
} else
--s;
- *p++ = val;
+ *p++ = (char)val;
break;
}
} else
- *p++ = c;
+ *p++ = (char)c;
}
out:
*p = '\0';
hextoint(c)
int c;
{
- if (!isascii(c)) return -1;
- if (isdigit(c)) return c - '0';
+ if (!isascii((unsigned char) c)) return -1;
+ if (isdigit((unsigned char) c)) return c - '0';
if ((c>='a')&&(c<='f')) return c + 10 - 'a';
if ((c>='A')&&(c<='F')) return c + 10 - 'A';
return -1;
*/
void
showstr(s)
-register char *s;
+const char *s;
{
register char c;