(xuflds, xunsymbol, xuloadrow): Symbol sets.

(VAL_SYMBOL_SET, getid, xunsymbol1): New.

(xunsymbol): New argument n for more useful diagnostics.

(xuloadrow): Remove redundant semantic check.
This commit is contained in:
Markus Armbruster 2005-12-03 14:14:44 +00:00
parent 739f346584
commit 86a59e4de4

View file

@ -60,6 +60,7 @@ enum enum_value {
VAL_NOTUSED, VAL_NOTUSED,
VAL_STRING, VAL_STRING,
VAL_SYMBOL, VAL_SYMBOL,
VAL_SYMBOL_SET,
VAL_DOUBLE VAL_DOUBLE
}; };
@ -71,6 +72,8 @@ struct value {
} v_field; } v_field;
}; };
static int gripe(char *fmt, ...) ATTRIBUTE((format (printf, 1, 2)));
static int static int
gripe(char *fmt, ...) gripe(char *fmt, ...)
{ {
@ -103,6 +106,15 @@ skipfs(FILE *fp)
return ch; return ch;
} }
static int
getid(FILE *fp, char *buf)
{
int n;
if (fscanf(fp, "%1023[^#() \t\n]%n", buf, &n) != 1 || !isalpha(buf[0]))
return -1;
return n;
}
static char * static char *
xuesc(char *buf) xuesc(char *buf)
{ {
@ -129,6 +141,8 @@ xuflds(FILE *fp, struct value values[])
{ {
int i, ch; int i, ch;
char buf[1024]; char buf[1024];
char *p;
int len, l1;
for (i = 0; ; i++) { for (i = 0; ; i++) {
values[i].v_type = VAL_NOTUSED; values[i].v_type = VAL_NOTUSED;
@ -164,9 +178,32 @@ xuflds(FILE *fp, struct value values[])
values[i].v_type = VAL_STRING; values[i].v_type = VAL_STRING;
values[i].v_field.v_string = strdup(buf); values[i].v_field.v_string = strdup(buf);
break; break;
case '(':
p = strdup("");
len = 0;
for (;;) {
ch = skipfs(fp);
if (ch == EOF || ch == '\n')
return gripe("Unmatched '(' in field %d", i + 1);
if (ch == ')')
break;
ungetc(ch, fp);
l1 = getid(fp, buf);
if (l1 < 0)
return gripe("Junk in field %d", i + 1);
p = realloc(p, len + l1 + 2);
strcpy(p + len, buf);
strcpy(p + len + l1, " ");
len += l1 + 1;
}
if (len)
p[len - 1] = 0;
values[i].v_type = VAL_SYMBOL_SET;
values[i].v_field.v_string = p;
break;
default: default:
ungetc(ch, fp); ungetc(ch, fp);
if (fscanf(fp, "%1023[^ \t#\n]", buf) != 1 || !isalpha(buf[0])) { if (getid(fp, buf) < 0) {
return gripe("Junk in field %d", i + 1); return gripe("Junk in field %d", i + 1);
} }
if (!strcmp(buf, "nil")) { if (!strcmp(buf, "nil")) {
@ -198,34 +235,47 @@ freeflds(struct value values[])
} }
static int static int
xunsymbol(struct castr *ca, struct value *vp) xunsymbol1(char *id, struct symbol *symtab, struct castr *ca, int n)
{
int i = stmtch(id, symtab, offsetof(struct symbol, name),
sizeof(struct symbol));
if (i < 0)
return gripe("%s %s symbol `%s' in field %d",
i == M_NOTUNIQUE ? "Ambiguous" : "Unknown",
ca->ca_name, id, n);
return i;
}
static int
xunsymbol(struct castr *ca, struct value *vp, int n)
{ {
struct symbol *symtab = (struct symbol *)empfile[ca->ca_table].cache; struct symbol *symtab = (struct symbol *)empfile[ca->ca_table].cache;
char *buf = vp->v_field.v_string; char *buf = vp->v_field.v_string;
int i; int i;
int value = 0; int value;
char *token; char *token;
if (ca->ca_flags & NSC_BITS) if (vp->v_type == VAL_SYMBOL_SET) {
token = strtok( buf, "|"); if (!(ca->ca_flags & NSC_BITS) || ca->ca_table == EF_BAD)
else return gripe("%s doesn't take a symbol set in field %d",
token = buf; ca->ca_name, n);
value = 0;
if (!token || token[0] == '\0') for (token = strtok(buf, " "); token; token = strtok(NULL, " ")) {
return gripe("Empty symbol value for field %s", ca->ca_name); i = xunsymbol1(token, symtab, ca, n);
if (i < 0)
while (token) { return -1;
if ((i = stmtch(token, symtab, offsetof(struct symbol, name),
sizeof(struct symbol))) != M_NOTFOUND) {
if (!(ca->ca_flags & NSC_BITS))
return(symtab[i].value);
value |= symtab[i].value; value |= symtab[i].value;
} }
else } else if (vp->v_type == VAL_SYMBOL) {
return gripe("Symbol %s was not found for field %s", token, if ((ca->ca_flags & NSC_BITS) || ca->ca_table == EF_BAD)
ca->ca_name); return gripe("%s doesn't take a symbol in field %d",
token = strtok(NULL, "|"); ca->ca_name, n);
} i = xunsymbol1(buf, symtab, ca, n);
if (i < 0)
return -1;
value = symtab[i].value;
} else
return 0;
vp->v_type = VAL_DOUBLE; vp->v_type = VAL_DOUBLE;
vp->v_field.v_double = value; vp->v_field.v_double = value;
@ -282,11 +332,8 @@ xuloadrow(int type, int row, struct value values[])
*/ */
switch (values[j].v_type) { switch (values[j].v_type) {
case VAL_SYMBOL: case VAL_SYMBOL:
if (ca[i].ca_table == EF_BAD) case VAL_SYMBOL_SET:
return(gripe("Found symbol string %s, but column %s " if (xunsymbol(&ca[i], &values[j], j) < 0)
"is not symbol or symbol sets",
values[j].v_field.v_string, ca[i].ca_name));
if (xunsymbol(&ca[i], &values[j]) < 0)
return -1; return -1;
/* fall through */ /* fall through */
case VAL_DOUBLE: case VAL_DOUBLE:
@ -412,6 +459,7 @@ xuloadrow(int type, int row, struct value values[])
break; break;
case VAL_STRING: case VAL_STRING:
case VAL_SYMBOL: case VAL_SYMBOL:
case VAL_SYMBOL_SET:
return gripe("Extra junk after the last column, read %s", return gripe("Extra junk after the last column, read %s",
values[j].v_field.v_string); values[j].v_field.v_string);
case VAL_DOUBLE: case VAL_DOUBLE: