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.
This commit is contained in:
@@ -654,16 +654,24 @@ nmc_free_output_field_values (NmcOutputField fields_array[])
|
|||||||
|
|
||||||
#define PRINT_DATA_COL_PARENT_NIL (G_MAXUINT)
|
#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;
|
const NMMetaSelectionItem *selection_item;
|
||||||
guint parent_idx;
|
|
||||||
guint self_idx;
|
guint self_idx;
|
||||||
bool is_leaf;
|
bool is_leaf;
|
||||||
} PrintDataCol;
|
} PrintDataCol;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_output_selection_append (GArray *cols,
|
_output_selection_append (GArray *cols,
|
||||||
const char *fields_prefix,
|
|
||||||
guint parent_idx,
|
guint parent_idx,
|
||||||
const NMMetaSelectionItem *selection_item,
|
const NMMetaSelectionItem *selection_item,
|
||||||
GPtrArray *gfree_keeper,
|
GPtrArray *gfree_keeper,
|
||||||
@@ -681,7 +689,7 @@ _output_selection_append (GArray *cols,
|
|||||||
{
|
{
|
||||||
PrintDataCol col = {
|
PrintDataCol col = {
|
||||||
.selection_item = selection_item,
|
.selection_item = selection_item,
|
||||||
.parent_idx = parent_idx,
|
._parent_idx = parent_idx,
|
||||||
.self_idx = col_idx,
|
.self_idx = col_idx,
|
||||||
.is_leaf = TRUE,
|
.is_leaf = TRUE,
|
||||||
};
|
};
|
||||||
@@ -727,8 +735,11 @@ _output_selection_append (GArray *cols,
|
|||||||
|
|
||||||
for (i = 0; i < selection->num; i++) {
|
for (i = 0; i < selection->num; i++) {
|
||||||
si = &selection->items[i];
|
si = &selection->items[i];
|
||||||
if (!_output_selection_append (cols, si->self_selection, col_idx,
|
if (!_output_selection_append (cols,
|
||||||
si, gfree_keeper, error))
|
col_idx,
|
||||||
|
si,
|
||||||
|
gfree_keeper,
|
||||||
|
error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,6 +752,26 @@ _output_selection_append (GArray *cols,
|
|||||||
return TRUE;
|
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++) {
|
for (i = 0; i < selection->num; i++) {
|
||||||
const NMMetaSelectionItem *si = &selection->items[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))
|
si, gfree_keeper, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_output_selection_complete (cols);
|
||||||
|
|
||||||
*out_cols = g_steal_pointer (&cols);
|
*out_cols = g_steal_pointer (&cols);
|
||||||
*out_gfree_keeper = g_steal_pointer (&gfree_keeper);
|
*out_gfree_keeper = g_steal_pointer (&gfree_keeper);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -1006,12 +1039,12 @@ _print_fill (const NmcConfig *nmc_config,
|
|||||||
|
|
||||||
header_cell->title = nm_meta_abstract_info_get_name (info, TRUE);
|
header_cell->title = nm_meta_abstract_info_get_name (info, TRUE);
|
||||||
if ( nmc_config->multiline_output
|
if ( nmc_config->multiline_output
|
||||||
&& col->parent_idx != PRINT_DATA_COL_PARENT_NIL
|
&& col->parent_col
|
||||||
&& NM_IN_SET (info->meta_type,
|
&& NM_IN_SET (info->meta_type,
|
||||||
&nm_meta_type_property_info,
|
&nm_meta_type_property_info,
|
||||||
&nmc_meta_type_generic_info)) {
|
&nmc_meta_type_generic_info)) {
|
||||||
header_cell->title = g_strdup_printf ("%s.%s",
|
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);
|
||||||
header_cell->title_to_free = TRUE;
|
header_cell->title_to_free = TRUE;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user