summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-05-02 16:36:28 +0200
committerThomas Haller <thaller@redhat.com>2018-07-25 17:08:37 +0200
commit66e5f133079a75455fe5f71ca650e83fe739da8c (patch)
tree06b872126cce025a1c52eccc9d1a43138d99bf90
parentac07cbb98bd6db6d79d1578a3a97d50cf454dd68 (diff)
downloadNetworkManager-66e5f133079a75455fe5f71ca650e83fe739da8c.tar.gz
cli: simplify tracking of parent column in PrintDataCol structure
PrintDataCol contains a reference to the parent structure, for which it was created. Previously, that was expressed via the "parent_idx" field, which is an index into the list of all PrintDataCol entries. That is inconvenient. Resolve the index to the actual pointer. Note that during _output_selection_append() we still need to use the index instead of resolving the pointer right away. That is because _output_selection_append() grows the GArray into which the parent_idx pointers to. So, obtaining the real pointer at that point would result in using a dangling pointer later on. Introduce a new step _output_selection_complete() which converts the index into the actual pointer.
-rw-r--r--clients/cli/utils.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/clients/cli/utils.c b/clients/cli/utils.c
index 9b7b4c4b33..59e8fcc4bf 100644
--- a/clients/cli/utils.c
+++ b/clients/cli/utils.c
@@ -654,16 +654,24 @@ nmc_free_output_field_values (NmcOutputField fields_array[])
#define PRINT_DATA_COL_PARENT_NIL (G_MAXUINT)
-typedef struct {
+typedef struct _PrintDataCol {
+ union {
+ const struct _PrintDataCol *parent_col;
+
+ /* while constructing the list of columns in _output_selection_append(), we keep track
+ * of the parent by index. The reason is, that at that point our columns are still
+ * tracked in a GArray which is growing (hence, the pointers are changing).
+ * Later, _output_selection_complete() converts the index into the actual pointer.
+ */
+ guint _parent_idx;
+ };
const NMMetaSelectionItem *selection_item;
- guint parent_idx;
guint self_idx;
bool is_leaf;
} PrintDataCol;
static gboolean
_output_selection_append (GArray *cols,
- const char *fields_prefix,
guint parent_idx,
const NMMetaSelectionItem *selection_item,
GPtrArray *gfree_keeper,
@@ -681,7 +689,7 @@ _output_selection_append (GArray *cols,
{
PrintDataCol col = {
.selection_item = selection_item,
- .parent_idx = parent_idx,
+ ._parent_idx = parent_idx,
.self_idx = col_idx,
.is_leaf = TRUE,
};
@@ -727,8 +735,11 @@ _output_selection_append (GArray *cols,
for (i = 0; i < selection->num; i++) {
si = &selection->items[i];
- if (!_output_selection_append (cols, si->self_selection, col_idx,
- si, gfree_keeper, error))
+ if (!_output_selection_append (cols,
+ col_idx,
+ si,
+ gfree_keeper,
+ error))
return FALSE;
}
@@ -741,6 +752,26 @@ _output_selection_append (GArray *cols,
return TRUE;
}
+static void
+_output_selection_complete (GArray *cols)
+{
+ guint i;
+
+ nm_assert (cols);
+ nm_assert (g_array_get_element_size (cols) == sizeof (PrintDataCol));
+
+ for (i = 0; i < cols->len; i++) {
+ PrintDataCol *col = &g_array_index (cols, PrintDataCol, i);
+
+ if (col->_parent_idx == PRINT_DATA_COL_PARENT_NIL)
+ col->parent_col = NULL;
+ else {
+ nm_assert (col->_parent_idx < i);
+ col->parent_col = &g_array_index (cols, PrintDataCol, col->_parent_idx);
+ }
+ }
+}
+
/*****************************************************************************/
/**
@@ -789,11 +820,13 @@ _output_selection_parse (const NMMetaAbstractInfo *const*fields,
for (i = 0; i < selection->num; i++) {
const NMMetaSelectionItem *si = &selection->items[i];
- if (!_output_selection_append (cols, NULL, PRINT_DATA_COL_PARENT_NIL,
+ if (!_output_selection_append (cols, PRINT_DATA_COL_PARENT_NIL,
si, gfree_keeper, error))
return FALSE;
}
+ _output_selection_complete (cols);
+
*out_cols = g_steal_pointer (&cols);
*out_gfree_keeper = g_steal_pointer (&gfree_keeper);
return TRUE;
@@ -1006,12 +1039,12 @@ _print_fill (const NmcConfig *nmc_config,
header_cell->title = nm_meta_abstract_info_get_name (info, TRUE);
if ( nmc_config->multiline_output
- && col->parent_idx != PRINT_DATA_COL_PARENT_NIL
+ && col->parent_col
&& NM_IN_SET (info->meta_type,
&nm_meta_type_property_info,
&nmc_meta_type_generic_info)) {
header_cell->title = g_strdup_printf ("%s.%s",
- nm_meta_abstract_info_get_name (cols[col->parent_idx].selection_item->info, FALSE),
+ nm_meta_abstract_info_get_name (col->parent_col->selection_item->info, FALSE),
header_cell->title);
header_cell->title_to_free = TRUE;
}