]> git.pond.sub.org Git - empserver/blobdiff - src/lib/common/xundump.c
Clean up redundant forward declarations
[empserver] / src / lib / common / xundump.c
index 1301d7def96aad3492bfc2f7c202ca9656f373e7..14e88bfa8fc4c4207cab3939be38e78c2b1f2a29 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                Ken Stevens, Steve McClure, Markus Armbruster
  *
  *  Empire is free software: you can redistribute it and/or modify
@@ -43,7 +43,6 @@
  * - Normalize terminology: table/rows/columns or file/records/fields
  * - Loading tables with NSC_STRING elements more than once leaks memory
  * TODO:
- * - Check EFF_CFG tables are dense
  * - Symbolic array indexes
  * - Option to treat missing and unknown fields as warning, not error
  * TODO, but hardly worth the effort:
@@ -71,9 +70,9 @@ static int cur_type;          /* Current table's file type */
 static int partno;             /* Counts from 0..#parts-1 */
 static void *cur_obj;          /* The object being read into */
 static int cur_id;             /* and its index in the table */
-static int cur_obj_is_blank;
+static int old_nelem;
 static unsigned char *idgap;   /* idgap && idgap[ID] iff part#0 lacks ID */
-static int idgap_max;          /* FIXME */
+static int idgap_len;          /* #elements in idgap[] */
 
 static int human;              /* Reading human-readable syntax? */
 static int ellipsis;           /* Header ended with ...? */
@@ -82,6 +81,7 @@ static struct castr **fldca;  /* Map field number to selector */
 static int *fldidx;            /* Map field number to index */
 static int *caflds;            /* Map selector number to #fields seen */
 static int *cafldspp;          /* ditto, in previous parts */
+static int may_omit_id;                /* Okay to omit IDs? */
 static int may_trunc;          /* Okay to truncate? */
 
 static int gripe(char *, ...) ATTRIBUTE((format (printf, 1, 2)));
@@ -90,7 +90,6 @@ static int defellipsis(void);
 static int chkflds(void);
 static int setnum(int, double);
 static int setstr(int, char *);
-static int xunsymbol(char *, struct castr *, int);
 static int setsym(int, char *);
 static int mtsymset(int, long *);
 static int add2symset(int, long *, char *);
@@ -122,8 +121,9 @@ tbl_start(int type)
     partno = 0;
     cur_id = -1;
     cur_obj = NULL;
+    old_nelem = type == EF_BAD ? 0 : ef_nelem(type);
     idgap = NULL;
-    idgap_max = 0;
+    idgap_len = 0;
 }
 
 /* End the current table.  */
@@ -137,7 +137,7 @@ tbl_end(void)
 /*
  * Seek to current table's ID-th record.
  * ID must be acceptable.
- * Store it in cur_obj, and set cur_id and cur_obj_is_blank accordingly.
+ * Store it in cur_obj, and set cur_id accordingly.
  * Return 0 on success, -1 on failure.
  */
 static int
@@ -145,8 +145,6 @@ tbl_seek(int id)
 {
     struct empfile *ep = &empfile[cur_type];
 
-    cur_obj_is_blank = id >= ep->fids;
-
     if (id >= ef_nelem(cur_type)) {
        if (!ef_ensure_space(cur_type, id, 1))
            return gripe("Can't put ID %d into table %s", id, ep->name);
@@ -162,7 +160,7 @@ tbl_seek(int id)
 /*
  * Get the next object.
  * Must not have a record index.
- * Store it in cur_obj, and set cur_id and cur_obj_is_blank accordingly.
+ * Store it in cur_obj, and set cur_id accordingly.
  * Return 0 on success, -1 on failure.
  */
 static int
@@ -177,6 +175,7 @@ tbl_next_obj(void)
 
 /*
  * Omit ID1..ID2-1.
+ * Reset the omitted objects to default state.
  */
 static void
 omit_ids(int id1, int id2)
@@ -186,13 +185,14 @@ omit_ids(int id1, int id2)
     if (id1 >= id2)
        return;
 
-    idgap = realloc(idgap, (id2 + 1) * sizeof(*idgap));
-    for (i = idgap_max; i < id1; i++)
+    idgap = realloc(idgap, id2 * sizeof(*idgap));
+    for (i = idgap_len; i < id1; i++)
        idgap[i] = 0;
-    for (i = id1; i < id2; i++)
+    for (i = id1; i < id2; i++) {
+       ef_blank(cur_type, i, ef_ptr(cur_type, i));
        idgap[i] = 1;
-    idgap[id2] = 0;
-    idgap_max = id2;
+    }
+    idgap_len = id2;
 }
 
 /*
@@ -204,7 +204,7 @@ expected_id(int id1, int id2)
     int i;
 
     for (i = id1; i < id2; i++) {
-       if (i >= idgap_max || !idgap[i])
+       if (i >= idgap_len || !idgap[i])
            return i;
     }
     return -1;
@@ -212,8 +212,9 @@ expected_id(int id1, int id2)
 
 /*
  * Get the next object, it has record index ID.
- * Store it in cur_obj, and set cur_id and cur_obj_is_blank accordingly.
+ * 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
@@ -224,6 +225,8 @@ tbl_skip_to_obj(int id)
     int max_id, exp_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);
@@ -251,6 +254,7 @@ tbl_skip_to_obj(int id)
  * Finish table part.
  * If the table has variable length, truncate it.
  * Else 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
@@ -265,8 +269,10 @@ tbl_part_done(void)
                if (!ef_truncate(cur_type, cur_id + 1))
                    return -1;
            } else {
-               return gripe("Expected %d more rows",
-                            ep->fids - (cur_id + 1));
+               if (!may_omit_id)
+                   return gripe("Expected %d more rows",
+                                ep->fids - (cur_id + 1));
+               omit_ids(cur_id + 1, ep->fids);
            }
        } else {
            exp_id = expected_id(cur_id + 1, ep->fids);
@@ -654,7 +660,7 @@ fldval_must_match(int fldno)
      * 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))
+    return (cur_id < old_nelem && (fldca[fldno]->ca_flags & NSC_CONST))
        || fldidx[fldno] < cafldspp[i];
 }
 
@@ -1075,13 +1081,14 @@ xundump(FILE *fp, char *file, int *plno, int expected_table)
        return -1;
 
     nca = nf = 0;
+    may_omit_id = 1;
     may_trunc = empfile[type].nent < 0;
     for (i = 0; ca[i].ca_name; i++) {
        nca++;
        if (!(ca[i].ca_flags & NSC_EXTRA)) {
            nf += MAX(1, ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0);
            if (ca[i].ca_flags & NSC_CONST)
-               may_trunc = 0;
+               may_omit_id = may_trunc = 0;
        }
     }
     fldca = malloc(nf * sizeof(*fldca));