(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:
parent
739f346584
commit
86a59e4de4
1 changed files with 74 additions and 26 deletions
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue