Skip to content

Commit

Permalink
qapi: Add QAPI_LIST_PREPEND() macro
Browse files Browse the repository at this point in the history
block.c has a useful macro QAPI_LIST_ADD() for inserting at the front
of any QAPI-generated list; move it from block.c to qapi/util.h so
more places can use it, including one earlier place in block.c, and
rename it to something more obvious (since we also have a lot of
places that append, rather than prepend, to a list).

There are many more places in the codebase that can benefit from using
the macro, but converting them will be left to later patches.

In theory, all QAPI list types are child classes of GenericList; but
in practice, that relationship is not explicitly spelled out in the C
type declarations (rather, it is something that happens implicitly due
to C compatible layouts), and the macro does not actually depend on
the GenericList type.  We considered moving GenericList from visitor.h
into util.h to group related code; however, such a move would be
awkward if we do not also move GenericAlternate.  Unfortunately,
moving GenericAlternate would introduce its own problems of
declaration circularity (qapi-builtin-types.h needs a complete
definition of QEnumLookup from util.h, but GenericAlternate needs a
complete definition of QType from qapi-builtin-types.h).

Suggested-by: Vladimir Sementsov-Ogievskiy <[email protected]>
Signed-off-by: Eric Blake <[email protected]>
Reviewed-by: Vladimir Sementsov-Ogievskiy <[email protected]>
Reviewed-by: Markus Armbruster <[email protected]>
Message-Id: <[email protected]>
[eblake: s/ADD/PREPEND/ per suggestion by Markus]
  • Loading branch information
ebblake committed Oct 30, 2020
1 parent 159f844 commit 9812e71
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
22 changes: 6 additions & 16 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -5220,7 +5220,7 @@ BlockDriverState *bdrv_find_node(const char *node_name)
BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
Error **errp)
{
BlockDeviceInfoList *list, *entry;
BlockDeviceInfoList *list;
BlockDriverState *bs;

list = NULL;
Expand All @@ -5230,22 +5230,12 @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
qapi_free_BlockDeviceInfoList(list);
return NULL;
}
entry = g_malloc0(sizeof(*entry));
entry->value = info;
entry->next = list;
list = entry;
QAPI_LIST_PREPEND(list, info);
}

return list;
}

#define QAPI_LIST_ADD(list, element) do { \
typeof(list) _tmp = g_malloc(sizeof(*(list))); \
_tmp->value = (element); \
_tmp->next = (list); \
(list) = _tmp; \
} while (0)

typedef struct XDbgBlockGraphConstructor {
XDbgBlockGraph *graph;
GHashTable *graph_nodes;
Expand Down Expand Up @@ -5300,7 +5290,7 @@ static void xdbg_graph_add_node(XDbgBlockGraphConstructor *gr, void *node,
n->type = type;
n->name = g_strdup(name);

QAPI_LIST_ADD(gr->graph->nodes, n);
QAPI_LIST_PREPEND(gr->graph->nodes, n);
}

static void xdbg_graph_add_edge(XDbgBlockGraphConstructor *gr, void *parent,
Expand All @@ -5319,14 +5309,14 @@ static void xdbg_graph_add_edge(XDbgBlockGraphConstructor *gr, void *parent,
uint64_t flag = bdrv_qapi_perm_to_blk_perm(qapi_perm);

if (flag & child->perm) {
QAPI_LIST_ADD(edge->perm, qapi_perm);
QAPI_LIST_PREPEND(edge->perm, qapi_perm);
}
if (flag & child->shared_perm) {
QAPI_LIST_ADD(edge->shared_perm, qapi_perm);
QAPI_LIST_PREPEND(edge->shared_perm, qapi_perm);
}
}

QAPI_LIST_ADD(gr->graph->edges, edge);
QAPI_LIST_PREPEND(gr->graph->edges, edge);
}


Expand Down
13 changes: 13 additions & 0 deletions include/qapi/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,17 @@ int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,

int parse_qapi_name(const char *name, bool complete);

/*
* For any GenericList @list, insert @element at the front.
*
* Note that this macro evaluates @element exactly once, so it is safe
* to have side-effects with that argument.
*/
#define QAPI_LIST_PREPEND(list, element) do { \
typeof(list) _tmp = g_malloc(sizeof(*(list))); \
_tmp->value = (element); \
_tmp->next = (list); \
(list) = _tmp; \
} while (0)

#endif

0 comments on commit 9812e71

Please sign in to comment.