mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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.
This commit is contained in:
parent
da545ce3b4
commit
0956fd230f
@ -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
|
||||
|
@ -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)
|
||||
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 = rh->reserved_values;
|
||||
const char **name;
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user