mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Partial support for multiplicity in configuration objects
A configuration manager, in addition to a top-level format object, may now also know about a suite of sub-formats. Top-level configuration objects, in turn, may now have a suite of sub-objects.
This commit is contained in:
parent
38b770bbbb
commit
638e58379a
@ -73,10 +73,10 @@ managed_var_free_(managed_var_t *mv)
|
||||
FREE_AND_NULL(managed_var_t, managed_var_free_, (mv))
|
||||
|
||||
struct config_suite_t {
|
||||
/* NOTE: This object isn't implemented yet; it's just a placeholder
|
||||
* to make sure we have our memory menagement right.
|
||||
*/
|
||||
int foo;
|
||||
/** A list of configuration objects managed by a given configuration
|
||||
* manager. They are stored in the same order as the config_format_t
|
||||
* objects in the manager's list of subformats. */
|
||||
smartlist_t *configs;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -86,6 +86,7 @@ static config_suite_t *
|
||||
config_suite_new(void)
|
||||
{
|
||||
config_suite_t *suite = tor_malloc_zero(sizeof(config_suite_t));
|
||||
suite->configs = smartlist_new();
|
||||
return suite;
|
||||
}
|
||||
|
||||
@ -96,6 +97,7 @@ config_suite_free_(config_suite_t *suite)
|
||||
{
|
||||
if (!suite)
|
||||
return;
|
||||
smartlist_free(suite->configs);
|
||||
tor_free(suite);
|
||||
}
|
||||
|
||||
@ -110,6 +112,11 @@ struct config_mgr_t {
|
||||
* contains. A subsequent commit will add more. XXXX)
|
||||
*/
|
||||
const config_format_t *toplevel;
|
||||
/**
|
||||
* List of second-level configuration format objects that this manager
|
||||
* also knows about.
|
||||
*/
|
||||
smartlist_t *subconfigs;
|
||||
/** A smartlist of managed_var_t objects for all configuration formats. */
|
||||
smartlist_t *all_vars;
|
||||
/** A smartlist of config_abbrev_t objects for all abbreviations. These
|
||||
@ -137,12 +144,14 @@ config_mgr_t *
|
||||
config_mgr_new(const config_format_t *toplevel_fmt)
|
||||
{
|
||||
config_mgr_t *mgr = tor_malloc_zero(sizeof(config_mgr_t));
|
||||
mgr->toplevel = toplevel_fmt;
|
||||
mgr->subconfigs = smartlist_new();
|
||||
mgr->all_vars = smartlist_new();
|
||||
mgr->all_abbrevs = smartlist_new();
|
||||
mgr->all_deprecations = smartlist_new();
|
||||
|
||||
config_mgr_register_fmt(mgr, toplevel_fmt, IDX_TOPLEVEL);
|
||||
mgr->toplevel = toplevel_fmt;
|
||||
|
||||
return mgr;
|
||||
}
|
||||
|
||||
@ -158,6 +167,14 @@ config_mgr_register_fmt(config_mgr_t *mgr,
|
||||
"Tried to add a format to a configuration manager after "
|
||||
"it had been frozen.");
|
||||
|
||||
if (object_idx != IDX_TOPLEVEL) {
|
||||
tor_assertf(fmt->config_suite_offset < 0,
|
||||
"Tried to register a toplevel format in a non-toplevel position");
|
||||
}
|
||||
tor_assertf(fmt != mgr->toplevel &&
|
||||
! smartlist_contains(mgr->subconfigs, fmt),
|
||||
"Tried to register an already-registered format.");
|
||||
|
||||
/* register variables */
|
||||
for (i = 0; fmt->vars[i].member.name; ++i) {
|
||||
managed_var_t *mv = tor_malloc_zero(sizeof(managed_var_t));
|
||||
@ -182,6 +199,21 @@ config_mgr_register_fmt(config_mgr_t *mgr,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new format to this configuration object. Asserts on failure.
|
||||
*
|
||||
**/
|
||||
int
|
||||
config_mgr_add_format(config_mgr_t *mgr,
|
||||
const config_format_t *fmt)
|
||||
{
|
||||
tor_assert(mgr);
|
||||
int idx = smartlist_len(mgr->subconfigs);
|
||||
config_mgr_register_fmt(mgr, fmt, idx);
|
||||
smartlist_add(mgr->subconfigs, (void *)fmt);
|
||||
return idx;
|
||||
}
|
||||
|
||||
/** Return a pointer to the config_suite_t * pointer inside a
|
||||
* configuration object; returns NULL if there is no such member. */
|
||||
static inline config_suite_t **
|
||||
@ -204,10 +236,19 @@ config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel)
|
||||
static void *
|
||||
config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
|
||||
{
|
||||
(void)mgr;
|
||||
tor_assert(idx == IDX_TOPLEVEL); // nothing else is implemented yet XXXX
|
||||
tor_assert(mgr);
|
||||
tor_assert(toplevel);
|
||||
return toplevel;
|
||||
if (idx == IDX_TOPLEVEL)
|
||||
return toplevel;
|
||||
|
||||
tor_assertf(idx >= 0 && idx < smartlist_len(mgr->subconfigs),
|
||||
"Index %d is out of range.", idx);
|
||||
config_suite_t **suite = config_mgr_get_suite_ptr(mgr, toplevel);
|
||||
tor_assert(suite);
|
||||
tor_assert(smartlist_len(mgr->subconfigs) ==
|
||||
smartlist_len((*suite)->configs));
|
||||
|
||||
return smartlist_get((*suite)->configs, idx);
|
||||
}
|
||||
|
||||
/** As config_mgr_get_obj_mutable(), but return a const pointer. */
|
||||
@ -257,6 +298,7 @@ config_mgr_free_(config_mgr_t *mgr)
|
||||
smartlist_free(mgr->all_vars);
|
||||
smartlist_free(mgr->all_abbrevs);
|
||||
smartlist_free(mgr->all_deprecations);
|
||||
smartlist_free(mgr->subconfigs);
|
||||
memset(mgr, 0, sizeof(*mgr));
|
||||
tor_free(mgr);
|
||||
}
|
||||
@ -296,6 +338,20 @@ config_mgr_assert_magic_ok(const config_mgr_t *mgr,
|
||||
tor_assert(options);
|
||||
tor_assert(mgr->frozen);
|
||||
struct_check_magic(options, &mgr->toplevel_magic);
|
||||
|
||||
config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, (void*)options);
|
||||
if (suitep == NULL) {
|
||||
tor_assert(smartlist_len(mgr->subconfigs) == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
tor_assert(smartlist_len((*suitep)->configs) ==
|
||||
smartlist_len(mgr->subconfigs));
|
||||
SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
|
||||
void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
|
||||
tor_assert(obj);
|
||||
struct_check_magic(obj, &fmt->magic);
|
||||
} SMARTLIST_FOREACH_END(fmt);
|
||||
}
|
||||
|
||||
/** Macro: assert that <b>cfg</b> has the right magic field for
|
||||
@ -309,12 +365,16 @@ void *
|
||||
config_new(const config_mgr_t *mgr)
|
||||
{
|
||||
tor_assert(mgr->frozen);
|
||||
const config_format_t *fmt = mgr->toplevel;
|
||||
void *opts = tor_malloc_zero(fmt->size);
|
||||
void *opts = tor_malloc_zero(mgr->toplevel->size);
|
||||
struct_set_magic(opts, &mgr->toplevel_magic);
|
||||
config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, opts);
|
||||
if (suitep) {
|
||||
*suitep = config_suite_new();
|
||||
SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
|
||||
void *obj = tor_malloc_zero(fmt->size);
|
||||
struct_set_magic(obj, &fmt->magic);
|
||||
smartlist_add((*suitep)->configs, obj);
|
||||
} SMARTLIST_FOREACH_END(fmt);
|
||||
}
|
||||
CONFIG_CHECK(mgr, opts);
|
||||
return opts;
|
||||
@ -826,30 +886,41 @@ config_reset(const config_mgr_t *mgr, void *options,
|
||||
void
|
||||
config_free_(const config_mgr_t *mgr, void *options)
|
||||
{
|
||||
const config_format_t *fmt = mgr->toplevel;
|
||||
|
||||
if (!options)
|
||||
return;
|
||||
|
||||
tor_assert(fmt);
|
||||
tor_assert(mgr);
|
||||
|
||||
if (mgr->toplevel->clear_fn) {
|
||||
mgr->toplevel->clear_fn(mgr, options);
|
||||
}
|
||||
config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, options);
|
||||
if (suitep) {
|
||||
tor_assert(smartlist_len((*suitep)->configs) ==
|
||||
smartlist_len(mgr->subconfigs));
|
||||
SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) {
|
||||
void *obj = smartlist_get((*suitep)->configs, fmt_sl_idx);
|
||||
if (fmt->clear_fn) {
|
||||
fmt->clear_fn(mgr, obj);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(fmt);
|
||||
}
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(mgr->all_vars, const managed_var_t *, mv) {
|
||||
config_clear(mgr, options, mv);
|
||||
} SMARTLIST_FOREACH_END(mv);
|
||||
|
||||
if (fmt->extra) {
|
||||
config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->offset);
|
||||
if (mgr->toplevel->extra) {
|
||||
config_line_t **linep = STRUCT_VAR_P(options,
|
||||
mgr->toplevel->extra->offset);
|
||||
config_free_lines(*linep);
|
||||
*linep = NULL;
|
||||
}
|
||||
|
||||
config_suite_t **suitep = config_mgr_get_suite_ptr(mgr, options);
|
||||
if (suitep)
|
||||
if (suitep) {
|
||||
SMARTLIST_FOREACH((*suitep)->configs, void *, obj, tor_free(obj));
|
||||
config_suite_free(*suitep);
|
||||
}
|
||||
|
||||
tor_free(options);
|
||||
}
|
||||
|
@ -76,6 +76,8 @@ typedef struct config_mgr_t config_mgr_t;
|
||||
|
||||
config_mgr_t *config_mgr_new(const config_format_t *toplevel_fmt);
|
||||
void config_mgr_free_(config_mgr_t *mgr);
|
||||
int config_mgr_add_format(config_mgr_t *mgr,
|
||||
const config_format_t *fmt);
|
||||
void config_mgr_freeze(config_mgr_t *mgr);
|
||||
#define config_mgr_free(mgr) \
|
||||
FREE_AND_NULL(config_mgr_t, config_mgr_free_, (mgr))
|
||||
|
Loading…
Reference in New Issue
Block a user