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_LEFT 0x00000001
|
||||||
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
|
#define DM_REPORT_FIELD_ALIGN_RIGHT 0x00000002
|
||||||
#define DM_REPORT_FIELD_TYPE_MASK 0x00000FF0
|
#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_STRING 0x00000010
|
||||||
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
|
#define DM_REPORT_FIELD_TYPE_NUMBER 0x00000020
|
||||||
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
|
#define DM_REPORT_FIELD_TYPE_SIZE 0x00000040
|
||||||
@ -1658,9 +1659,35 @@ struct dm_report_field_type {
|
|||||||
const char *desc; /* description of the field */
|
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 {
|
struct dm_report_reserved_value {
|
||||||
const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
|
const unsigned type; /* DM_REPORT_FIELD_TYPE_* */
|
||||||
const void *value; /* reserved value:
|
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_NUMBER
|
||||||
uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
|
uint64_t for DM_REPORT_FIELD_TYPE_SIZE (number of 512-byte sectors)
|
||||||
uint64_t for DM_REPORT_FIELD_TYPE_PERCENT
|
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);
|
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:
|
* Input:
|
||||||
@ -1689,38 +1701,62 @@ static const char *_tok_value_string(const char *s,
|
|||||||
return 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
|
* Used to replace a string representation of the reserved value
|
||||||
* found in selection with the exact reserved value of certain type.
|
* found in selection with the exact reserved value of certain type.
|
||||||
*/
|
*/
|
||||||
static const char *_get_reserved_value(struct dm_report *rh, unsigned type,
|
static const char *_get_reserved(struct dm_report *rh, unsigned type,
|
||||||
const char *s, const char **begin, const char **end,
|
uint32_t field_num, int implicit,
|
||||||
const struct dm_report_reserved_value **reserved)
|
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 struct dm_report_reserved_value *iter = implicit ? NULL : rh->reserved_values;
|
||||||
const char **name;
|
const char *tmp_begin, *tmp_end, *tmp_s = s;
|
||||||
|
const char *name = NULL;
|
||||||
|
char c;
|
||||||
|
|
||||||
*reserved = NULL;
|
*reserved = NULL;
|
||||||
|
|
||||||
if (!iter)
|
if (!iter)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
while (iter->type) {
|
c = _get_and_skip_quote_char(&tmp_s);
|
||||||
if (iter->type & type) {
|
if (!(tmp_s = _tok_value_string(tmp_s, &tmp_begin, &tmp_end, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL)))
|
||||||
name = iter->names;
|
return s;
|
||||||
while (*name) {
|
|
||||||
if (!strcmp(*name, s)) {
|
while (iter->value) {
|
||||||
*begin = s;
|
if (!iter->type) {
|
||||||
*end = s += strlen(*name);
|
/* DM_REPORT_FIELD_TYPE_NONE - per-field reserved value */
|
||||||
*reserved = iter;
|
if (((((const struct dm_report_field_reserved_value *) iter->value)->field_num) == field_num) &&
|
||||||
return s;
|
(name = _reserved_name(iter->names, tmp_begin, tmp_end - tmp_begin)))
|
||||||
}
|
break;
|
||||||
name++;
|
} 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++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
/* found! */
|
||||||
|
*begin = tmp_begin;
|
||||||
|
*end = tmp_end;
|
||||||
|
s = tmp_s;
|
||||||
|
*reserved = iter;
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1880,18 +1916,6 @@ static int _add_item_to_string_list(struct dm_pool *mem, const char *begin,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char _get_and_skip_quote_char(char const **s)
|
|
||||||
{
|
|
||||||
char c = 0;
|
|
||||||
|
|
||||||
if (**s == '"' || **s == '\'') {
|
|
||||||
c = **s;
|
|
||||||
(*s)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input:
|
* Input:
|
||||||
* ft - field type for which the value is parsed
|
* ft - field type for which the value is parsed
|
||||||
@ -2033,8 +2057,10 @@ bad:
|
|||||||
*/
|
*/
|
||||||
static const char *_tok_value(struct dm_report *rh,
|
static const char *_tok_value(struct dm_report *rh,
|
||||||
const struct dm_report_field_type *ft,
|
const struct dm_report_field_type *ft,
|
||||||
const char *s, const char **begin,
|
uint32_t field_num, int implicit,
|
||||||
const char **end, uint32_t *flags,
|
const char *s,
|
||||||
|
const char **begin, const char **end,
|
||||||
|
uint32_t *flags,
|
||||||
const struct dm_report_reserved_value **reserved,
|
const struct dm_report_reserved_value **reserved,
|
||||||
struct dm_pool *mem, void *custom)
|
struct dm_pool *mem, void *custom)
|
||||||
{
|
{
|
||||||
@ -2046,7 +2072,7 @@ static const char *_tok_value(struct dm_report *rh,
|
|||||||
|
|
||||||
s = _skip_space(s);
|
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) {
|
if (*reserved) {
|
||||||
*flags |= expected_type;
|
*flags |= expected_type;
|
||||||
return s;
|
return s;
|
||||||
@ -2149,6 +2175,14 @@ static const char *_tok_field_name(const char *s,
|
|||||||
return 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,
|
static struct field_selection *_create_field_selection(struct dm_report *rh,
|
||||||
uint32_t field_num,
|
uint32_t field_num,
|
||||||
int implicit,
|
int implicit,
|
||||||
@ -2229,7 +2263,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
|||||||
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
|
switch (flags & DM_REPORT_FIELD_TYPE_MASK) {
|
||||||
case DM_REPORT_FIELD_TYPE_STRING:
|
case DM_REPORT_FIELD_TYPE_STRING:
|
||||||
if (reserved) {
|
if (reserved) {
|
||||||
fs->v.s = (const char *) reserved->value;
|
fs->v.s = (const char *) _get_reserved_value(reserved);
|
||||||
dm_pool_free(rh->mem, s);
|
dm_pool_free(rh->mem, s);
|
||||||
} else {
|
} else {
|
||||||
fs->v.s = s;
|
fs->v.s = s;
|
||||||
@ -2241,7 +2275,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
|||||||
break;
|
break;
|
||||||
case DM_REPORT_FIELD_TYPE_NUMBER:
|
case DM_REPORT_FIELD_TYPE_NUMBER:
|
||||||
if (reserved)
|
if (reserved)
|
||||||
fs->v.i = *(uint64_t *) reserved->value;
|
fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
|
||||||
else {
|
else {
|
||||||
if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
|
if (((fs->v.i = strtoull(s, NULL, 10)) == ULLONG_MAX) &&
|
||||||
(errno == ERANGE)) {
|
(errno == ERANGE)) {
|
||||||
@ -2257,7 +2291,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
|||||||
break;
|
break;
|
||||||
case DM_REPORT_FIELD_TYPE_SIZE:
|
case DM_REPORT_FIELD_TYPE_SIZE:
|
||||||
if (reserved)
|
if (reserved)
|
||||||
fs->v.d = (double) * (uint64_t *) reserved->value;
|
fs->v.d = (double) * (uint64_t *) _get_reserved_value(reserved);
|
||||||
else {
|
else {
|
||||||
fs->v.d = strtod(s, NULL);
|
fs->v.d = strtod(s, NULL);
|
||||||
if (errno == ERANGE) {
|
if (errno == ERANGE) {
|
||||||
@ -2276,7 +2310,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
|||||||
break;
|
break;
|
||||||
case DM_REPORT_FIELD_TYPE_PERCENT:
|
case DM_REPORT_FIELD_TYPE_PERCENT:
|
||||||
if (reserved)
|
if (reserved)
|
||||||
fs->v.i = *(uint64_t *) reserved->value;
|
fs->v.i = *(uint64_t *) _get_reserved_value(reserved);
|
||||||
else {
|
else {
|
||||||
fs->v.d = strtod(s, NULL);
|
fs->v.d = strtod(s, NULL);
|
||||||
if ((errno == ERANGE) || (fs->v.d < 0) || (fs->v.d > 100)) {
|
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;
|
custom = &str_list;
|
||||||
else
|
else
|
||||||
custom = NULL;
|
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;
|
goto_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user