From bfee6962fc9d3808d9703d7dbea2c0b99dcee755 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 5 Aug 2007 18:38:37 +0000 Subject: [PATCH] Fix fields checks for split tables: (caseen): Remove. (xufldhdr, deffld): Record only fields in this part in caflds[]. This fixes the check for duplicate fields in parts other than the first. (cafldspp): New, to record fields in previous parts. (xundump): Initialize and finalize it. (xufooter): Update it. Requires new parameter ca. Caller changed. (fldval_must_match): Use it to do the right thing for split arrays. (chkflds): Adapt for changed caflds[]. (chkflds): The check for missing fields was skipped for all parts of a split table instead of for all but the final part. --- src/lib/common/xundump.c | 60 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index 9ffb3ee0d..b4fc6544b 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -43,7 +43,6 @@ * - Symbolic array indexes * TODO, but hardly worth the effort: * - Permit reordering of array elements - * - Permit repetition of array elements in split tables */ #include @@ -68,8 +67,8 @@ static int cur_obj_is_blank; static int nflds; static struct castr **fldca; static int *fldidx; -static int *caflds; -static unsigned char *caseen; +static int *caflds; /* Map selector number to #fields seen */ +static int *cafldspp; /* ditto, in previous parts */ static int gripe(char *, ...) ATTRIBUTE((format (printf, 1, 2))); static int deffld(int, char *, int); @@ -321,15 +320,13 @@ deffld(int fldno, char *name, int idx) return gripe("Header %s doesn't take an index in field %d", ca[res].ca_name, fldno + 1); idx = 0; - if (caflds[res] && !caseen[res]) - /* FIXME doesn't catch dupes within table part when caseen[res] */ + if (caflds[res]) return gripe("Duplicate header %s in field %d", ca[res].ca_name, fldno + 1); } fldca[fldno] = &ca[res]; fldidx[fldno] = idx; - if (!caseen[res]) - caflds[res]++; + caflds[res]++; return 1; } @@ -349,29 +346,30 @@ static int chkflds(void) { struct castr *ca = ef_cadef(cur_type); - int i, len, res = 0; + int i, len, cafldsmax, res = 0; if (is_partial) { - /* Require index field */ + /* Need a join field, use 0-th selector */ if (!caflds[0]) return gripe("Header field %s required with ...", ca[0].ca_name); - /* Want the index field again in continued table: */ - caflds[0] = 0; - return 0; } + if (ellipsis) + return 0; + for (i = 0; ca[i].ca_name; i++) { + cafldsmax = MAX(caflds[i], cafldspp[i]); if (ca[i].ca_flags & NSC_EXTRA) continue; len = ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0; - if (!len && !caflds[i]) + if (!len && !cafldsmax) res = gripe("Header field %s missing", ca[i].ca_name); - else if (len && caflds[i] == len - 1) + else if (len && cafldsmax == len - 1) res = gripe("Header field %s(%d) missing", ca[i].ca_name, len - 1); - else if (len && caflds[i] < len - 1) + else if (len && cafldsmax < len - 1) res = gripe("Header fields %s(%d) ... %s(%d) missing", - ca[i].ca_name, caflds[i], ca[i].ca_name, len - 1); + ca[i].ca_name, cafldsmax, ca[i].ca_name, len - 1); } return res; @@ -397,8 +395,13 @@ fldval_must_match(int fldno) struct castr *ca = ef_cadef(cur_type); int i = fldca[fldno] - ca; + /* + * Value must match if: + * it's for a const selector, unless the object is still blank, or + * it was already given in a previous part of a split table. + */ return (!cur_obj_is_blank && (fldca[fldno]->ca_flags & NSC_CONST)) - || caseen[i]; + || fldidx[fldno] < cafldspp[i]; } static void * @@ -687,6 +690,8 @@ xufldhdr(FILE *fp, struct castr ca[]) int *fidx; int ch, i, j, n; + for (i = 0; ca[i].ca_name; i++) + caflds[i] = 0; ellipsis = 0; if (human) { @@ -719,9 +724,9 @@ xufldhdr(FILE *fp, struct castr ca[]) } static int -xufooter(FILE *fp, int row) +xufooter(FILE *fp, struct castr ca[], int row) { - int rows, res; + int res, rows, i; res = -1; if (human) { @@ -738,6 +743,11 @@ xufooter(FILE *fp, int row) return gripe("Junk after table footer"); lineno++; + for (i = 0; ca[i].ca_name; i++) { + if (cafldspp[i] < caflds[i]) + cafldspp[i] = caflds[i]; + } + return 0; } @@ -765,14 +775,14 @@ xundump(FILE *fp, char *file, int *plno, int expected_table) } fldca = calloc(nf, sizeof(*fldca)); fldidx = calloc(nf, sizeof(*fldidx)); - caflds = calloc(nca, sizeof(*caflds)); - caseen = calloc(nca, sizeof(*caseen)); + caflds = malloc(nca * sizeof(*caflds)); + cafldspp = calloc(nca, sizeof(*cafldspp)); cur_type = type; if (xutail(fp, ca) < 0) type = EF_BAD; - free(caseen); + free(cafldspp); free(caflds); free(fldidx); free(fldca); @@ -789,7 +799,7 @@ xundump(FILE *fp, char *file, int *plno, int expected_table) static int xutail(FILE *fp, struct castr *ca) { - int recs, i; + int recs; is_partial = 0; for (;;) { @@ -797,12 +807,10 @@ xutail(FILE *fp, struct castr *ca) return -1; if ((recs = xubody(fp)) < 0) return -1; - if (xufooter(fp, recs) < 0) + if (xufooter(fp, ca, recs) < 0) return -1; if (!ellipsis) return 0; - for (i = 0; ca[i].ca_name; i++) - caseen[i] = caflds[i] != 0; if (xuheader(fp, cur_type) < 0) return -1; } -- 2.43.0