]> git.pond.sub.org Git - empserver/blobdiff - src/lib/common/xundump.c
Clean up omit_ids() not to set an extra element in idgap[]
[empserver] / src / lib / common / xundump.c
index e361c8bc4691771dbaf87034a5de2d5d037f3562..0059ee2a9b7373832f2d9444924e13fbaec3b8b3 100644 (file)
@@ -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 ...? */
@@ -123,8 +122,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.  */
@@ -138,7 +138,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
@@ -146,8 +146,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);
@@ -163,7 +161,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
@@ -178,6 +176,7 @@ tbl_next_obj(void)
 
 /*
  * Omit ID1..ID2-1.
+ * Reset the omitted objects to default state.
  */
 static void
 omit_ids(int id1, int id2)
@@ -187,13 +186,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;
 }
 
 /*
@@ -205,7 +205,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;
@@ -213,8 +213,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
@@ -254,6 +255,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
@@ -268,8 +270,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);
@@ -657,7 +661,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];
 }