]> git.pond.sub.org Git - empserver/commitdiff
Clean up maintenance of config table sentinels
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 1 Sep 2008 13:20:08 +0000 (09:20 -0400)
committerMarkus Armbruster <armbru@pond.sub.org>
Thu, 4 Sep 2008 00:43:13 +0000 (20:43 -0400)
Xundump had special hackery to maintain configuration tables'
sentinels: xubody() and getobj() added a sentinel element when
initializing or growing a table, which xubody() stripped off again
before returning.  The latter was an unclean hack.

Replace this by building knowledge of sentinels into struct empfile:
new flag EFF_SENTINEL, set for the appropriate members of empfile[],
obeyed by ef_extend() and ef_truncate().

include/file.h
src/lib/common/file.c
src/lib/common/xundump.c
src/lib/global/file.c

index 86846ba05ae469feee6d463320ae878c3cce2ce1..55aa672d94c53b69d45769f3287bd80780ab9cff 100644 (file)
@@ -99,6 +99,8 @@ struct emptypedstr {
 #define EFF_GROUP      bit(3)
 /* Table is allocated statically */
 #define EFF_STATIC     bit(4)
+/* Table has a sentinel (all zero, not counted as elt), implies EFF_MEM */
+#define EFF_SENTINEL   bit(5)
 /* All the immutable flags */
 #define EFF_IMMUTABLE \
     (EFF_TYPED | EFF_XY | EFF_OWNER | EFF_GROUP | EFF_STATIC)
index 0878928b0d21b903c9236c6b6944e09cf6a36e86..c3b082d72718c732f0e95067dfc81095c5e797db 100644 (file)
@@ -554,7 +554,7 @@ ef_extend(int type, int count)
 {
     struct empfile *ep;
     char *p;
-    int i, id;
+    int need_sentinel, i, id;
 
     if (ef_check(type) < 0)
        return 0;
@@ -564,13 +564,14 @@ ef_extend(int type, int count)
 
     id = ep->fids;
     if (ep->flags & EFF_MEM) {
-       if (id + count > ep->csize) {
+       need_sentinel = (ep->flags & EFF_SENTINEL) != 0;
+       if (id + count + need_sentinel > ep->csize) {
            if (ep->flags & EFF_STATIC) {
                logerror("Can't extend %s beyond %d elements",
-                        ep->name, ep->csize);
+                        ep->name, ep->csize - need_sentinel);
                return 0;
            }
-           if (!ef_realloc_cache(ep, id + count)) {
+           if (!ef_realloc_cache(ep, id + count + need_sentinel)) {
                logerror("Can't extend %s to %d elements (%s)",
                         ep->name, id + count, strerror(errno));
                return 0;
@@ -582,7 +583,9 @@ ef_extend(int type, int count)
            if (do_write(ep, p, id, count) < 0)
                return 0;
        }
-       ep->cids += count;
+       if (need_sentinel)
+           memset(ep->cache + (id + count) * ep->size, 0, ep->size);
+       ep->cids = id + count;
     } else {
        /* need a buffer, steal last cache slot */
        if (ep->cids == ep->csize)
@@ -594,7 +597,7 @@ ef_extend(int type, int count)
                return 0;
        }
     }
-    ep->fids += count;
+    ep->fids = id + count;
     return 1;
 }
 
@@ -646,6 +649,7 @@ int
 ef_truncate(int type, int count)
 {
     struct empfile *ep;
+    int need_sentinel;
 
     if (ef_check(type) < 0)
        return 0;
@@ -663,13 +667,16 @@ ef_truncate(int type, int count)
     ep->fids = count;
 
     if (ep->flags & EFF_MEM) {
+       need_sentinel = (ep->flags & EFF_SENTINEL) != 0;
        if (!(ep->flags & EFF_STATIC)) {
-           if (!ef_realloc_cache(ep, count)) {
+           if (!ef_realloc_cache(ep, count + need_sentinel)) {
                logerror("Can't shrink %s cache after truncate (%s)",
                         ep->name, strerror(errno));
                /* continue with unshrunk cache */
            }
        }
+       if (need_sentinel)
+           memset(ep->cache + count * ep->size, 0, ep->size);
        ep->cids = count;
     } else {
        if (ep->baseid >= count)
index 69914c3377e01b186707bc5177a356d98149fb4c..abef9c27e664d1a6b73198938a3d44de72e2c9e8 100644 (file)
@@ -482,17 +482,16 @@ static void *
 getobj(void)
 {
     struct empfile *ep = &empfile[cur_type];
-    int need_sentinel = !EF_IS_GAME_STATE(cur_type);
 
     if (!cur_obj) {
-       cur_obj_is_blank = cur_id >= ep->fids - !!need_sentinel;
+       cur_obj_is_blank = cur_id >= ep->fids;
        if (cur_obj_is_blank) {
-           if (ef_ensure_space(cur_type, cur_id + !!need_sentinel, 1))
+           if (ef_ensure_space(cur_type, cur_id, 1))
                cur_obj = ef_ptr(cur_type, cur_id);
            /* FIXME diagnose out of dynamic memory vs. static table full */
            if (!cur_obj)
                gripe("Can't put ID %d into table %s, it holds only 0..%d.",
-                     cur_id, ep->name, ep->fids - !!need_sentinel - 1);
+                     cur_id, ep->name, ep->fids - 1);
        } else
            cur_obj = ef_ptr(cur_type, cur_id);
     }
@@ -962,13 +961,8 @@ static int
 xubody(FILE *fp)
 {
     struct empfile *ep = &empfile[cur_type];
-    int need_sentinel = !EF_IS_GAME_STATE(cur_type);
-    int old_maxid = ep->fids;
     int i, maxid, ch;
 
-    if (old_maxid == 0 && need_sentinel)
-       ef_ensure_space(cur_type, 0, 1);
-
     maxid = 0;
     for (i = 0;; ++i) {
        while ((ch = skipfs(fp)) == '\n')
@@ -983,12 +977,6 @@ xubody(FILE *fp)
        maxid = MAX(maxid, cur_id + 1);
     }
 
-    if (maxid >= old_maxid && need_sentinel) {
-       /* appended a sentinel, strip it off */
-       ep->fids--;
-       ep->cids--;
-    }
-
     if (CANT_HAPPEN(maxid > ep->fids))
        maxid = ep->fids;
     if (maxid < ep->fids) {
index 72b1f81ce336d04ab228201fdd5c29dc2710ad00..2cc640f6ff5a4331212dcf95167da42640b1f3c0 100644 (file)
@@ -86,7 +86,7 @@
     SZ((array)), 0, SZ((array)) - 1, SZ((array)) - 1, -1, NULL, NULL
 
 /* Common configuration table flags */
-#define EFF_CFG (EFF_PRIVATE | EFF_MEM | EFF_STATIC)
+#define EFF_CFG (EFF_PRIVATE | EFF_MEM | EFF_STATIC | EFF_SENTINEL)
 
 struct empfile empfile[] = {
     /*