Wait until category is complete before adding items to bins
authorCarl Worth <cworth@cworth.org>
Tue, 17 Apr 2007 17:57:51 +0000 (10:57 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 17 Apr 2007 17:57:51 +0000 (10:57 -0700)
Otherwise the category will keep reallocing the items array which
means the pointers to each item won't be stable so we must not
save them into bins.

mnemon.c

index 101ace80edb9f29d49232261de5db331931a847a..039f0ca0115325a6163018d47f1f1b68e53529a2 100644 (file)
--- a/mnemon.c
+++ b/mnemon.c
@@ -361,23 +361,6 @@ mnemon_get_bin (mnemon_t   *mnemon,
     return bin;
 }
 
-static void
-mnemon_add_item (mnemon_t      *mnemon,
-                category_t     *category,
-                int             count,
-                const char     *challenge,
-                const char     *response)
-{
-    item_t *item;
-    bin_t *bin;
-
-    item = category_add_item (category, count, challenge, response);
-
-    bin = mnemon_get_bin (mnemon, count);
-
-    bin_add_item (bin, item);
-}
-
 static void
 chomp (char *s)
 {
@@ -399,6 +382,7 @@ mnemon_load_category (mnemon_t              *mnemon,
     int line_count = 0;
     char *path;
     category_t *category;
+    int i;
 
     path = xmalloc (strlen (mnemon->dir_name) + 1 + strlen (name) + 1);
     sprintf (path, "%s/%s", mnemon->dir_name, name);
@@ -448,7 +432,7 @@ mnemon_load_category (mnemon_t              *mnemon,
        chomp (line);
        response = line;
 
-       mnemon_add_item (mnemon, category, count, challenge, response);
+       category_add_item (category, count, challenge, response);
 
        free (challenge);
     }
@@ -457,6 +441,20 @@ mnemon_load_category (mnemon_t             *mnemon,
     free (line);
     fclose (file);
     free (path);
+
+    /* Resize category items to fit exactly. */
+    category->items_size = category->num_items;
+    category->items = xrealloc (category->items, category->items_size * sizeof (item_t));
+
+    /* Now that the category is completely loaded, with stable
+     * pointers to every item, we can add each item to its appropriate
+     * bin. */
+    for (i = 0; i < category->num_items; i++) {
+       item_t *item = &category->items[i];
+       bin_t *bin = mnemon_get_bin (mnemon, item->count);
+
+       bin_add_item (bin, item);
+    }
 }
 
 static void