mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
config: add support for config value formatting flags
There are two basic groups of formatting flags (32 bits): - common ones applicable for all config value types (lower 16 bits) - type-related formatting flags (higher 16 bits) With this patch, we initially support four new flags that modify the the way the config value is displayed: Common flags: ============= DM_CONFIG_VALUE_FMT_COMMON_ARRAY - causes array config values to be enclosed in "[ ]" even if there's only one item (previously, there was no way to recognize an array with one item and scalar value, hence array values with one member were always displayed without "[ ]" which libdm accepted when reading, but it may have been misleading for users) DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACE - causes extra spaces to be inserted in "key = value" (or key = [ value, value, ... ] in case of arrays), compared to "key=value" seen on output before. This makes the output more readable for users. Type-related flags: =================== DM_CONFIG_VALUE_FMT_INT_OCTAL - prints integers in octal form with "0" as a prefix (libdm's config reading code can handle this via strtol just fine so it's properly recognized as number in octal form already if there's "0" used as prefix) DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES - makes it possible to print strings without enclosing " " This patch also adds dm_config_value_set_format_flags and dm_config_value_get_format_flags functions to set and get these formatting flags.
This commit is contained in:
parent
c5ba60827e
commit
9465963faf
@ -667,7 +667,8 @@ static void _log_type_error(const char *path, cfg_def_type_t actual,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct dm_config_value *_get_def_array_values(struct dm_config_tree *cft,
|
static struct dm_config_value *_get_def_array_values(struct dm_config_tree *cft,
|
||||||
const cfg_def_item_t *def)
|
const cfg_def_item_t *def,
|
||||||
|
uint32_t format_flags)
|
||||||
{
|
{
|
||||||
char *enc_value, *token, *p, *r;
|
char *enc_value, *token, *p, *r;
|
||||||
struct dm_config_value *array = NULL, *v = NULL, *oldv = NULL;
|
struct dm_config_value *array = NULL, *v = NULL, *oldv = NULL;
|
||||||
@ -678,6 +679,7 @@ static struct dm_config_value *_get_def_array_values(struct dm_config_tree *cft,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
array->type = DM_CFG_EMPTY_ARRAY;
|
array->type = DM_CFG_EMPTY_ARRAY;
|
||||||
|
dm_config_value_set_format_flags(array, format_flags);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,6 +712,9 @@ static struct dm_config_value *_get_def_array_values(struct dm_config_tree *cft,
|
|||||||
dm_free(enc_value);
|
dm_free(enc_value);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dm_config_value_set_format_flags(v, format_flags);
|
||||||
|
|
||||||
if (oldv)
|
if (oldv)
|
||||||
oldv->next = v;
|
oldv->next = v;
|
||||||
if (!array)
|
if (!array)
|
||||||
@ -839,7 +844,7 @@ static int _check_value_differs_from_default(struct cft_check_handle *handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!v_def && (def->type & CFG_TYPE_ARRAY)) {
|
if (!v_def && (def->type & CFG_TYPE_ARRAY)) {
|
||||||
if (!(v_def_array = v_def_iter = _get_def_array_values(handle->cft, def)))
|
if (!(v_def_array = v_def_iter = _get_def_array_values(handle->cft, def, 0)))
|
||||||
return_0;
|
return_0;
|
||||||
do {
|
do {
|
||||||
/* iterate over each element of the array and check its value */
|
/* iterate over each element of the array and check its value */
|
||||||
@ -1739,15 +1744,19 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
|
|||||||
{
|
{
|
||||||
struct dm_config_node *cn;
|
struct dm_config_node *cn;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
uint32_t format_flags = 0;
|
||||||
|
|
||||||
if (!(cn = dm_config_create_node(cft, def->name))) {
|
if (!(cn = dm_config_create_node(cft, def->name))) {
|
||||||
log_error("Failed to create default config setting node.");
|
log_error("Failed to create default config setting node.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(def->type & CFG_TYPE_SECTION) && (!(cn->v = dm_config_create_value(cft)))) {
|
if (!(def->type & CFG_TYPE_SECTION) && !(def->type & CFG_TYPE_ARRAY)) {
|
||||||
log_error("Failed to create default config setting node value.");
|
if (!(cn->v = dm_config_create_value(cft))) {
|
||||||
return NULL;
|
log_error("Failed to create default config setting node value.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
format_flags |= DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES;
|
||||||
}
|
}
|
||||||
|
|
||||||
cn->id = def->id;
|
cn->id = def->id;
|
||||||
@ -1755,6 +1764,9 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
|
|||||||
if (spec->unconfigured && def->default_unconfigured_value.v_UNCONFIGURED) {
|
if (spec->unconfigured && def->default_unconfigured_value.v_UNCONFIGURED) {
|
||||||
cn->v->type = DM_CFG_STRING;
|
cn->v->type = DM_CFG_STRING;
|
||||||
cn->v->v.str = cfg_def_get_default_unconfigured_value_hint(spec->cmd, def);
|
cn->v->v.str = cfg_def_get_default_unconfigured_value_hint(spec->cmd, def);
|
||||||
|
if (def->type != CFG_TYPE_STRING)
|
||||||
|
format_flags |= DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES;
|
||||||
|
dm_config_value_set_format_flags(cn->v, format_flags);
|
||||||
} else if (!(def->type & CFG_TYPE_ARRAY)) {
|
} else if (!(def->type & CFG_TYPE_ARRAY)) {
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case CFG_TYPE_SECTION:
|
case CFG_TYPE_SECTION:
|
||||||
@ -1767,6 +1779,8 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
|
|||||||
case CFG_TYPE_INT:
|
case CFG_TYPE_INT:
|
||||||
cn->v->type = DM_CFG_INT;
|
cn->v->type = DM_CFG_INT;
|
||||||
cn->v->v.i = cfg_def_get_default_value_hint(spec->cmd, def, CFG_TYPE_INT, NULL);
|
cn->v->v.i = cfg_def_get_default_value_hint(spec->cmd, def, CFG_TYPE_INT, NULL);
|
||||||
|
if (def->flags & CFG_FORMAT_INT_OCTAL)
|
||||||
|
format_flags |= DM_CONFIG_VALUE_FMT_INT_OCTAL;
|
||||||
break;
|
break;
|
||||||
case CFG_TYPE_FLOAT:
|
case CFG_TYPE_FLOAT:
|
||||||
cn->v->type = DM_CFG_FLOAT;
|
cn->v->type = DM_CFG_FLOAT;
|
||||||
@ -1783,8 +1797,12 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
|
|||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
dm_config_value_set_format_flags(cn->v, format_flags);
|
||||||
cn->v = _get_def_array_values(cft, def);
|
} else {
|
||||||
|
format_flags |= (DM_CONFIG_VALUE_FMT_COMMON_ARRAY |
|
||||||
|
DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES);
|
||||||
|
cn->v = _get_def_array_values(cft, def, format_flags);
|
||||||
|
}
|
||||||
|
|
||||||
cn->child = NULL;
|
cn->child = NULL;
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
@ -119,6 +119,8 @@ typedef union {
|
|||||||
#define CFG_DEFAULT_RUN_TIME 0x100
|
#define CFG_DEFAULT_RUN_TIME 0x100
|
||||||
/* whether the configuration setting is disabled (and hence defaults always used) */
|
/* whether the configuration setting is disabled (and hence defaults always used) */
|
||||||
#define CFG_DISABLED 0x200
|
#define CFG_DISABLED 0x200
|
||||||
|
/* whether to print integers in octal form (prefixed by "0") */
|
||||||
|
#define CFG_FORMAT_INT_OCTAL 0x400
|
||||||
|
|
||||||
/* configuration definition item structure */
|
/* configuration definition item structure */
|
||||||
typedef struct cfg_def_item {
|
typedef struct cfg_def_item {
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
* CFG_DEFAULT_UNDEFINED - node's default value is undefined (depends on other system/kernel values outside of lvm)
|
* CFG_DEFAULT_UNDEFINED - node's default value is undefined (depends on other system/kernel values outside of lvm)
|
||||||
* CFG_DEFAULT_COMMENTED - node's default value is commented out on output
|
* CFG_DEFAULT_COMMENTED - node's default value is commented out on output
|
||||||
* CFG_DISABLED - configuration is disabled (defaults always used)
|
* CFG_DISABLED - configuration is disabled (defaults always used)
|
||||||
|
* CFG_FORMAT_INT_OCTAL - print integer number in octal form (also prefixed by "0")
|
||||||
*
|
*
|
||||||
* type: Allowed type for the value of simple configuation setting, one of:
|
* type: Allowed type for the value of simple configuation setting, one of:
|
||||||
* CFG_TYPE_BOOL
|
* CFG_TYPE_BOOL
|
||||||
|
2
libdm/.exported_symbols.DM_1_02_100
Normal file
2
libdm/.exported_symbols.DM_1_02_100
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
dm_config_value_set_format_flags
|
||||||
|
dm_config_value_get_format_flags
|
@ -1847,6 +1847,7 @@ struct dm_config_value {
|
|||||||
} v;
|
} v;
|
||||||
|
|
||||||
struct dm_config_value *next; /* For arrays */
|
struct dm_config_value *next; /* For arrays */
|
||||||
|
uint32_t format_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dm_config_node {
|
struct dm_config_node {
|
||||||
@ -1949,6 +1950,24 @@ struct dm_config_node *dm_config_create_node(struct dm_config_tree *cft, const c
|
|||||||
struct dm_config_value *dm_config_create_value(struct dm_config_tree *cft);
|
struct dm_config_value *dm_config_create_value(struct dm_config_tree *cft);
|
||||||
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *cn, int siblings);
|
struct dm_config_node *dm_config_clone_node(struct dm_config_tree *cft, const struct dm_config_node *cn, int siblings);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common formatting flags applicable to all config node types (lower 16 bits).
|
||||||
|
*/
|
||||||
|
#define DM_CONFIG_VALUE_FMT_COMMON_ARRAY 0x00000001 /* value is array */
|
||||||
|
#define DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES 0x00000002 /* add spaces in "key = value" pairs in constrast to "key=value" for better readability */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type-related config node formatting flags (higher 16 bits).
|
||||||
|
*/
|
||||||
|
/* int-related formatting flags */
|
||||||
|
#define DM_CONFIG_VALUE_FMT_INT_OCTAL 0x00010000 /* print number in octal form */
|
||||||
|
|
||||||
|
/* string-related formatting flags */
|
||||||
|
#define DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES 0x00010000 /* do not print quotes around string value */
|
||||||
|
|
||||||
|
void dm_config_value_set_format_flags(struct dm_config_value *cv, uint32_t format_flags);
|
||||||
|
uint32_t dm_config_value_get_format_flags(struct dm_config_value *cv);
|
||||||
|
|
||||||
struct dm_pool *dm_config_memory(struct dm_config_tree *cft);
|
struct dm_pool *dm_config_memory(struct dm_config_tree *cft);
|
||||||
|
|
||||||
/* Udev device directory. */
|
/* Udev device directory. */
|
||||||
|
@ -273,11 +273,13 @@ static int _line_end(const struct dm_config_node *cn, struct config_output *out)
|
|||||||
static int _write_value(struct config_output *out, const struct dm_config_value *v)
|
static int _write_value(struct config_output *out, const struct dm_config_value *v)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case DM_CFG_STRING:
|
case DM_CFG_STRING:
|
||||||
buf = alloca(dm_escaped_len(v->v.str));
|
buf = alloca(dm_escaped_len(v->v.str));
|
||||||
line_append("\"%s\"", dm_escape_double_quotes(buf, v->v.str));
|
s = (v->format_flags & DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES) ? "" : "\"";
|
||||||
|
line_append("%s%s%s", s, dm_escape_double_quotes(buf, v->v.str), s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_CFG_FLOAT:
|
case DM_CFG_FLOAT:
|
||||||
@ -285,11 +287,15 @@ static int _write_value(struct config_output *out, const struct dm_config_value
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_CFG_INT:
|
case DM_CFG_INT:
|
||||||
line_append("%" PRId64, v->v.i);
|
if (v->format_flags & DM_CONFIG_VALUE_FMT_INT_OCTAL)
|
||||||
|
line_append("0%" PRIo64, v->v.i);
|
||||||
|
else
|
||||||
|
line_append("%" PRId64, v->v.i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_CFG_EMPTY_ARRAY:
|
case DM_CFG_EMPTY_ARRAY:
|
||||||
line_append("[]");
|
s = (v->format_flags & DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES) ? " " : "";
|
||||||
|
line_append("[%s]", s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -303,6 +309,8 @@ static int _write_value(struct config_output *out, const struct dm_config_value
|
|||||||
static int _write_config(const struct dm_config_node *n, int only_one,
|
static int _write_config(const struct dm_config_node *n, int only_one,
|
||||||
struct config_output *out, int level)
|
struct config_output *out, int level)
|
||||||
{
|
{
|
||||||
|
const char *extra_space;
|
||||||
|
int format_array;
|
||||||
char space[MAX_INDENT + 1];
|
char space[MAX_INDENT + 1];
|
||||||
int l = (level < MAX_INDENT) ? level : MAX_INDENT;
|
int l = (level < MAX_INDENT) ? level : MAX_INDENT;
|
||||||
int i;
|
int i;
|
||||||
@ -316,6 +324,9 @@ static int _write_config(const struct dm_config_node *n, int only_one,
|
|||||||
space[i] = '\0';
|
space[i] = '\0';
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
extra_space = (n->v && (n->v->format_flags & DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES)) ? " " : "";
|
||||||
|
format_array = (n->v && (n->v->format_flags & DM_CONFIG_VALUE_FMT_COMMON_ARRAY));
|
||||||
|
|
||||||
if (out->spec && out->spec->prefix_fn)
|
if (out->spec && out->spec->prefix_fn)
|
||||||
out->spec->prefix_fn(n, space, out->baton);
|
out->spec->prefix_fn(n, space, out->baton);
|
||||||
|
|
||||||
@ -341,20 +352,25 @@ static int _write_config(const struct dm_config_node *n, int only_one,
|
|||||||
} else {
|
} else {
|
||||||
/* it's a value */
|
/* it's a value */
|
||||||
const struct dm_config_value *v = n->v;
|
const struct dm_config_value *v = n->v;
|
||||||
line_append("=");
|
line_append("%s=%s", extra_space, extra_space);
|
||||||
if (v->next) {
|
if (v->next) {
|
||||||
line_append("[");
|
line_append("[%s", extra_space);
|
||||||
while (v && v->type != DM_CFG_EMPTY_ARRAY) {
|
while (v && v->type != DM_CFG_EMPTY_ARRAY) {
|
||||||
if (!_write_value(out, v))
|
if (!_write_value(out, v))
|
||||||
return_0;
|
return_0;
|
||||||
v = v->next;
|
v = v->next;
|
||||||
if (v && v->type != DM_CFG_EMPTY_ARRAY)
|
if (v && v->type != DM_CFG_EMPTY_ARRAY)
|
||||||
line_append(", ");
|
line_append(",%s", extra_space);
|
||||||
}
|
}
|
||||||
line_append("]");
|
line_append("%s]", extra_space);
|
||||||
} else
|
} else {
|
||||||
|
if (format_array && (v->type != DM_CFG_EMPTY_ARRAY))
|
||||||
|
line_append("[%s", extra_space);
|
||||||
if (!_write_value(out, v))
|
if (!_write_value(out, v))
|
||||||
return_0;
|
return_0;
|
||||||
|
if (format_array && (v->type != DM_CFG_EMPTY_ARRAY))
|
||||||
|
line_append("%s]", extra_space);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!_line_end(n, out))
|
if (!_line_end(n, out))
|
||||||
return_0;
|
return_0;
|
||||||
@ -1328,6 +1344,22 @@ struct dm_config_value *dm_config_create_value(struct dm_config_tree *cft)
|
|||||||
return _create_value(cft->mem);
|
return _create_value(cft->mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dm_config_value_set_format_flags(struct dm_config_value *cv, uint32_t format_flags)
|
||||||
|
{
|
||||||
|
if (!cv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cv->format_flags = format_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t dm_config_value_get_format_flags(struct dm_config_value *cv)
|
||||||
|
{
|
||||||
|
if (!cv)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return cv->format_flags;
|
||||||
|
}
|
||||||
|
|
||||||
struct dm_pool *dm_config_memory(struct dm_config_tree *cft)
|
struct dm_pool *dm_config_memory(struct dm_config_tree *cft)
|
||||||
{
|
{
|
||||||
return cft->mem;
|
return cft->mem;
|
||||||
|
Loading…
Reference in New Issue
Block a user