From 515beef12eef02b76f1af8c35b160767bf9bfe0f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 8 Feb 2014 12:16:34 +0100 Subject: [PATCH] xundump: Support splitting any table Each part of a split table needs to supply rows for the same objects. We currently require each part to name its objects explicitly, with an object ID field, and don't support splitting tables that don't have such IDs. These restrictions became arbitrary when commit 4e23c45 implemented checking each partial table supplies the same rows. Relax them. Affects tables sect, news, lost, realm, game, infrastructure. Signed-off-by: Markus Armbruster --- src/lib/common/xundump.c | 109 ++++++------------ tests/empdump/errors.err | 8 +- tests/empdump/errors.status | 3 - tests/empdump/xundump-errors/colhdr-ellipsis | 2 +- tests/empdump/xundump-errors/colhdr-ellipsis3 | 3 - tests/empdump/xundump-errors/colhdr-ellipsis4 | 3 - tests/empdump/xundump-errors/colhdr-ellipsis5 | 4 - tests/empdump/xundump-errors/colhdr-miss2 | 1 - tests/empdump/xundump-errors/fld-unexpid1 | 2 +- 9 files changed, 41 insertions(+), 94 deletions(-) delete mode 100644 tests/empdump/xundump-errors/colhdr-ellipsis3 delete mode 100644 tests/empdump/xundump-errors/colhdr-ellipsis4 delete mode 100644 tests/empdump/xundump-errors/colhdr-ellipsis5 diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index 5426c47c..cd903ade 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -87,7 +87,6 @@ static int may_trunc; /* Okay to truncate? */ static int gripe(char *, ...) ATTRIBUTE((format (printf, 1, 2))); static int deffld(int, char *, int); -static int defellipsis(void); static int chkflds(void); static int setnum(int, double); static int setstr(int, char *); @@ -158,22 +157,6 @@ tbl_seek(int id) return 0; } -/* - * Get the next object. - * Must not have a record index. - * Store it in cur_obj, and set cur_id accordingly. - * Return 0 on success, -1 on failure. - */ -static int -tbl_next_obj(void) -{ - int max_id = ef_id_limit(cur_type); - - if (cur_id >= max_id) - return gripe("Too many rows"); - return tbl_seek(cur_id + 1); -} - /* * Omit ID1..ID2-1. * Reset the omitted objects to default state. @@ -214,43 +197,54 @@ expected_id(int id1, int id2) /* * Get the next object, it has record index ID. * Store it in cur_obj, and set cur_id accordingly. - * Ensure we're omitting the same objects as the previous parts. * Reset any omitted objects to default state. * Return 0 on success, -1 on failure. */ static int tbl_skip_to_obj(int id) { - struct empfile *ep = &empfile[cur_type]; int prev_id = cur_id; - int max_id, exp_id; + int max_id; - if (partno == 0) { - if (!may_omit_id && id != cur_id + 1) - return gripe("Expected %d in field %d", cur_id + 1, 1); - if (id <= cur_id) - return gripe("Field %d must be > %d", 1, cur_id); - max_id = ef_id_limit(cur_type); - if (id > max_id) - return gripe("Field %d must be <= %d", 1, max_id); - } else { - exp_id = expected_id(cur_id + 1, ep->fids); - if (exp_id < 0) - return gripe("Table's first part doesn't have this row"); - else if (id != exp_id) - return gripe("Expected %d in field %d," - " like in table's first part", - exp_id, 1); - } + if (CANT_HAPPEN(partno != 0)) + return -1; + if (!may_omit_id && id != cur_id + 1) + return gripe("Expected %d in field %d", cur_id + 1, 1); + if (id <= cur_id) + return gripe("Field %d must be > %d", 1, cur_id); + max_id = ef_id_limit(cur_type); + if (id > max_id) + return gripe("Field %d must be <= %d", 1, max_id); if (tbl_seek(id) < 0) return -1; - if (partno == 0) - omit_ids(prev_id + 1, id); + omit_ids(prev_id + 1, id); return 0; } +/* + * Get the next object. + * Store it in cur_obj, and set cur_id accordingly. + * Return 0 on success, -1 on failure. + */ +static int +tbl_next_obj(void) +{ + int next_id; + + if (partno == 0) { + if (cur_id >= ef_id_limit(cur_type)) + return gripe("Too many rows"); + next_id = cur_id + 1; + } else { + next_id = expected_id(cur_id + 1, empfile[cur_type].fids); + if (next_id < 0) + return gripe("Table's first part doesn't have this row"); + } + return tbl_seek(next_id); +} + /* * Finish table part. * If the table has variable length, truncate it. @@ -378,8 +372,9 @@ xufldname(FILE *fp, int i) case '.': if (getc(fp) != '.' || getc(fp) != '.') return gripe("Junk in header field %d", i + 1); - if (defellipsis() < 0) - return -1; + if (i == 0) + return gripe("Header fields expected"); + ellipsis = 1; ch = skipfs(fp); if (ch != EOF && ch != '\n') return gripe("Junk after ..."); @@ -563,29 +558,6 @@ deffld(int fldno, char *name, int idx) return 1; } -/* - * Record that header ends with ... - * Set ellipsis and is_partial. - * Return 0 on success, -1 on error. - */ -static int -defellipsis(void) -{ - struct castr *ca = ef_cadef(cur_type); - - if (ca[0].ca_table != cur_type || (ca[0].ca_flags & NSC_EXTRA)) - return gripe("Table %s doesn't support ...", ef_nameof(cur_type)); - ellipsis = 1; - return 0; -} - -/* Is table split into parts? */ -static int -is_partial(void) -{ - return ellipsis || partno; -} - /* * Check fields in xdump are sane. * Return 0 on success, -1 on error. @@ -600,13 +572,6 @@ chkflds(void) if (ca[0].ca_table == cur_type && caflds[0] && fldca[0] != &ca[0]) res = gripe("Header field %s must come first", ca[0].ca_name); - if (is_partial()) { - /* Need a join field, use 0-th selector */ - if (!caflds[0]) - res = gripe("Header field %s required in each table part", - ca[0].ca_name); - } - if (ellipsis) return res; /* table is split, another part expected */ @@ -683,7 +648,7 @@ setnum(int fldno, double dbl) return -1; if (fldno == 0) { - if (ca->ca_table == cur_type) { + if (partno == 0 && ca->ca_table == cur_type) { /* Got record index */ next_id = (int)dbl; if (next_id != dbl) diff --git a/tests/empdump/errors.err b/tests/empdump/errors.err index 3af703ca..54258d3a 100644 --- a/tests/empdump/errors.err +++ b/tests/empdump/errors.err @@ -2,11 +2,8 @@ tests/empdump/xundump-errors/colhdr-amb:2: Header m of field 3 is ambiguous tests/empdump/xundump-errors/colhdr-dup:2: Duplicate header name in field 2 tests/empdump/xundump-errors/colhdr-dup2:6: Duplicate header name in field 3 tests/empdump/xundump-errors/colhdr-dup3:2: Duplicate header pkg(0) in field 8 -tests/empdump/xundump-errors/colhdr-ellipsis:2: Header field uid required in each table part +tests/empdump/xundump-errors/colhdr-ellipsis:2: Header fields expected tests/empdump/xundump-errors/colhdr-ellipsis2:2: Junk after ... -tests/empdump/xundump-errors/colhdr-ellipsis3:2: Table infrastructure doesn't support ... -tests/empdump/xundump-errors/colhdr-ellipsis4:2: Header field uid required in each table part -tests/empdump/xundump-errors/colhdr-ellipsis5:2: Table sect doesn't support ... tests/empdump/xundump-errors/colhdr-eof:2: Unexpected EOF tests/empdump/xundump-errors/colhdr-first:2: Header field uid must come first tests/empdump/xundump-errors/colhdr-idxbig:2: Header pkg(99) index out of bounds in field 7 @@ -22,7 +19,6 @@ tests/empdump/xundump-errors/colhdr-miss:2: Header field uid missing tests/empdump/xundump-errors/colhdr-miss:2: Header field ctype(2) missing tests/empdump/xundump-errors/colhdr-miss:2: Header fields camt(0) ... camt(2) missing tests/empdump/xundump-errors/colhdr-miss:2: Header field nllag missing -tests/empdump/xundump-errors/colhdr-miss2:21: Header field uid required in each table part tests/empdump/xundump-errors/colhdr-miss2:21: Header fields ctype(0) ... ctype(2) missing tests/empdump/xundump-errors/colhdr-miss2:21: Header fields camt(0) ... camt(2) missing tests/empdump/xundump-errors/colhdr-miss2:21: Header field type missing @@ -75,7 +71,7 @@ tests/empdump/xundump-errors/fld-nosymset:2: Field 1 doesn't take symbol sets tests/empdump/xundump-errors/fld-sep:2: Bad field separator after field 1 tests/empdump/xundump-errors/fld-strbig:3: Field 19 takes at most 9 characters tests/empdump/xundump-errors/fld-unexpid:6: Table's first part doesn't have this row -tests/empdump/xundump-errors/fld-unexpid1:7: Expected 2 in field 1, like in table's first part +tests/empdump/xundump-errors/fld-unexpid1:7: Value for field 1 must be 2 tests/empdump/xundump-errors/fld-unksym:2: Unknown level symbol `xxx' in field 11 tests/empdump/xundump-errors/fld-unparen:2: Unmatched '(' in field 19 tests/empdump/xundump-errors/ftr-fewrows:2: Expected 1024 more rows diff --git a/tests/empdump/errors.status b/tests/empdump/errors.status index 3a96297f..7fbeef1b 100644 --- a/tests/empdump/errors.status +++ b/tests/empdump/errors.status @@ -69,9 +69,6 @@ 1 1 1 -1 -1 -1 0 1 0 diff --git a/tests/empdump/xundump-errors/colhdr-ellipsis b/tests/empdump/xundump-errors/colhdr-ellipsis index 3cf6e023..f23f0c8e 100644 --- a/tests/empdump/xundump-errors/colhdr-ellipsis +++ b/tests/empdump/xundump-errors/colhdr-ellipsis @@ -1,3 +1,3 @@ config product ... -# Header field uid required in each table part +# Header fields expected diff --git a/tests/empdump/xundump-errors/colhdr-ellipsis3 b/tests/empdump/xundump-errors/colhdr-ellipsis3 deleted file mode 100644 index 1cf602ce..00000000 --- a/tests/empdump/xundump-errors/colhdr-ellipsis3 +++ /dev/null @@ -1,3 +0,0 @@ -config infrastructure -name ... -# Table infrastructure doesn't support ... diff --git a/tests/empdump/xundump-errors/colhdr-ellipsis4 b/tests/empdump/xundump-errors/colhdr-ellipsis4 deleted file mode 100644 index cc65144e..00000000 --- a/tests/empdump/xundump-errors/colhdr-ellipsis4 +++ /dev/null @@ -1,3 +0,0 @@ -config product -sname name ... -# Header field uid required in each table part diff --git a/tests/empdump/xundump-errors/colhdr-ellipsis5 b/tests/empdump/xundump-errors/colhdr-ellipsis5 deleted file mode 100644 index 1a95aa54..00000000 --- a/tests/empdump/xundump-errors/colhdr-ellipsis5 +++ /dev/null @@ -1,4 +0,0 @@ -config sect -xloc yloc ... -# Table sect doesn't support ... -/config diff --git a/tests/empdump/xundump-errors/colhdr-miss2 b/tests/empdump/xundump-errors/colhdr-miss2 index 044641ed..11948969 100644 --- a/tests/empdump/xundump-errors/colhdr-miss2 +++ b/tests/empdump/xundump-errors/colhdr-miss2 @@ -19,7 +19,6 @@ uid sname ... config product name -# Header field uid required in each table part # Header fields ctype(0) ... ctype(2) missing # Header fields camt(0) ... camt(2) missing # Header field type missing diff --git a/tests/empdump/xundump-errors/fld-unexpid1 b/tests/empdump/xundump-errors/fld-unexpid1 index fe85f50b..14f4f485 100644 --- a/tests/empdump/xundump-errors/fld-unexpid1 +++ b/tests/empdump/xundump-errors/fld-unexpid1 @@ -5,5 +5,5 @@ uid ... config ship uid ... 1 -# Expected 2 in field 1, like in table's first part +# Value for field 1 must be 2 /config