summaryrefslogtreecommitdiff
path: root/src/til_settings.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-05-09 11:43:22 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-05-11 15:18:34 -0700
commit31a0147a720f2f0ef30df41512f41f43734662dd (patch)
treec381b2905eaf5cde93b83b2ee93adc148400b488 /src/til_settings.c
parent1a8abe80dabd6b723897fc507808db30b126b3a4 (diff)
til_settings: introduce til_setting_spec_t concept vs. desc
For recursive settings the individual setting being described needs to get added to a potentially different settings instance than the one being operated on at the top of the current setup_func phase. The settings instance being passed around for a setup_func to operate on is constified, mainly to try ensure modules don't start directly mucking with the settings. They're supposed to just describe what they want next and iterate back and forth, with the front-end creating the settings from the returned descs however is appropriate, eventually building up the settings to completion. But since it's the setup_func that decides which settings instance is appropriate for containing the setting.. at some point it must associate a settings instance with the desc it's producing, one that is going to be necessarily written to. So here I'm just turning the existing til_setting_desc_t to a "spec", unchanged. And introducing a new til_setting_desc_t embedding the spec, accompanied by a non-const til_settings_t* "container". Now what setup_funcs use to express settings are a spec, otherwise identically to before. Instead of cloning a desc to allocate it for returning to the front-end, the desc is created from a spec with the target settings instance passed in. This turns the desc step where we take a constified settings instance and cast it into a non-const a more formal act of going from spec->desc, binding the spec to a specific settings instance. It will also serve to isolate that hacky cast to a til_settings function, and all the accessors of til_setting_desc_t needing to operate on the containing settings instance can just do so. As of this commit, the container pointer is just sitting in the desc_t but isn't being made use of or even assigned yet. This is just to minimize the amount of churn happening in this otherwise mostly mechanical and sprawling commit. There's also been some small changes surrounding the desc generators and plumbing of the settings instance where there previously wasn't any. It's unclear to me if desc generators will stay desc generators or turn into spec generators. For now those are mostly just used by the drm_fb stuff anyways, modules haven't made use of them, so they can stay a little crufty harmlessly for now.
Diffstat (limited to 'src/til_settings.c')
-rw-r--r--src/til_settings.c95
1 files changed, 51 insertions, 44 deletions
diff --git a/src/til_settings.c b/src/til_settings.c
index 84feed4..0328475 100644
--- a/src/til_settings.c
+++ b/src/til_settings.c
@@ -243,23 +243,23 @@ const char * til_settings_get_value_by_idx(const til_settings_t *settings, unsig
* 0 when setting is present and described, res_value and res_setting will be populated w/non-NULL, and res_desc NULL in this case.
* 1 when setting is either present but undescribed, or absent (and undescribed), res_* will be populated but res_{value,setting} may be NULL if absent and simply described.
*/
-int til_settings_get_and_describe_value(const til_settings_t *settings, const til_setting_desc_t *desc, const char **res_value, til_setting_t **res_setting, const til_setting_desc_t **res_desc)
+int til_settings_get_and_describe_value(const til_settings_t *settings, const til_setting_spec_t *spec, const char **res_value, til_setting_t **res_setting, const til_setting_desc_t **res_desc)
{
til_setting_t *setting;
const char *value;
assert(settings);
- assert(desc);
+ assert(spec);
assert(res_value);
- value = til_settings_get_value_by_key(settings, desc->key, &setting);
+ value = til_settings_get_value_by_key(settings, spec->key, &setting);
if (!value || !setting->desc) {
int r;
assert(res_setting);
assert(res_desc);
- r = til_setting_desc_clone(desc, res_desc);
+ r = til_setting_desc_new(settings, spec, res_desc);
if (r < 0)
return r;
@@ -318,11 +318,11 @@ int til_settings_apply_desc_generators(const til_settings_t *settings, const til
const til_setting_desc_t *desc;
int r;
- r = g->func(setup, &desc);
+ r = g->func(settings, setup, &desc);
if (r < 0)
return r;
- r = til_settings_get_and_describe_value(settings, desc, g->value_ptr, res_setting, res_desc);
+ r = til_settings_get_and_describe_value(settings, &desc->spec, g->value_ptr, res_setting, res_desc);
til_setting_desc_free(desc); /* always need to cleanup the desc from g->func(), res_desc gets its own copy */
if (r)
return r;
@@ -338,49 +338,56 @@ int til_settings_apply_desc_generators(const til_settings_t *settings, const til
/* convenience helper for creating a new setting description */
/* copies of everything supplied are made in newly allocated memory, stored @ res_desc */
/* returns < 0 on error */
-int til_setting_desc_clone(const til_setting_desc_t *desc, const til_setting_desc_t **res_desc)
+int til_setting_desc_new(const til_settings_t *settings, const til_setting_spec_t *spec, const til_setting_desc_t **res_desc)
{
til_setting_desc_t *d;
- assert(desc);
- assert(desc->name);
- assert(desc->preferred); /* XXX: require a preferred default? */
- assert(!desc->annotations || desc->values);
+ assert(settings);
+ assert(spec);
+ if (!spec->as_nested_settings) { /* this feels dirty, but sometimes you just need a bare nested settings created */
+ assert(spec->name);
+ assert(spec->preferred); /* XXX: require a preferred default? */
+ }
+ assert((!spec->annotations || spec->values) || spec->as_nested_settings);
assert(res_desc);
d = calloc(1, sizeof(til_setting_desc_t));
if (!d)
return -ENOMEM;
- d->name = strdup(desc->name);
- if (desc->key) /* This is inappropriately subtle, but when key is NULL, the value will be the key, and there will be no value side at all. */
- d->key = strdup(desc->key);
- if (desc->regex)
- d->regex = strdup(desc->regex);
- d->preferred = strdup(desc->preferred);
+ if (spec->name)
+ d->spec.name = strdup(spec->name);
+ if (spec->key) /* This is inappropriately subtle, but when key is NULL, the value will be the key, and there will be no value side at all. */
+ d->spec.key = strdup(spec->key);
+ if (spec->regex)
+ d->spec.regex = strdup(spec->regex);
+
+ if (spec->preferred)
+ d->spec.preferred = strdup(spec->preferred);
- if (desc->values) {
+ if (spec->values) {
unsigned i;
- for (i = 0; desc->values[i]; i++);
+ for (i = 0; spec->values[i]; i++);
- d->values = calloc(i + 1, sizeof(*desc->values));
+ d->spec.values = calloc(i + 1, sizeof(*spec->values));
- if (desc->annotations)
- d->annotations = calloc(i + 1, sizeof(*desc->annotations));
+ if (spec->annotations)
+ d->spec.annotations = calloc(i + 1, sizeof(*spec->annotations));
- for (i = 0; desc->values[i]; i++) {
- d->values[i] = strdup(desc->values[i]);
+ for (i = 0; spec->values[i]; i++) {
+ d->spec.values[i] = strdup(spec->values[i]);
- if (desc->annotations) {
- assert(desc->annotations[i]);
- d->annotations[i] = strdup(desc->annotations[i]);
+ if (spec->annotations) {
+ assert(spec->annotations[i]);
+ d->spec.annotations[i] = strdup(spec->annotations[i]);
}
}
}
- d->random = desc->random;
+ d->spec.random = spec->random;
+ d->spec.as_nested_settings = spec->as_nested_settings;
/* TODO: handle allocation errors above... */
*res_desc = d;
@@ -392,21 +399,21 @@ int til_setting_desc_clone(const til_setting_desc_t *desc, const til_setting_des
til_setting_desc_t * til_setting_desc_free(const til_setting_desc_t *desc)
{
if (desc) {
- free((void *)desc->name);
- free((void *)desc->key);
- free((void *)desc->regex);
- free((void *)desc->preferred);
+ free((void *)desc->spec.name);
+ free((void *)desc->spec.key);
+ free((void *)desc->spec.regex);
+ free((void *)desc->spec.preferred);
- if (desc->values) {
- for (unsigned i = 0; desc->values[i]; i++) {
- free((void *)desc->values[i]);
+ if (desc->spec.values) {
+ for (unsigned i = 0; desc->spec.values[i]; i++) {
+ free((void *)desc->spec.values[i]);
- if (desc->annotations)
- free((void *)desc->annotations[i]);
+ if (desc->spec.annotations)
+ free((void *)desc->spec.annotations[i]);
}
- free((void *)desc->values);
- free((void *)desc->annotations);
+ free((void *)desc->spec.values);
+ free((void *)desc->spec.annotations);
}
free((void *)desc);
@@ -416,15 +423,15 @@ til_setting_desc_t * til_setting_desc_free(const til_setting_desc_t *desc)
}
-int til_setting_desc_check(const til_setting_desc_t *desc, const char *value)
+int til_setting_spec_check(const til_setting_spec_t *spec, const char *value)
{
- assert(desc);
+ assert(spec);
assert(value);
- if (desc->values) {
+ if (spec->values) {
- for (int i = 0; desc->values[i]; i++) {
- if (!strcasecmp(desc->values[i], value))
+ for (int i = 0; spec->values[i]; i++) {
+ if (!strcasecmp(spec->values[i], value))
return 0;
}
© All Rights Reserved