diff options
author | Thomas Haller <thaller@redhat.com> | 2018-05-02 16:36:28 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-07-25 17:08:37 +0200 |
commit | 66e5f133079a75455fe5f71ca650e83fe739da8c (patch) | |
tree | 06b872126cce025a1c52eccc9d1a43138d99bf90 | |
parent | ac07cbb98bd6db6d79d1578a3a97d50cf454dd68 (diff) | |
download | NetworkManager-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.c | 51 |
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; } |