1
0
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:
Peter Rajnoha 2015-06-23 13:02:45 +02:00
parent c5ba60827e
commit 9465963faf
6 changed files with 89 additions and 15 deletions

View File

@ -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,22 +1744,29 @@ 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)) {
if (!(cn->v = dm_config_create_value(cft))) {
log_error("Failed to create default config setting node value."); log_error("Failed to create default config setting node value.");
return NULL; return NULL;
} }
format_flags |= DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACES;
}
cn->id = def->id; cn->id = def->id;
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) {

View File

@ -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 {

View File

@ -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

View File

@ -0,0 +1,2 @@
dm_config_value_set_format_flags
dm_config_value_get_format_flags

View File

@ -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. */

View File

@ -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:
if (v->format_flags & DM_CONFIG_VALUE_FMT_INT_OCTAL)
line_append("0%" PRIo64, v->v.i);
else
line_append("%" PRId64, v->v.i); 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;