Gitweb:
http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0956fd230fea55...
Commit: 0956fd230fea550707acb2889223438996102de4
Parent: da545ce3b471e76b3ebcfcb5528118d8dd9264df
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 4 11:21:38 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 4 15:50:50 2014 +0200
report: adapt selection code to recognize per-field reserved values
In contrast to per-type reserved values that are applied for all fields
of that type, per-field reserved values are only applied for concrete
field only.
Also add 'struct dm_report_field_reserved_value' to libdm for per-field
reserved value definition. This is defined by field number (an index
in the 'fields' array which is given for the dm_report_init_with_selection
function during report initialization) and the value to use for any
of the specified reserved names.
---
libdm/libdevmapper.h | 27 ++++++++++++
libdm/libdm-report.c | 112 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 101 insertions(+), 38 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ad504da..dc3da78 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1633,6 +1633,7 @@ struct dm_report_field;
#define DM_REPORT_FIELD_ALIGN_LEFT 0x00000001
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
#define DM_REPORT_FIELD_TYPE_MASK 0x00000FF0
+#define DM_REPORT_FIELD_TYPE_NONE 0x00000000
#define DM_REPORT_FIELD_TYPE_STRING 0x00000010
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
@@ -1658,9 +1659,35 @@ struct dm_report_field_type {
const char *desc; /* description of the field */
};
+/*
+ * Per-field reserved value.
+ */
+struct dm_report_field_reserved_value {
+ /* field_num is the position of the field in 'fields'
+ array passed to dm_report_init_with_selection */
+ uint32_t field_num;
+ /* the value is of the same type as the field
+ identified by field_num */
+ const void *value;
+};
+
+/*
+ * Reserved value is a 'value' that is used directly if any of the
'names' is hit.
+ *
+ * If type is any of DM_REPORT_FIELD_TYPE_*, the reserved value is recognized
+ * for all fields of that type.
+ *
+ * If type is DM_REPORT_FIELD_TYPE_NONE, the reserved value is recognized
+ * for the exact field specified - hence the type of the value is automatically
+ * the same as the type of the field itself.
+ *
+ * The array of reserved values is used to initialize reporting with
+ * selection enabled (see also dm_report_init_with_selection function).
+ */
struct dm_report_reserved_value {
const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
const void *value; /* reserved value:
+ struct dm_report_field_reserved_value for DM_REPORT_FIELD_TYPE_NONE
uint64_t for DM_REPORT_FIELD_TYPE_NUMBER
uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
uint64_t for DM_REPORT_FIELD_TYPE_PERCENT
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 00c3d3f..ad89cf2 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1599,6 +1599,18 @@ static int _tok_op_cmp(const char *s, const char **end)
return _tok_op(_op_cmp, s, end, 0);
}
+static char _get_and_skip_quote_char(char const **s)
+{
+ char c = 0;
+
+ if (**s == '"' || **s == '\'') {
+ c = **s;
+ (*s)++;
+ }
+
+ return c;
+}
+
/*
*
* Input:
@@ -1689,38 +1701,62 @@ static const char *_tok_value_string(const char *s,
return s;
}
+static const char *_reserved_name(const char **names, const char *s, size_t len)
+{
+ const char **name = names;
+ while (*name) {
+ if ((strlen(*name) == len) && !strncmp(*name, s, len))
+ return *name;
+ name++;
+ }
+ return NULL;
+}
+
/*
* Used to replace a string representation of the reserved value
* found in selection with the exact reserved value of certain type.
*/
-static const char *_get_reserved_value(struct dm_report *rh, unsigned type,
- const char *s, const char **begin, const char **end,
- const struct dm_report_reserved_value **reserved)
-{
- const struct dm_report_reserved_value *iter = rh->reserved_values;
- const char **name;
+static const char *_get_reserved(struct dm_report *rh, unsigned type,
+ uint32_t field_num, int implicit,
+ const char *s, const char **begin, const char **end,
+ const struct dm_report_reserved_value **reserved)
+{
+ const struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
+ const char *tmp_begin, *tmp_end, *tmp_s = s;
+ const char *name = NULL;
+ char c;
*reserved = NULL;
if (!iter)
return s;
- while (iter->type) {
- if (iter->type & type) {
- name = iter->names;
- while (*name) {
- if (!strcmp(*name, s)) {
- *begin = s;
- *end = s += strlen(*name);
- *reserved = iter;
- return s;
- }
- name++;
- }
+ c = _get_and_skip_quote_char(&tmp_s);
+ if (!(tmp_s = _tok_value_string(tmp_s, &tmp_begin, &tmp_end, c, SEL_AND | SEL_OR
| SEL_PRECEDENCE_PE, NULL)))
+ return s;
+
+ while (iter->value) {
+ if (!iter->type) {
+ /* DM_REPORT_FIELD_TYPE_NONE - per-field reserved value */
+ if (((((const struct dm_report_field_reserved_value *) iter->value)->field_num)
== field_num) &&
+ (name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
+ } else if (iter->type & type) {
+ /* DM_REPORT_FIELD_TYPE_* - per-type reserved value */
+ if ((name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
+ break;
}
iter++;
}
+ if (name) {
+ /* found! */
+ *begin = tmp_begin;
+ *end = tmp_end;
+ s = tmp_s;
+ *reserved = iter;
+ }
+
return s;
}
@@ -1880,18 +1916,6 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char
*begin,
return 1;
}
-static char _get_and_skip_quote_char(char const **s)
-{
- char c = 0;
-
- if (**s == '"' || **s == '\'') {
- c = **s;
- (*s)++;
- }
-
- return c;
-}
-
/*
* Input:
* ft - field type for which the value is parsed
@@ -2033,8 +2057,10 @@ bad:
*/
static const char *_tok_value(struct dm_report *rh,
const struct dm_report_field_type *ft,
- const char *s, const char **begin,
- const char **end, uint32_t *flags,
+ uint32_t field_num, int implicit,
+ const char *s,
+ const char **begin, const char **end,
+ uint32_t *flags,
const struct dm_report_reserved_value **reserved,
struct dm_pool *mem, void *custom)
{
@@ -2046,7 +2072,7 @@ static const char *_tok_value(struct dm_report *rh,
s = _skip_space(s);
- s = _get_reserved_value(rh, expected_type, s, begin, end, reserved);
+ s = _get_reserved(rh, expected_type, field_num, implicit, s, begin, end, reserved);
if (*reserved) {
*flags |= expected_type;
return s;
@@ -2149,6 +2175,14 @@ static const char *_tok_field_name(const char *s,
return s;
}
+static const void *_get_reserved_value(const struct dm_report_reserved_value *reserved)
+{
+ if (reserved->type)
+ return reserved->value;
+ else
+ return ((const struct dm_report_field_reserved_value *) reserved->value)->value;
+}
+
static struct field_selection *_create_field_selection(struct dm_report *rh,
uint32_t field_num,
int implicit,
@@ -2229,7 +2263,7 @@ static struct field_selection *_create_field_selection(struct
dm_report *rh,
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
case DM_REPORT_FIELD_TYPE_STRING:
if (reserved) {
- fs->v.s = (const char *) reserved->value;
+ fs->v.s = (const char *) _get_reserved_value(reserved);
dm_pool_free(rh->mem, s);
} else {
fs->v.s = s;
@@ -2241,7 +2275,7 @@ static struct field_selection *_create_field_selection(struct
dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_NUMBER:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
(errno == ERANGE)) {
@@ -2257,7 +2291,7 @@ static struct field_selection *_create_field_selection(struct
dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_SIZE:
if (reserved)
- fs->v.d = (double) * (uint64_t *) reserved->value;
+ fs->v.d = (double) * (uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if (errno == ERANGE) {
@@ -2276,7 +2310,7 @@ static struct field_selection *_create_field_selection(struct
dm_report *rh,
break;
case DM_REPORT_FIELD_TYPE_PERCENT:
if (reserved)
- fs->v.i = *(uint64_t *) reserved->value;
+ fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
else {
fs->v.d = strtod(s, NULL);
if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
@@ -2508,7 +2542,9 @@ static struct selection_node *_parse_selection(struct dm_report
*rh,
custom = &str_list;
else
custom = NULL;
- if (!(last = _tok_value(rh, ft, last, &vs, &ve, &flags, &reserved,
rh->mem, custom)))
+ if (!(last = _tok_value(rh, ft, field_num, implicit,
+ last, &vs, &ve, &flags,
+ &reserved, rh->mem, custom)))
goto_bad;
}