strmap: Convert to using TCON_WRAP() instead of plain TCON()
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 27 Jan 2016 12:52:12 +0000 (23:52 +1100)
committerDavid Gibson <david@gibson.dropbear.id.au>
Tue, 2 Feb 2016 12:00:06 +0000 (23:00 +1100)
The usual way of construction strmap objects is to use the STRMAP_MEMBERS()
macro which expands to both a raw strmap structure and a tcon type canary.
However, the tcon type canary involves a flexible array member which means
that in standard C99 STRMAP_MEMBERS() must appear only at the end of a
structure definition.  But worse, that structure can then only appear at
the end of any other structure it is included in, which is pretty
inconvenient for the intended purpose of creating type specific strmaps.

gcc extensions allow this to work (somehow), but clang complains loudly
about it.

The tcon module already includes the TCON_WRAP() mechanism, which already
provides this same sort of type-specific definitions in a more general way.
So convert strmap (and its users) to that approach.

This removes STRMAP_MEMBERS() entirely, breaking compatibility.  I'm hoping
strmap is used in few enough places that we can get away with that.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
ccan/cdump/cdump.c
ccan/cdump/cdump.h
ccan/strmap/_info
ccan/strmap/strmap.h
ccan/strmap/test/run-iterate-const.c
ccan/strmap/test/run-order.c
ccan/strmap/test/run-prefix.c
ccan/strmap/test/run.c
tools/ccanlint/ccanlint.c

index f080b968b5732593dbed861d241614878c5191bf..85c818a6df7508db2365efaa952366daa11f8af5 100644 (file)
@@ -213,7 +213,7 @@ static struct cdump_type *get_type(struct cdump_definitions *defs,
                                   enum cdump_type_kind kind,
                                   const char *name)
 {
-       struct cdump_map *m;
+       cdump_map_t *m;
        struct cdump_type *t;
 
        switch (kind) {
@@ -609,7 +609,7 @@ static bool tok_take_enum(struct parse_state *ps)
 
 static bool gather_undefines(const char *name,
                             struct cdump_type *t,
-                            struct cdump_map *undefs)
+                            cdump_map_t *undefs)
 {
        if (!type_defined(t))
                strmap_add(undefs, name, t);
@@ -618,15 +618,15 @@ static bool gather_undefines(const char *name,
 
 static bool remove_from_map(const char *name,
                            struct cdump_type *t,
-                           struct cdump_map *map)
+                           cdump_map_t *map)
 {
        strmap_del(map, name, NULL);
        return true;
 }
 
-static void remove_undefined(struct cdump_map *map)
+static void remove_undefined(cdump_map_t *map)
 {
-       struct cdump_map undefs;
+       cdump_map_t undefs;
 
        /* We can't delete inside iterator, so gather all the undefs
         * then remove them. */
index 312767b41754ae009db21b28cdfdce30be118c23..30822ec50c7f84fab449d7b253615cb304b9f847 100644 (file)
@@ -50,14 +50,12 @@ struct cdump_type {
 };
 
 /* The map of typenames to definitions */
-struct cdump_map {
-       STRMAP_MEMBERS(struct cdump_type *);
-};
+typedef STRMAP(struct cdump_type *) cdump_map_t;
 
 struct cdump_definitions {
-       struct cdump_map enums;
-       struct cdump_map structs;
-       struct cdump_map unions;
+       cdump_map_t enums;
+       cdump_map_t structs;
+       cdump_map_t unions;
 };
 
 /**
index 55319a82db53009bd3ab0b6cdd5830bd73cfd4d7..c128cc27b5c3cbe941cd5e72a4bef2ae2c043f91 100644 (file)
@@ -29,7 +29,7 @@
  * int main(int argc, char *argv[])
  * {
  *     size_t i;
- *     struct { STRMAP_MEMBERS(size_t); } map;
+ *     STRMAP(size_t) map;
  *
  *     strmap_init(&map);
  *     for (i = 1; i < argc; i++)
index 8fabc359acc64e2d4a4603e7097cfe93b3b2be17..0b32e6befc0ca2974ad7304dd967e1c95fae75d3 100644 (file)
@@ -21,7 +21,7 @@ struct strmap {
 };
 
 /**
- * STRMAP_MEMBERS - declare members for a type-specific strmap.
+ * STRMAP - declare a type-specific strmap
  * @type: type for this map's values, or void * for any pointer.
  *
  * You use this to create your own typed strmap for a particular type.
@@ -29,14 +29,11 @@ struct strmap {
  * value!
  *
  * Example:
- *     struct strmap_intp {
- *             STRMAP_MEMBERS(int *);
- *     };
+ *     STRMAP(int *) int_strmap;
+ *     strmap_init(&int_strmap);
  */
-#define STRMAP_MEMBERS(type)                   \
-       struct strmap raw;                      \
-       TCON(type canary)
-
+#define STRMAP(type)                           \
+       TCON_WRAP(struct strmap, type canary)
 
 /**
  * strmap_init - initialize a string map (empty)
@@ -46,11 +43,11 @@ struct strmap {
  * need this.
  *
  * Example:
- *     struct strmap_intp map;
+ *     STRMAP(int *) map;
  *
  *     strmap_init(&map);
  */
-#define strmap_init(map) strmap_init_(&(map)->raw)
+#define strmap_init(map) strmap_init_(tcon_unwrap(map))
 
 static inline void strmap_init_(struct strmap *map)
 {
@@ -65,7 +62,7 @@ static inline void strmap_init_(struct strmap *map)
  *     if (!strmap_empty(&map))
  *             abort();
  */
-#define strmap_empty(map) strmap_empty_(&(map)->raw)
+#define strmap_empty(map) strmap_empty_(tcon_unwrap(map))
 
 static inline bool strmap_empty_(const struct strmap *map)
 {
@@ -85,7 +82,7 @@ static inline bool strmap_empty_(const struct strmap *map)
  *             printf("hello => %i\n", *val);
  */
 #define strmap_get(map, member) \
-       tcon_cast((map), canary, strmap_get_(&(map)->raw, (member)))
+       tcon_cast((map), canary, strmap_get_(tcon_unwrap(map), (member)))
 void *strmap_get_(const struct strmap *map, const char *member);
 
 /**
@@ -106,8 +103,8 @@ void *strmap_get_(const struct strmap *map, const char *member);
  *     if (!strmap_add(&map, "goodbye", val))
  *             printf("goodbye was already in the map\n");
  */
-#define strmap_add(map, member, value)                         \
-       strmap_add_(&tcon_check((map), canary, (value))->raw,   \
+#define strmap_add(map, member, value)                                 \
+       strmap_add_(tcon_unwrap(tcon_check((map), canary, (value))),    \
                    (member), (void *)(value))
 
 bool strmap_add_(struct strmap *map, const char *member, const void *value);
@@ -130,7 +127,7 @@ bool strmap_add_(struct strmap *map, const char *member, const void *value);
  *             printf("goodbye was not in the map?\n");
  */
 #define strmap_del(map, member, valuep)                                        \
-       strmap_del_(&tcon_check_ptr((map), canary, valuep)->raw,        \
+       strmap_del_(tcon_unwrap(tcon_check_ptr((map), canary, valuep)), \
                    (member), (void **)valuep)
 char *strmap_del_(struct strmap *map, const char *member, void **valuep);
 
@@ -143,7 +140,7 @@ char *strmap_del_(struct strmap *map, const char *member, void **valuep);
  * Example:
  *     strmap_clear(&map);
  */
-#define strmap_clear(map) strmap_clear_(&(map)->raw)
+#define strmap_clear(map) strmap_clear_(tcon_unwrap(map))
 
 void strmap_clear_(struct strmap *map);
 
@@ -160,9 +157,7 @@ void strmap_clear_(struct strmap *map);
  * You should not alter the map within the @handle function!
  *
  * Example:
- *     struct strmap_intp {
- *             STRMAP_MEMBERS(int *);
- *     };
+ *     typedef STRMAP(int *) strmap_intp;
  *     static bool dump_some(const char *member, int *value, int *num)
  *     {
  *             // Only dump out num nodes.
@@ -172,7 +167,7 @@ void strmap_clear_(struct strmap *map);
  *             return true;
  *     }
  *
- *     static void dump_map(const struct strmap_intp *map)
+ *     static void dump_map(const strmap_intp *map)
  *     {
  *             int max = 100;
  *             strmap_iterate(map, dump_some, &max);
@@ -181,7 +176,7 @@ void strmap_clear_(struct strmap *map);
  *     }
  */
 #define strmap_iterate(map, handle, arg)                               \
-       strmap_iterate_(&(map)->raw,                                    \
+       strmap_iterate_(tcon_unwrap(map),                               \
                        typesafe_cb_cast(bool (*)(const char *,         \
                                                  void *, void *),      \
                                         bool (*)(const char *,         \
@@ -202,7 +197,7 @@ void strmap_iterate_(const struct strmap *map,
  * strmap_empty() on the returned pointer.
  *
  * Example:
- *     static void dump_prefix(const struct strmap_intp *map,
+ *     static void dump_prefix(const strmap_intp *map,
  *                             const char *prefix)
  *     {
  *             int max = 100;
@@ -214,10 +209,10 @@ void strmap_iterate_(const struct strmap *map,
  */
 #if HAVE_TYPEOF
 #define strmap_prefix(map, prefix) \
-       ((const __typeof__(map))strmap_prefix_(&(map)->raw, (prefix)))
+       ((const __typeof__(map))strmap_prefix_(tcon_unwrap(map), (prefix)))
 #else
 #define strmap_prefix(map, prefix) \
-       ((const void *)strmap_prefix_(&(map)->raw, (prefix)))
+       ((const void *)strmap_prefix_(tcon_unwrap(map), (prefix)))
 #endif
 
 const struct strmap *strmap_prefix_(const struct strmap *map,
index 07c814a3df53fba115d475c635baf0d55b7774a8..63bea95236af32ba1372c460151243bf3f5d7d66 100644 (file)
@@ -14,9 +14,7 @@ static bool find_string(const char *str, char *member, const char *cmp)
 
 int main(void)
 {
-       struct strmap_charp {
-               STRMAP_MEMBERS(char *);
-       } map;
+       STRMAP(char *) map;
 
        plan_tests(3);
 
index 68062eab0f9583a8aa2cd7bea26735ef14809214..b541666d81209820f62d37418476ee51a1f22a88 100644 (file)
@@ -33,9 +33,7 @@ static bool dump(const char *member, char *value, bool *ok)
 
 int main(void)
 {
-       struct strmap_charp {
-               STRMAP_MEMBERS(char *);
-       } map;
+       STRMAP(char *) map;
        unsigned int i;
        char *str[NUM];
        bool dump_ok;
index 9c5156e6e57dd8c7ba09d85a1ca43138341497b8..d88eb55655c2bfe3737ca3fc510f8d3b43658bc9 100644 (file)
@@ -24,11 +24,9 @@ static bool find_empty(const char *index, char *value, char *empty)
 
 int main(void)
 {
-       struct map {
-               STRMAP_MEMBERS(char *);
-       };
-       struct map map;
-       const struct map *sub;
+       typedef STRMAP(char *) map_t;
+       map_t map;
+       const map_t *sub;
        unsigned int i;
        char *str[NUM], *empty;
 
@@ -56,9 +54,9 @@ int main(void)
 
        /* Everything */
        sub = strmap_prefix(&map, "0");
-       ok1(sub->raw.u.n == map.raw.u.n);
+       ok1(tcon_unwrap(sub)->u.n == tcon_unwrap(&map)->u.n);
        sub = strmap_prefix(&map, "");
-       ok1(sub->raw.u.n == map.raw.u.n);
+       ok1(tcon_unwrap(sub)->u.n == tcon_unwrap(&map)->u.n);
 
        /* Single. */
        sub = strmap_prefix(&map, "00000000");
index aaa8618125c14d228a0a08da695aff8bd4c7e708..f64ddc5e57918b3dc12ba5fca849733df7d59eec 100644 (file)
@@ -4,9 +4,7 @@
 
 int main(void)
 {
-       struct strmap_charp {
-               STRMAP_MEMBERS(char *);
-       } map;
+       STRMAP(char *) map;
        const char str[] = "hello";
        const char val[] = "there";
        const char none[] = "";
index 158195cbdef04adf4c6ca1323ccc68c3862b1f1b..1e5cf2759c0236a2b329c0a5f00e4ebe35584649 100644 (file)
 #include <ccan/tal/path/path.h>
 #include <ccan/strmap/strmap.h>
 
-struct ccanlint_map {
-       STRMAP_MEMBERS(struct ccanlint *);
-};
+typedef STRMAP(struct ccanlint *) ccanlint_map_t;
 
 int verbose = 0;
-static struct ccanlint_map tests;
+static ccanlint_map_t tests;
 bool safe_mode = false;
 bool keep_results = false;
 bool non_ccan_deps = false;
@@ -273,7 +271,7 @@ static bool init_deps(const char *member, struct ccanlint *c, void *unused)
 }
 
 static bool check_names(const char *member, struct ccanlint *c,
-                       struct ccanlint_map *names)
+                       ccanlint_map_t *names)
 {
        if (!strmap_add(names, c->name, c))
                err(1, "Duplicate name %s", c->name);
@@ -282,7 +280,7 @@ static bool check_names(const char *member, struct ccanlint *c,
 
 static void init_tests(void)
 {
-       struct ccanlint_map names;
+       ccanlint_map_t names;
        struct ccanlint **table;
        size_t i, num;