diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index 12854457..d0cb523f 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -406,10 +406,11 @@ xundump(FILE *fp, char *file, int expected_table) { char name[64]; char sep; + struct empfile *ep; int row, res, rows, ch; struct value values[MAX_NUM_COLUMNS + 1]; int type; - int fixed_rows; + int fixed_rows, need_sentinel; if (strcmp(fname, file) != 0) { fname = file; @@ -425,12 +426,16 @@ xundump(FILE *fp, char *file, int expected_table) type = ef_byname(name); if (type < 0) return gripe("Unknown table `%s'", name); + ep = &empfile[type]; + if (CANT_HAPPEN(!(ep->flags & EFF_MEM))) + return -1; /* not implemented */ if (expected_table != EF_BAD && expected_table != type) return gripe("Expected table `%s', not `%s'", ef_nameof(expected_table), name); fixed_rows = has_const(ef_cadef(type)); + need_sentinel = !fixed_rows; /* FIXME only approximation */ for (row = 0; ; row++) { lineno++; @@ -443,12 +448,12 @@ xundump(FILE *fp, char *file, int expected_table) * Add column count check to the return value of xuflds() */ res = xuflds(fp, values); - if (res > 0 && row >= empfile[type].csize - 1) { + if (res > 0 && row >= ep->csize - 1) { + /* TODO grow cache unless EFF_STATIC */ gripe("Too many rows for table %s", name); res = -1; } if (res > 0) { - empfile[type].fids = row + 1; if (!fixed_rows) xuinitrow(type, row); res = xuloadrow(type, row, values); @@ -465,14 +470,14 @@ xundump(FILE *fp, char *file, int expected_table) if (row != rows) return gripe("Read %d rows, which doesn't match footer", row); - if (fixed_rows && row != empfile[type].csize -1) + if (fixed_rows && row != ep->csize -1) return gripe("Table %s requires %d rows, got %d", - name, empfile[type].csize - 1, row); + name, ep->csize - 1, row); if (sep != '\n') return gripe("Junk after table footer"); - - if (!fixed_rows) + if (need_sentinel) xuinitrow(type, row); - return 0; + ep->fids = ep->cids = row; + return type; } diff --git a/src/lib/subs/fileinit.c b/src/lib/subs/fileinit.c index 7f1dc2b0..8af390d2 100644 --- a/src/lib/subs/fileinit.c +++ b/src/lib/subs/fileinit.c @@ -35,6 +35,56 @@ #include "file.h" #include "prototypes.h" +struct fileinit { + int ef_type; + void (*init) (int, char *); + int (*postread) (int, char *); + int (*prewrite) (int, char *); +}; + +static struct fileinit fileinit[] = { + {EF_SECTOR, NULL, sct_postread, sct_prewrite}, + {EF_SHIP, shp_init, shp_postread, shp_prewrite}, + {EF_PLANE, pln_init, pln_postread, pln_prewrite}, + {EF_LAND, lnd_init, lnd_postread, lnd_prewrite}, + {EF_NUKE, nuk_init, nuk_postread, nuk_prewrite} +}; + +static void ef_open_srv(void); +static void ef_close_srv(void); + +/* + * Initialize empfile for full server operations. + * Like ef_init(), but additionally installs the server's callbacks. + * This is separate from ef_init(), so that utility programs like + * files can use empfile. + */ +void +ef_init_srv(void) +{ + unsigned i; + + ef_init(); + if (ef_load() < 0) + exit(EXIT_FAILURE); + + for (i = 0; i < sizeof(fileinit) / sizeof(fileinit[0]); i++) { + empfile[fileinit[i].ef_type].init = fileinit[i].init; + empfile[fileinit[i].ef_type].postread = fileinit[i].postread; + empfile[fileinit[i].ef_type].prewrite = fileinit[i].prewrite; + } + ef_open_srv(); + if (ef_verify() < 0) + exit(EXIT_FAILURE); + global_init(); +} + +void +ef_fin_srv(void) +{ + ef_close_srv(); +} + static void ef_open_srv(void) { @@ -60,47 +110,6 @@ ef_open_srv(void) } } -struct fileinit { - int ef_type; - void (*init) (int, char *); - int (*postread) (int, char *); - int (*prewrite) (int, char *); -}; - -static struct fileinit fileinit[] = { - {EF_SECTOR, NULL, sct_postread, sct_prewrite}, - {EF_SHIP, shp_init, shp_postread, shp_prewrite}, - {EF_PLANE, pln_init, pln_postread, pln_prewrite}, - {EF_LAND, lnd_init, lnd_postread, lnd_prewrite}, - {EF_NUKE, nuk_init, nuk_postread, nuk_prewrite} -}; - -/* - * Initialize empfile for full server operations. - * Like ef_init(), but additionally installs the server's callbacks. - * This is separate from ef_init(), so that utility programs like - * files can use empfile. - */ -void -ef_init_srv(void) -{ - unsigned i; - - if (ef_load() < 0) - exit(EXIT_FAILURE); - - for (i = 0; i < sizeof(fileinit) / sizeof(fileinit[0]); i++) { - empfile[fileinit[i].ef_type].init = fileinit[i].init; - empfile[fileinit[i].ef_type].postread = fileinit[i].postread; - empfile[fileinit[i].ef_type].prewrite = fileinit[i].prewrite; - } - ef_init(); - ef_open_srv(); - if (ef_verify() < 0) - exit(EXIT_FAILURE); - global_init(); -} - static void ef_close_srv(void) { @@ -120,9 +129,3 @@ ef_close_srv(void) ef_close(EF_BMAP); ef_close(EF_LOST); } - -void -ef_fin_srv(void) -{ - ef_close_srv(); -}