(xufldname, xufld): New, factored out of xuflds and specialized for
headers and for body lines, respectively. (xflds): Call them through new parameter parse. Callers changed.
This commit is contained in:
parent
361e33d70f
commit
8a6438b4e0
1 changed files with 130 additions and 104 deletions
|
@ -144,121 +144,147 @@ xuesc(char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xuflds(FILE *fp, struct value values[])
|
xufldname(FILE *fp, struct value values[], int i)
|
||||||
{
|
{
|
||||||
int i, ch;
|
int ch;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
values[i].v_type = VAL_NOTUSED;
|
||||||
|
|
||||||
|
ch = skipfs(fp);
|
||||||
|
switch (ch) {
|
||||||
|
case EOF:
|
||||||
|
return gripe("Unexpected EOF");
|
||||||
|
case '\n':
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
ungetc(ch, fp);
|
||||||
|
if (getid(fp, buf) < 0)
|
||||||
|
return gripe("Junk in field %d", i + 1);
|
||||||
|
ch = getc(fp);
|
||||||
|
if (ch != '(') {
|
||||||
|
ungetc(ch, fp);
|
||||||
|
values[i].v_type = VAL_SYMBOL;
|
||||||
|
values[i].v_field.v_string = strdup(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ch = getc(fp);
|
||||||
|
ungetc(ch, fp);
|
||||||
|
if (isdigit(ch) || ch == '-' || ch == '+') {
|
||||||
|
if (fscanf(fp, "%d", &values[i].v_field.v_int) != 1) {
|
||||||
|
return gripe("Malformed number in index field %d", i + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getid(fp, buf) < 0)
|
||||||
|
return gripe("Malformed string in index field %d", i + 1);
|
||||||
|
return gripe("Symbolic index in field %d not yet implemented",
|
||||||
|
i + 1);
|
||||||
|
}
|
||||||
|
ch = getc(fp);
|
||||||
|
if (ch != ')')
|
||||||
|
return gripe("Malformed index field %d", i + 1);
|
||||||
|
values[i].v_index_name = strdup(buf);
|
||||||
|
values[i].v_type = VAL_INDEX_ID;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xufld(FILE *fp, struct value values[], int i)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *p;
|
char *p;
|
||||||
int len, l1;
|
int len, l1;
|
||||||
|
|
||||||
|
values[i].v_type = VAL_NOTUSED;
|
||||||
|
|
||||||
|
ch = skipfs(fp);
|
||||||
|
switch (ch) {
|
||||||
|
case EOF:
|
||||||
|
return gripe("Unexpected EOF");
|
||||||
|
case '\n':
|
||||||
|
return 0;
|
||||||
|
case '+': case '-': case '.':
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
ungetc(ch, fp);
|
||||||
|
if (fscanf(fp, "%lg", &values[i].v_field.v_double) != 1)
|
||||||
|
return gripe("Malformed number in field %d", i + 1);
|
||||||
|
values[i].v_type = VAL_DOUBLE;
|
||||||
|
return 1;
|
||||||
|
case '"':
|
||||||
|
ch = getc(fp);
|
||||||
|
if (ch == '"')
|
||||||
|
buf[0] = 0;
|
||||||
|
else {
|
||||||
|
ungetc(ch, fp);
|
||||||
|
if (fscanf(fp, "%1023[^\"\n]", buf) != 1 || getc(fp) != '"')
|
||||||
|
return gripe("Malformed string in field %d", i + 1);
|
||||||
|
if (!xuesc(buf))
|
||||||
|
return gripe("Invalid escape sequence in field %d",
|
||||||
|
i + 1);
|
||||||
|
}
|
||||||
|
values[i].v_type = VAL_STRING;
|
||||||
|
values[i].v_field.v_string = strdup(buf);
|
||||||
|
return 1;
|
||||||
|
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;
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
ungetc(ch, fp);
|
||||||
|
if (getid(fp, buf) < 0)
|
||||||
|
return gripe("Junk in field %d", i + 1);
|
||||||
|
if (!strcmp(buf, "nil")) {
|
||||||
|
values[i].v_type = VAL_STRING;
|
||||||
|
values[i].v_field.v_string = NULL;
|
||||||
|
} else {
|
||||||
|
values[i].v_type = VAL_SYMBOL;
|
||||||
|
values[i].v_field.v_string = strdup(buf);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xuflds(FILE *fp, struct value values[],
|
||||||
|
int (*parse)(FILE *, struct value values[], int))
|
||||||
|
{
|
||||||
|
int i, ch, res;
|
||||||
|
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
values[i].v_type = VAL_NOTUSED;
|
|
||||||
if (i >= MAX_NUM_COLUMNS)
|
if (i >= MAX_NUM_COLUMNS)
|
||||||
return gripe("Too many columns");
|
return gripe("Too many columns");
|
||||||
|
res = parse(fp, values, i);
|
||||||
ch = skipfs(fp);
|
if (res < 0)
|
||||||
switch (ch) {
|
return -1;
|
||||||
case EOF:
|
if (res == 0)
|
||||||
return gripe("Unexpected EOF");
|
|
||||||
case '\n':
|
|
||||||
return i;
|
return i;
|
||||||
case '+': case '-': case '.':
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
|
||||||
ungetc(ch, fp);
|
|
||||||
if (fscanf(fp, "%lg", &values[i].v_field.v_double) != 1)
|
|
||||||
return gripe("Malformed number in field %d", i + 1);
|
|
||||||
values[i].v_type = VAL_DOUBLE;
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
ch = getc(fp);
|
|
||||||
if (ch == '"')
|
|
||||||
buf[0] = 0;
|
|
||||||
else {
|
|
||||||
ungetc(ch, fp);
|
|
||||||
if (fscanf(fp, "%1023[^\"\n]", buf) != 1 || getc(fp) != '"')
|
|
||||||
return gripe("Malformed string in field %d", i + 1);
|
|
||||||
if (!xuesc(buf))
|
|
||||||
return gripe("Invalid escape sequence in field %d",
|
|
||||||
i + 1);
|
|
||||||
}
|
|
||||||
values[i].v_type = VAL_STRING;
|
|
||||||
values[i].v_field.v_string = strdup(buf);
|
|
||||||
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:
|
|
||||||
ungetc(ch, fp);
|
|
||||||
if (getid(fp, buf) < 0) {
|
|
||||||
return gripe("Junk in field %d", i + 1);
|
|
||||||
}
|
|
||||||
ch = getc(fp);
|
|
||||||
ungetc(ch, fp);
|
|
||||||
if (ch == '(') {
|
|
||||||
ch = getc(fp);
|
|
||||||
ch = getc(fp);
|
|
||||||
ungetc(ch, fp);
|
|
||||||
if (isdigit(ch) || ch == '-') {
|
|
||||||
if (fscanf(fp, "%d", &values[i].v_field.v_int) != 1) {
|
|
||||||
return gripe("Malformed number in index field %d", i + 1);
|
|
||||||
}
|
|
||||||
values[i].v_index_name = strdup(buf);
|
|
||||||
values[i].v_type = VAL_INDEX_ID;
|
|
||||||
} else {
|
|
||||||
values[i].v_index_name = strdup(buf);
|
|
||||||
if (getid(fp, buf) < 0) {
|
|
||||||
free(values[i].v_index_name);
|
|
||||||
values[i].v_index_name = NULL;
|
|
||||||
return gripe("Malformed string in index field %d", i + 1);
|
|
||||||
}
|
|
||||||
values[i].v_field.v_string = strdup(buf);
|
|
||||||
values[i].v_type = VAL_INDEX_SYMBOL;
|
|
||||||
}
|
|
||||||
ch = getc(fp);
|
|
||||||
if (ch != ')') {
|
|
||||||
free(values[i].v_index_name);
|
|
||||||
values[i].v_index_name = NULL;
|
|
||||||
if (values[i].v_type == VAL_INDEX_SYMBOL)
|
|
||||||
free(values[i].v_field.v_string);
|
|
||||||
values[i].v_type = VAL_NOTUSED;
|
|
||||||
return gripe("Malformed index field %d", i + 1);
|
|
||||||
}
|
|
||||||
} else if (!strcmp(buf, "nil")) {
|
|
||||||
values[i].v_type = VAL_STRING;
|
|
||||||
values[i].v_field.v_string = NULL;
|
|
||||||
} else {
|
|
||||||
values[i].v_type = VAL_SYMBOL;
|
|
||||||
values[i].v_field.v_string = strdup(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ch = getc(fp);
|
ch = getc(fp);
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
ungetc(ch, fp);
|
ungetc(ch, fp);
|
||||||
else if (ch != ' ' && ch != '\t') {
|
else if (ch != ' ' && ch != '\t')
|
||||||
values[i].v_type = VAL_NOTUSED;
|
|
||||||
return gripe("Bad field separator after field %d", i + 1);
|
return gripe("Bad field separator after field %d", i + 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +614,7 @@ xucolumnheader(FILE *fp, int type, struct value values[])
|
||||||
ungetc(ch, fp);
|
ungetc(ch, fp);
|
||||||
|
|
||||||
/* FIXME parse column header */
|
/* FIXME parse column header */
|
||||||
if (xuflds(fp, values) <= 0) {
|
if (xuflds(fp, values, xufldname) <= 0) {
|
||||||
freeflds(values);
|
freeflds(values);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -732,7 +758,7 @@ xundump(FILE *fp, char *file, int expected_table)
|
||||||
* TODO
|
* TODO
|
||||||
* Add column count check to the return value of xuflds()
|
* Add column count check to the return value of xuflds()
|
||||||
*/
|
*/
|
||||||
res = xuflds(fp, values);
|
res = xuflds(fp, values, xufld);
|
||||||
if (res > 0 && row >= ep->csize - 1) {
|
if (res > 0 && row >= ep->csize - 1) {
|
||||||
/* TODO grow cache unless EFF_STATIC */
|
/* TODO grow cache unless EFF_STATIC */
|
||||||
gripe("Too many rows for table %s", ef_nameof(type));
|
gripe("Too many rows for table %s", ef_nameof(type));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue