diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index 305714a5..53a647b7 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -130,7 +130,8 @@ ca0_is_id(int type) static int can_fill_gaps(int type) { - return ca0_is_id(type) && !have_hardcoded_indexes(type); + return (ca0_is_id(type) || type == EF_SECTOR) + && !have_hardcoded_indexes(type); } /* @@ -342,6 +343,56 @@ rowid(void) return id; } +/* + * Find the field NAME with index IDX and value representable as long. + * Return the field number if it exists, else -1. + */ +static int +fld_find_long_by_name(char *name, int idx) +{ + int i; + + for (i = 0; i < nflds; i++) { + if (!strcmp(fldca[i]->ca_name, name) && fldidx[i] == idx) + break; + } + + if (i == nflds || fldval[i].val_type != NSC_DOUBLE + || (long)fldval[i].val_as.dbl != fldval[i].val_as.dbl) + return -1; + return i; +} + +/* + * Get the current row's ID. + * Current table's type must be EF_SECTOR. + * Return ID on success, -1 on failure. + */ +static int +rowid_sect(void) +{ + int fldno_x, fldno_y, id; + coord x, y; + + if (CANT_HAPPEN(partno != 0 || cur_type != EF_SECTOR)) + return -1; + + fldno_x = fld_find_long_by_name("xloc", 0); + fldno_y = fld_find_long_by_name("yloc", 0); + if (fldno_x < 0 || fldno_y < 0) + return cur_id + 1; + + id = sctoff((long)fldval[fldno_x].val_as.dbl, + (long)fldval[fldno_y].val_as.dbl); + /* Note: reporting values out of range left to putnum() */ + if (id <= cur_id) { + sctoff2xy(&x, &y, cur_id); + return gripe("Coordinates in fields %d,%d must be > %d,%d", + fldno_x + 1, fldno_y + 1, x, y); + } + return id; +} + /* * Get the current row's object. * Extend the table if necessary. @@ -365,6 +416,10 @@ rowobj(void) id = rowid(); if (id < 0) return NULL; + } else if (cur_type == EF_SECTOR) { + id = rowid_sect(); + if (id < 0) + return NULL; } else id = last_id + 1; if (id > ef_id_limit(cur_type)) { diff --git a/tests/empdump/errors.err b/tests/empdump/errors.err index d604c696..ea76e977 100644 --- a/tests/empdump/errors.err +++ b/tests/empdump/errors.err @@ -45,6 +45,7 @@ tests/empdump/xundump-errors/fld-invid1:3: Expected 0 in field 1 tests/empdump/xundump-errors/fld-invid2:3: Field 1 must be > -1 tests/empdump/xundump-errors/fld-invid3:4: Field 1 must be > 2 tests/empdump/xundump-errors/fld-invid4:3: Field 1 must be <= 98 +tests/empdump/xundump-errors/fld-invid5:4: Coordinates in fields 1,2 must be > 2,0 tests/empdump/xundump-errors/fld-junk:2: Junk in field 1 tests/empdump/xundump-errors/fld-junk2:2: Junk in field 19 tests/empdump/xundump-errors/fld-malnum:2: Malformed number in field 1 diff --git a/tests/empdump/errors.status b/tests/empdump/errors.status index 7fbeef1b..da7383b0 100644 --- a/tests/empdump/errors.status +++ b/tests/empdump/errors.status @@ -69,6 +69,7 @@ 1 1 1 +1 0 1 0 diff --git a/tests/empdump/xundump-errors/fld-invid5 b/tests/empdump/xundump-errors/fld-invid5 new file mode 100644 index 00000000..99f03997 --- /dev/null +++ b/tests/empdump/xundump-errors/fld-invid5 @@ -0,0 +1,5 @@ +config sect +xloc yloc ... +2 0 +0 0 +# Coordinates in fields 1,2 must be > 2,0