summaryrefslogtreecommitdiff
path: root/src/app/config/confparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/config/confparse.c')
-rw-r--r--src/app/config/confparse.c110
1 files changed, 45 insertions, 65 deletions
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index a02aa26e82..be4341e3f6 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -29,8 +29,7 @@
#include "lib/confmgt/unitparse.h"
#include "lib/container/bitarray.h"
#include "lib/encoding/confline.h"
-
-#include "lib/confmgt/typedvar.h"
+#include "lib/confmgt/structvar.h"
static void config_reset(const config_format_t *fmt, void *options,
const config_var_t *var, int use_defaults);
@@ -110,17 +109,17 @@ config_find_option_mutable(config_format_t *fmt, const char *key)
if (!keylen)
return NULL; /* if they say "--" on the command line, it's not an option */
/* First, check for an exact (case-insensitive) match */
- for (i=0; fmt->vars[i].name; ++i) {
- if (!strcasecmp(key, fmt->vars[i].name)) {
+ for (i=0; fmt->vars[i].member.name; ++i) {
+ if (!strcasecmp(key, fmt->vars[i].member.name)) {
return &fmt->vars[i];
}
}
/* If none, check for an abbreviated match */
- for (i=0; fmt->vars[i].name; ++i) {
- if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
+ for (i=0; fmt->vars[i].member.name; ++i) {
+ if (!strncasecmp(key, fmt->vars[i].member.name, keylen)) {
log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
"Please use '%s' instead",
- key, fmt->vars[i].name);
+ key, fmt->vars[i].member.name);
return &fmt->vars[i];
}
}
@@ -144,7 +143,7 @@ static int
config_count_options(const config_format_t *fmt)
{
int i;
- for (i=0; fmt->vars[i].name; ++i)
+ for (i=0; fmt->vars[i].member.name; ++i)
;
return i;
}
@@ -163,23 +162,14 @@ config_assign_value(const config_format_t *fmt, void *options,
config_line_t *c, char **msg)
{
const config_var_t *var;
- void *lvalue;
CONFIG_CHECK(fmt, options);
var = config_find_option(fmt, c->key);
tor_assert(var);
- tor_assert(!strcmp(c->key, var->name));
-
- lvalue = STRUCT_VAR_P(options, var->var_offset);
+ tor_assert(!strcmp(c->key, var->member.name));
- if (var->type == CONFIG_TYPE_ROUTERSET) {
- // XXXX make the backend extensible so that we don't have to
- // XXXX special-case this type.
- return typed_var_kvassign_ex(lvalue, c, msg, &routerset_type_defn);
- }
-
- return typed_var_kvassign(lvalue, c, msg, var->type);
+ return struct_var_kvassign(options, c, msg, &var->member);
}
/** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
@@ -191,14 +181,14 @@ config_mark_lists_fragile(const config_format_t *fmt, void *options)
tor_assert(fmt);
tor_assert(options);
- for (i = 0; fmt->vars[i].name; ++i) {
+ for (i = 0; fmt->vars[i].member.name; ++i) {
const config_var_t *var = &fmt->vars[i];
config_line_t *list;
- if (var->type != CONFIG_TYPE_LINELIST &&
- var->type != CONFIG_TYPE_LINELIST_V)
+ if (var->member.type != CONFIG_TYPE_LINELIST &&
+ var->member.type != CONFIG_TYPE_LINELIST_V)
continue;
- list = *(config_line_t **)STRUCT_VAR_P(options, var->var_offset);
+ list = *(config_line_t **)STRUCT_VAR_P(options, var->member.offset);
if (list)
list->fragile = 1;
}
@@ -238,7 +228,7 @@ config_assign_line(const config_format_t *fmt, void *options,
var = config_find_option(fmt, c->key);
if (!var) {
if (fmt->extra) {
- void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
+ void *lvalue = STRUCT_VAR_P(options, fmt->extra->offset);
log_info(LD_CONFIG,
"Found unrecognized option '%s'; saving it.", c->key);
config_line_append((config_line_t**)lvalue, c->key, c->value);
@@ -251,22 +241,22 @@ config_assign_line(const config_format_t *fmt, void *options,
}
/* Put keyword into canonical case. */
- if (strcmp(var->name, c->key)) {
+ if (strcmp(var->member.name, c->key)) {
tor_free(c->key);
- c->key = tor_strdup(var->name);
+ c->key = tor_strdup(var->member.name);
}
const char *deprecation_msg;
if (warn_deprecations &&
- (deprecation_msg = config_find_deprecation(fmt, var->name))) {
- warn_deprecated_option(var->name, deprecation_msg);
+ (deprecation_msg = config_find_deprecation(fmt, var->member.name))) {
+ warn_deprecated_option(var->member.name, deprecation_msg);
}
if (!strlen(c->value)) {
/* reset or clear it, then return */
if (!clear_first) {
- if ((var->type == CONFIG_TYPE_LINELIST ||
- var->type == CONFIG_TYPE_LINELIST_S) &&
+ if ((var->member.type == CONFIG_TYPE_LINELIST ||
+ var->member.type == CONFIG_TYPE_LINELIST_S) &&
c->command != CONFIG_LINE_CLEAR) {
/* We got an empty linelist from the torrc or command line.
As a special case, call this an error. Warn and ignore. */
@@ -283,14 +273,14 @@ config_assign_line(const config_format_t *fmt, void *options,
config_reset(fmt, options, var, use_defaults); // LCOV_EXCL_LINE
}
- if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
- var->type != CONFIG_TYPE_LINELIST_S)) {
+ if (options_seen && (var->member.type != CONFIG_TYPE_LINELIST &&
+ var->member.type != CONFIG_TYPE_LINELIST_S)) {
/* We're tracking which options we've seen, and this option is not
* supposed to occur more than once. */
int var_index = (int)(var - fmt->vars);
if (bitarray_is_set(options_seen, var_index)) {
log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
- "value will be ignored.", var->name);
+ "value will be ignored.", var->member.name);
}
bitarray_set(options_seen, var_index);
}
@@ -352,7 +342,6 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
const char *key, int escape_val)
{
const config_var_t *var;
- const void *value;
config_line_t *result;
tor_assert(options && key);
@@ -363,15 +352,8 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
return NULL;
}
- value = STRUCT_VAR_P(options, var->var_offset);
-
- if (var->type == CONFIG_TYPE_ROUTERSET) {
- // XXXX make the backend extensible so that we don't have to
- // XXXX special-case this type.
- result = typed_var_kvencode_ex(var->name, value, &routerset_type_defn);
- } else {
- result = typed_var_kvencode(var->name, value, var->type);
- }
+
+ result = struct_var_kvencode(options, &var->member);
if (escape_val) {
config_line_t *line;
@@ -497,14 +479,10 @@ static void
config_clear(const config_format_t *fmt, void *options,
const config_var_t *var)
{
- void *lvalue = STRUCT_VAR_P(options, var->var_offset);
+
(void)fmt; /* unused */
- if (var->type == CONFIG_TYPE_ROUTERSET) {
- typed_var_free_ex(lvalue, &routerset_type_defn);
- return;
- }
- typed_var_free(lvalue, var->type);
+ struct_var_free(options, &var->member);
}
/** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
@@ -522,7 +500,7 @@ config_reset(const config_format_t *fmt, void *options,
return; /* all done */
if (var->initvalue) {
c = tor_malloc_zero(sizeof(config_line_t));
- c->key = tor_strdup(var->name);
+ c->key = tor_strdup(var->member.name);
c->value = tor_strdup(var->initvalue);
if (config_assign_value(fmt, options, c, &msg) < 0) {
// LCOV_EXCL_START
@@ -545,10 +523,11 @@ config_free_(const config_format_t *fmt, void *options)
tor_assert(fmt);
- for (i=0; fmt->vars[i].name; ++i)
+ for (i=0; fmt->vars[i].member.name; ++i)
config_clear(fmt, options, &(fmt->vars[i]));
+
if (fmt->extra) {
- config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
+ config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset);
config_free_lines(*linep);
*linep = NULL;
}
@@ -585,12 +564,12 @@ config_dup(const config_format_t *fmt, const void *old)
config_line_t *line;
newopts = config_new(fmt);
- for (i=0; fmt->vars[i].name; ++i) {
- if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
+ for (i=0; fmt->vars[i].member.name; ++i) {
+ if (fmt->vars[i].member.type == CONFIG_TYPE_LINELIST_S)
continue;
- if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
+ if (fmt->vars[i].member.type == CONFIG_TYPE_OBSOLETE)
continue;
- line = config_get_assigned_option(fmt, old, fmt->vars[i].name, 0);
+ line = config_get_assigned_option(fmt, old, fmt->vars[i].member.name, 0);
if (line) {
char *msg = NULL;
if (config_assign(fmt, newopts, line, 0, &msg) < 0) {
@@ -615,7 +594,7 @@ config_init(const config_format_t *fmt, void *options)
const config_var_t *var;
CONFIG_CHECK(fmt, options);
- for (i=0; fmt->vars[i].name; ++i) {
+ for (i=0; fmt->vars[i].member.name; ++i) {
var = &fmt->vars[i];
if (!var->initvalue)
continue; /* defaults to NULL or 0 */
@@ -657,22 +636,23 @@ config_dump(const config_format_t *fmt, const void *default_options,
}
elements = smartlist_new();
- for (i=0; fmt->vars[i].name; ++i) {
+ for (i=0; fmt->vars[i].member.name; ++i) {
int comment_option = 0;
- if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
- fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
+ if (fmt->vars[i].member.type == CONFIG_TYPE_OBSOLETE ||
+ fmt->vars[i].member.type == CONFIG_TYPE_LINELIST_S)
continue;
/* Don't save 'hidden' control variables. */
- if (!strcmpstart(fmt->vars[i].name, "__"))
+ if (!strcmpstart(fmt->vars[i].member.name, "__"))
continue;
- if (minimal && config_is_same(fmt, options, defaults, fmt->vars[i].name))
+ if (minimal && config_is_same(fmt, options, defaults,
+ fmt->vars[i].member.name))
continue;
else if (comment_defaults &&
- config_is_same(fmt, options, defaults, fmt->vars[i].name))
+ config_is_same(fmt, options, defaults, fmt->vars[i].member.name))
comment_option = 1;
line = assigned =
- config_get_assigned_option(fmt, options, fmt->vars[i].name, 1);
+ config_get_assigned_option(fmt, options, fmt->vars[i].member.name, 1);
for (; line; line = line->next) {
if (!strcmpstart(line->key, "__")) {
@@ -688,7 +668,7 @@ config_dump(const config_format_t *fmt, const void *default_options,
}
if (fmt->extra) {
- line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
+ line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->offset);
for (; line; line = line->next) {
smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value);
}