summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2016-05-12 15:04:37 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2016-06-02 14:38:14 +0200
commit02a414b4a532ab989cec4df22c627d3b786fdfb5 (patch)
tree1067d35a23a8526aac83a80f918bc88c17686a8e
parent57c55e70cfc9ee61f13bbd60598e1cd30020ee30 (diff)
downloadlvm2-02a414b4a532ab989cec4df22c627d3b786fdfb5.tar.gz
libdm: report: add dm_report_set_selection
-rw-r--r--libdm/.exported_symbols.DM_1_02_1261
-rw-r--r--libdm/libdevmapper.h2
-rw-r--r--libdm/libdm-report.c124
3 files changed, 96 insertions, 31 deletions
diff --git a/libdm/.exported_symbols.DM_1_02_126 b/libdm/.exported_symbols.DM_1_02_126
index 6e365d52c..c3239739b 100644
--- a/libdm/.exported_symbols.DM_1_02_126
+++ b/libdm/.exported_symbols.DM_1_02_126
@@ -2,3 +2,4 @@ dm_report_group_create
dm_report_group_push
dm_report_group_pop
dm_report_group_destroy
+dm_report_set_selection
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index cb3ba2ef1..a6ba1bc88 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -2675,6 +2675,8 @@ void dm_report_free(struct dm_report *rh);
int dm_report_set_output_field_name_prefix(struct dm_report *rh,
const char *report_prefix);
+int dm_report_set_selection(struct dm_report *rh, const char *selection);
+
/*
* Report functions are provided for simple data types.
* They take care of allocating copies of the data.
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 8a106ae3d..ddd19d37e 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -30,6 +30,7 @@
struct selection {
struct dm_pool *mem;
struct selection_node *selection_root;
+ int add_new_fields;
};
struct report_group_item;
@@ -1900,7 +1901,7 @@ static int _check_selection(struct dm_report *rh, struct selection_node *sn,
static int _check_report_selection(struct dm_report *rh, struct dm_list *fields)
{
- if (!rh->selection)
+ if (!rh->selection || !rh->selection->selection_root)
return 1;
return _check_selection(rh, rh->selection->selection_root, fields);
@@ -3422,9 +3423,17 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
/* The field is neither used in display options nor sort keys. */
if (!found) {
- if (!(found = _add_field(rh, field_num, implicit, FLD_HIDDEN)))
+ if (rh->selection->add_new_fields) {
+ if (!(found = _add_field(rh, field_num, implicit, FLD_HIDDEN)))
+ return NULL;
+ rh->report_types |= fields[field_num].type;
+ } else {
+ log_error("Unable to create selection with field \'%s\' "
+ "which is not included in current report.",
+ implicit ? _implicit_report_fields[field_num].id
+ : rh->fields[field_num].id);
return NULL;
- rh->report_types |= fields[field_num].type;
+ }
}
field_id = fields[found->field_num].id;
@@ -3962,6 +3971,86 @@ error:
return NULL;
}
+static int _alloc_rh_selection(struct dm_report *rh)
+{
+ if (!(rh->selection = dm_pool_zalloc(rh->mem, sizeof(struct selection))) ||
+ !(rh->selection->mem = dm_pool_create("report selection", 10 * 1024))) {
+ log_error("Failed to allocate report selection structure.");
+ if (rh->selection)
+ dm_pool_free(rh->mem, rh->selection);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int _report_set_selection(struct dm_report *rh, const char *selection, int add_new_fields)
+{
+ struct selection_node *root = NULL;
+ const char *fin, *next;
+
+ if (rh->selection) {
+ if (rh->selection->selection_root)
+ /* Trash any previous selection. */
+ dm_pool_free(rh->selection->mem, rh->selection->selection_root);
+ rh->selection->selection_root = NULL;
+ } else {
+ if (!_alloc_rh_selection(rh))
+ goto_bad;
+ }
+
+ if (!selection)
+ return 1;
+
+ rh->selection->add_new_fields = add_new_fields;
+
+ if (!(root = _alloc_selection_node(rh->selection->mem, SEL_OR)))
+ return 0;
+
+ if (!_parse_or_ex(rh, selection, &fin, root))
+ goto_bad;
+
+ next = _skip_space(fin);
+ if (*next) {
+ log_error("Expecting logical operator");
+ log_error(_sel_syntax_error_at_msg, next);
+ log_error(_sel_help_ref_msg);
+ goto bad;
+ }
+
+ rh->selection->selection_root = root;
+ return 1;
+bad:
+ dm_pool_free(rh->selection->mem, root);
+ return 0;
+}
+
+static void _reset_field_props(struct dm_report *rh)
+{
+ struct field_properties *fp;
+ dm_list_iterate_items(fp, &rh->field_props)
+ fp->width = fp->initial_width;
+}
+
+int dm_report_set_selection(struct dm_report *rh, const char *selection)
+{
+ struct row *row;
+
+ if (!_report_set_selection(rh, selection, 0))
+ return_0;
+
+ _reset_field_props(rh);
+
+ dm_list_iterate_items(row, &rh->rows) {
+ row->selected = _check_report_selection(rh, &row->fields);
+ if (row->field_sel_status)
+ _implicit_report_fields[row->field_sel_status->props->field_num].report_fn(rh,
+ rh->mem, row->field_sel_status, row, rh->private);
+ }
+
+ return 1;
+}
+
struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
const struct dm_report_object_type *types,
const struct dm_report_field_type *fields,
@@ -3974,8 +4063,6 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
void *private_data)
{
struct dm_report *rh;
- struct selection_node *root = NULL;
- const char *fin, *next;
_implicit_report_fields = _implicit_special_report_fields_with_selection;
@@ -4005,29 +4092,11 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types,
return rh;
}
- if (!(rh->selection = dm_pool_zalloc(rh->mem, sizeof(struct selection))) ||
- !(rh->selection->mem = dm_pool_create("report selection", 10 * 1024))) {
- log_error("Failed to allocate report selection structure.");
- goto bad;
- }
-
- if (!(root = _alloc_selection_node(rh->selection->mem, SEL_OR)))
- goto_bad;
-
- if (!_parse_or_ex(rh, selection, &fin, root))
+ if (!_report_set_selection(rh, selection, 1))
goto_bad;
- next = _skip_space(fin);
- if (*next) {
- log_error("Expecting logical operator");
- log_error(_sel_syntax_error_at_msg, next);
- log_error(_sel_help_ref_msg);
- goto bad;
- }
-
_dm_report_init_update_types(rh, report_types);
- rh->selection->selection_root = root;
return rh;
bad:
dm_report_free(rh);
@@ -4351,13 +4420,6 @@ bad:
return 0;
}
-static void _reset_field_props(struct dm_report *rh)
-{
- struct field_properties *fp;
- dm_list_iterate_items(fp, &rh->field_props)
- fp->width = fp->initial_width;
-}
-
static void _destroy_rows(struct dm_report *rh)
{
/*