diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 3fb69cb66..183ef1526 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,6 @@ Version 1.02.94 - =================================== + Add dm_report_object_is_selected for generalized interface for report/select. Version 1.02.93 - 21st January 2015 =================================== diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index b164b5162..309e63fd1 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -1761,7 +1761,17 @@ struct dm_report *dm_report_init_with_selection(uint32_t *report_types, const char *selection, const struct dm_report_reserved_value reserved_values[], void *private_data); +/* + * Report an object, pass it through the selection criteria if they + * are present and display the result on output if it passes the criteria. + */ int dm_report_object(struct dm_report *rh, void *object); +/* + * The same as dm_report_object, but display the result on output only if + * 'do_output' arg is set. Also, save the result of selection in 'selected' + * arg if it's not NULL (either 1 if the object passes, otherwise 0). + */ +int dm_report_object_is_selected(struct dm_report *rh, void *object, int do_output, int *selected); /* * Compact report output so that if field value is empty for all rows in diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c index 2612f74d0..6f528f1a4 100644 --- a/libdm/libdm-report.c +++ b/libdm/libdm-report.c @@ -1575,7 +1575,7 @@ static int _check_report_selection(struct dm_report *rh, struct dm_list *fields) return _check_selection(rh, rh->selection->selection_root, fields); } -int dm_report_object(struct dm_report *rh, void *object) +static int _do_report_object(struct dm_report *rh, void *object, int do_output, int *selected) { const struct dm_report_field_type *fields; struct field_properties *fp; @@ -1586,7 +1586,13 @@ int dm_report_object(struct dm_report *rh, void *object) int r = 0; if (!rh) { - log_error(INTERNAL_ERROR "dm_report handler is NULL."); + log_error(INTERNAL_ERROR "_do_report_object: dm_report handler is NULL."); + return 0; + } + + if (!do_output && !selected) { + log_error(INTERNAL_ERROR "_do_report_object: output not requested and " + "selected output variable is NULL too."); return 0; } @@ -1594,7 +1600,7 @@ int dm_report_object(struct dm_report *rh, void *object) return 1; if (!(row = dm_pool_zalloc(rh->mem, sizeof(*row)))) { - log_error("dm_report_object: struct row allocation failed"); + log_error("_do_report_object: struct row allocation failed"); return 0; } @@ -1604,7 +1610,7 @@ int dm_report_object(struct dm_report *rh, void *object) !(row->sort_fields = dm_pool_zalloc(rh->mem, sizeof(struct dm_report_field *) * rh->keys_count))) { - log_error("dm_report_object: " + log_error("_do_report_object: " "row sort value structure allocation failed"); goto out; } @@ -1615,7 +1621,7 @@ int dm_report_object(struct dm_report *rh, void *object) /* For each field to be displayed, call its report_fn */ dm_list_iterate_items(fp, &rh->field_props) { if (!(field = dm_pool_zalloc(rh->mem, sizeof(*field)))) { - log_error("dm_report_object: " + log_error("_do_report_object: " "struct dm_report_field allocation failed"); goto out; } @@ -1632,7 +1638,7 @@ int dm_report_object(struct dm_report *rh, void *object) data = fp->implicit ? _report_get_implicit_field_data(rh, fp, row) : _report_get_field_data(rh, fp, object); if (!data) { - log_error("dm_report_object: " + log_error("_do_report_object: " "no data assigned to field %s", fields[fp->field_num].id); goto out; @@ -1641,7 +1647,7 @@ int dm_report_object(struct dm_report *rh, void *object) if (!fields[fp->field_num].report_fn(rh, rh->mem, field, data, rh->private)) { - log_error("dm_report_object: " + log_error("_do_report_object: " "report function failed for field %s", fields[fp->field_num].id); goto out; @@ -1650,11 +1656,14 @@ int dm_report_object(struct dm_report *rh, void *object) dm_list_add(&row->fields, &field->list); } + r = 1; + if (!_check_report_selection(rh, &row->fields)) { - if (!field_sel_status) { - r = 1; + row->selected = 0; + + if (!field_sel_status) goto out; - } + /* * If field with id "selected" is reported, * report the row although it does not pass @@ -1662,7 +1671,6 @@ int dm_report_object(struct dm_report *rh, void *object) * The "selected" field reports the result * of the selection. */ - row->selected = 0; _implicit_report_fields[field_sel_status->props->field_num].report_fn(rh, rh->mem, field_sel_status, row, rh->private); /* @@ -1670,12 +1678,13 @@ int dm_report_object(struct dm_report *rh, void *object) * because it is part of the sort field list, * skip the display of the row as usual. */ - if (field_sel_status->props->flags & FLD_HIDDEN) { - r = 1; + if (field_sel_status->props->flags & FLD_HIDDEN) goto out; - } } + if (!do_output) + goto out; + dm_list_add(&rh->rows, &row->list); dm_list_iterate_items(field, &row->fields) { @@ -1691,10 +1700,10 @@ int dm_report_object(struct dm_report *rh, void *object) if (!(rh->flags & DM_REPORT_OUTPUT_BUFFERED)) return dm_report_output(rh); - - r = 1; out: - if (!r) + if (selected) + *selected = row->selected; + if (!do_output || !r) dm_pool_free(rh->mem, row); return r; } @@ -1751,6 +1760,16 @@ int dm_report_compact_fields(struct dm_report *rh) return 1; } +int dm_report_object(struct dm_report *rh, void *object) +{ + return _do_report_object(rh, object, 1, NULL); +} + +int dm_report_object_is_selected(struct dm_report *rh, void *object, int do_output, int *selected) +{ + return _do_report_object(rh, object, do_output, selected); +} + /* * Selection parsing */