Commit bc50cdd460ba1485c84f2dfffec4fbb1ca3b4606

Ran Benita 2012-06-05T18:46:24

darray: some changes for convenience - Make darray_free also initialize the array back to an empty state, and stop worrying about it everywhere. - Add darray_mem, to access the underlying memory, which we do manually now using &darray_item(arr, 0). This makes a bit more clear when we actually mean to take the address of a specific item. - Add darray_copy, to make a deep copy of a darray. - Add darray_same, to test whether two darrays have the same underlying memory (e.g. if the struct itself was value copied). This should used where previously two arrays were compared for pointer equality. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/alloc.c b/src/alloc.c
index 45a9114..d0b0618 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -130,10 +130,7 @@ XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into)
 
     *into = *from;
 
-    darray_init(into->map);
-    darray_from_items(into->map,
-                      &darray_item(from->map, 0),
-                      darray_size(from->map));
+    darray_copy(into->map, from->map);
 
     if (from->preserve && !darray_empty(into->map)) {
         into->preserve = calloc(darray_size(into->map),
@@ -161,8 +158,7 @@ bool
 XkbcResizeKeySyms(struct xkb_keymap *keymap, xkb_keycode_t key,
                   unsigned int needed)
 {
-    struct xkb_sym_map *sym_map =
-        &darray_item(keymap->map->key_sym_map, key);
+    struct xkb_sym_map *sym_map = &darray_item(keymap->map->key_sym_map, key);
 
     if (sym_map->size_syms >= needed)
         return true;
@@ -212,8 +208,8 @@ XkbcResizeKeyActions(struct xkb_keymap *keymap, xkb_keycode_t key,
      * new space.
      */
     if (old_ndx != 0)
-        memcpy(&darray_item(keymap->server->acts, new_ndx),
-               &darray_item(keymap->server->acts, old_ndx),
+        memcpy(darray_mem(keymap->server->acts, new_ndx),
+               darray_mem(keymap->server->acts, old_ndx),
                old_num_acts * sizeof(union xkb_action));
 
     return XkbKeyActionsPtr(keymap, key);
diff --git a/src/darray.h b/src/darray.h
index 2547b47..3185193 100644
--- a/src/darray.h
+++ b/src/darray.h
@@ -58,6 +58,10 @@
  *     size_t darray_alloc(darray(T) arr);
  *     bool   darray_empty(darray(T) arr);
  *
+ *     // Access raw memory, starting from the item in offset.
+ *     // Not safe, be careful, etc.
+ *     T*     darray_mem(darray(T) arr, size_t offset);
+ *
  * Insertion (single item):
  *
  *     void   darray_append(darray(T) arr, T item);
@@ -121,10 +125,11 @@
 #define darray(type) struct {type *item; size_t size; size_t alloc;}
 
 #define darray_new() {0,0,0}
-#define darray_lit(c_array) {(c_array), sizeof(c_array) / sizeof(*(c_array)), 0}
 #define darray_init(arr) do {(arr).item=0; (arr).size=0; (arr).alloc=0;} while(0)
-#define darray_free(arr) do {free((arr).item);} while(0)
+#define darray_free(arr) do {free((arr).item); darray_init(arr);} while(0)
 
+/* Only use for immutable darray - e.g. for static const initialzers. */
+#define darray_lit(c_array) {(c_array), sizeof(c_array) / sizeof(*(c_array)), 0}
 
 /*
  * Typedefs for darrays of common types.  These are useful
@@ -163,6 +168,8 @@ typedef darray(unsigned long)  darray_ulong;
 #define darray_alloc(arr)   ((arr).alloc)
 #define darray_empty(arr)   ((arr).size == 0)
 
+#define darray_mem(arr, offset) ((arr).item + (offset))
+#define darray_same(arr1, arr2) ((arr1).item == (arr2).item)
 
 /*** Insertion (single item) ***/
 
@@ -234,6 +241,7 @@ typedef darray(unsigned long)  darray_ulong;
 
 #define darray_from_items(arr, items, count) do {size_t __count = (count); darray_resize(arr, __count); memcpy((arr).item, items, __count*sizeof(*(arr).item));} while(0)
 #define darray_from_c(arr, c_array) darray_from_items(arr, c_array, sizeof(c_array)/sizeof(*(c_array)))
+#define darray_copy(arr_to, arr_from) darray_from_items(arr_to, (arr_from).item, (arr_from).size)
 
 
 /*** String buffer ***/
diff --git a/src/keymap-dump.c b/src/keymap-dump.c
index 4fafde5..7225fea 100644
--- a/src/keymap-dump.c
+++ b/src/keymap-dump.c
@@ -339,12 +339,10 @@ write_keycodes(struct xkb_keymap *keymap, char **buf, size_t *size,
     }
 
 
-    for (i = 0; i < darray_size(keymap->names->key_aliases); i++) {
-        alias = &darray_item(keymap->names->key_aliases, i);
+    darray_foreach(alias, keymap->names->key_aliases)
         write_buf(keymap, buf, size, offset, "\t\talias %6s = %6s;\n",
                   XkbcKeyNameText(alias->alias),
                   XkbcKeyNameText(alias->real));
-    }
 
     write_buf(keymap, buf, size, offset, "\t};\n\n");
     return true;
@@ -354,14 +352,13 @@ static bool
 write_types(struct xkb_keymap *keymap, char **buf, size_t *size,
             size_t *offset)
 {
-    int i, n;
+    int n;
     struct xkb_key_type *type;
 
     write_buf(keymap, buf, size, offset, "\txkb_types {\n\n");
     write_vmods(keymap, buf, size, offset);
 
-    for (i = 0; i < darray_size(keymap->map->types); i++) {
-        type = &darray_item(keymap->map->types, i);
+    darray_foreach(type, keymap->map->types) {
 	write_buf(keymap, buf, size, offset, "\t\ttype \"%s\" {\n",
 	          type->name);
 	write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
@@ -643,9 +640,8 @@ write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
     write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= false;\n");
     write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= false;\n");
 
-    for (i = 0; i < darray_size(keymap->compat->sym_interpret); i++) {
+    darray_foreach(interp, keymap->compat->sym_interpret) {
         char keysym_name[64];
-        interp = &darray_item(keymap->compat->sym_interpret, i);
 
         if (interp->sym == XKB_KEY_NoSymbol)
             sprintf(keysym_name, "Any");
diff --git a/src/misc.c b/src/misc.c
index e500548..07a675d 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -261,11 +261,9 @@ XkbcFindKeycodeByName(struct xkb_keymap *keymap, const char *name,
         return 0;
 
 
-    for (i = 0; i < darray_size(keymap->names->key_aliases); i++) {
-        alias = &darray_item(keymap->names->key_aliases, i);
+    darray_foreach(alias, keymap->names->key_aliases)
         if (strncmp(name, alias->alias, XkbKeyNameLength) == 0)
             return XkbcFindKeycodeByName(keymap, alias->real, false);
-    }
 
     return 0;
 }
diff --git a/src/xkb-priv.h b/src/xkb-priv.h
index 237d43d..6493aea 100644
--- a/src/xkb-priv.h
+++ b/src/xkb-priv.h
@@ -401,7 +401,7 @@ struct xkb_keymap {
      (XkbKeyGroupsWidth(d, k) * XkbKeyNumGroups(d, k)) : \
      1)
 #define XkbKeyActionsPtr(d, k) \
-    (&darray_item((d)->server->acts, darray_item((d)->server->key_acts, k)))
+    (darray_mem((d)->server->acts, darray_item((d)->server->key_acts, k)))
 #define XkbKeyAction(d, k, n) \
     (XkbKeyHasActions(d, k) ? &XkbKeyActionsPtr(d, k)[n] : NULL)
 #define XkbKeyActionEntry(d, k, sl, g) \
diff --git a/src/xkbcomp/keycodes.c b/src/xkbcomp/keycodes.c
index c582781..b9115f4 100644
--- a/src/xkbcomp/keycodes.c
+++ b/src/xkbcomp/keycodes.c
@@ -281,11 +281,8 @@ ClearKeyNamesInfo(KeyNamesInfo * info)
     info->computedMax = info->explicitMax = info->explicitMin = 0;
     info->computedMin = XKB_KEYCODE_MAX;
     darray_free(info->names);
-    darray_init(info->names);
     darray_free(info->files);
-    darray_init(info->files);
     darray_free(info->has_alt_forms);
-    darray_init(info->has_alt_forms);
     if (info->leds)
         ClearIndicatorNameInfo(info->leds, info);
     if (info->aliases)
diff --git a/src/xkbcomp/keytypes.c b/src/xkbcomp/keytypes.c
index e4248f4..9898e1d 100644
--- a/src/xkbcomp/keytypes.c
+++ b/src/xkbcomp/keytypes.c
@@ -127,15 +127,8 @@ InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap,
     {
         info->dflt = from->dflt;
 
-        darray_init(info->dflt.entries);
-        darray_from_items(info->dflt.entries,
-                          &darray_item(from->dflt.entries, 0),
-                          darray_size(from->dflt.entries));
-
-        darray_init(info->dflt.lvlNames);
-        darray_from_items(info->dflt.lvlNames,
-                          &darray_item(from->dflt.lvlNames, 0),
-                          darray_size(from->dflt.lvlNames));
+        darray_copy(info->dflt.entries, from->dflt.entries);
+        darray_copy(info->dflt.lvlNames, from->dflt.lvlNames);
 
         if (from->dflt.preserve)
         {
@@ -163,9 +156,7 @@ static void
 FreeKeyTypeInfo(KeyTypeInfo * type)
 {
     darray_free(type->entries);
-    darray_init(type->entries);
     darray_free(type->lvlNames);
-    darray_init(type->lvlNames);
     if (type->preserve != NULL)
     {
         ClearCommonInfo(&type->preserve->defs);
diff --git a/src/xkbcomp/parseutils.c b/src/xkbcomp/parseutils.c
index 7a6afa7..d5a2528 100644
--- a/src/xkbcomp/parseutils.c
+++ b/src/xkbcomp/parseutils.c
@@ -442,7 +442,7 @@ AppendMultiKeysymList(ExprDef * list, ExprDef * append)
     darray_append(list->value.list.symsMapIndex, nSyms);
     darray_append(list->value.list.symsNumEntries, numEntries);
     darray_append_items(list->value.list.syms,
-                        &darray_item(append->value.list.syms, 0),
+                        darray_mem(append->value.list.syms, 0),
                         numEntries);
 
     darray_resize(append->value.list.syms, 0);
diff --git a/src/xkbcomp/rules.c b/src/xkbcomp/rules.c
index 244701d..52e93ba 100644
--- a/src/xkbcomp/rules.c
+++ b/src/xkbcomp/rules.c
@@ -263,7 +263,7 @@ static void
 match_mapping_line(darray_char *line, struct mapping *mapping)
 {
     char *tok;
-    char *str = &darray_item(*line, 1);
+    char *str = darray_mem(*line, 1);
     unsigned present = 0, layout_ndx_present = 0, variant_ndx_present = 0;
     int i, tmp;
     size_t len;
@@ -372,7 +372,7 @@ static bool
 match_group_line(darray_char *line, struct group *group)
 {
     int i;
-    char *name = strchr(&darray_item(*line, 0), '$');
+    char *name = strchr(darray_mem(*line, 0), '$');
     char *words = strchr(name, ' ');
 
     if (!words)
@@ -421,7 +421,7 @@ match_rule_line(darray_char *line, struct mapping *mapping,
         return false;
     }
 
-    str = &darray_item(*line, 0);
+    str = darray_mem(*line, 0);
 
     for (nread = 0; (tok = strtok_r(str, " ", &strtok_buf)) != NULL; nread++) {
         str = NULL;
@@ -443,7 +443,7 @@ match_rule_line(darray_char *line, struct mapping *mapping,
     }
 
     if (nread < mapping->num_maps) {
-        WARN("Too few words on a line: %s\n", &darray_item(*line, 0));
+        WARN("Too few words on a line: %s\n", darray_mem(*line, 0));
         ACTION("line ignored\n");
         return false;
     }