summaryrefslogtreecommitdiff
path: root/src/settings.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2021-10-01 16:35:08 -0700
committerVito Caputo <vcaputo@pengaru.com>2021-10-01 16:35:08 -0700
commitb686b405c6a22b26e9b8082c92ed91513608bea3 (patch)
tree0000f671501863a8ee9b536ba869221d0f6710f9 /src/settings.c
parentd1da5500261e96efe0ede06fbebb32f0e191f3c1 (diff)
*: librototiller->libtil
Largely mechanical rename of librototiller -> libtil, but introducing a til_ prefix to all librototiller (now libtil) functions and types where a rototiller prefix was absent. This is just a step towards a more libized librototiller, and til is just a nicer to type/read prefix than rototiller_.
Diffstat (limited to 'src/settings.c')
-rw-r--r--src/settings.c391
1 files changed, 0 insertions, 391 deletions
diff --git a/src/settings.c b/src/settings.c
deleted file mode 100644
index e54a690..0000000
--- a/src/settings.c
+++ /dev/null
@@ -1,391 +0,0 @@
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "settings.h"
-#include "util.h"
-
-#ifdef __WIN32__
-char * strndup(const char *s, size_t n)
-{
- size_t len;
- char *buf;
-
- for (len = 0; len < n; len++) {
- if (!s[len])
- break;
- }
-
- buf = calloc(len + 1, sizeof(char));
- if (!buf)
- return NULL;
-
- memcpy(buf, s, len);
-
- return buf;
-}
-#endif
-
-/* Split form of key=value[,key=value...] settings string */
-typedef struct settings_t {
- unsigned num;
- const char **keys;
- const char **values;
-} settings_t;
-
-typedef enum settings_fsm_state_t {
- SETTINGS_FSM_STATE_KEY,
- SETTINGS_FSM_STATE_EQUAL,
- SETTINGS_FSM_STATE_VALUE,
- SETTINGS_FSM_STATE_COMMA,
-} settings_fsm_state_t;
-
-
-static int add_value(settings_t *settings, const char *key, const char *value)
-{
- assert(settings);
-
- settings->num++;
- /* TODO errors */
- settings->keys = realloc(settings->keys, settings->num * sizeof(const char **));
- settings->values = realloc(settings->values, settings->num * sizeof(const char **));
- settings->keys[settings->num - 1] = key;
- settings->values[settings->num - 1] = value;
-
- return 0;
-}
-
-
-/* split settings_string into a data structure */
-settings_t * settings_new(const char *settings_string)
-{
- settings_fsm_state_t state = SETTINGS_FSM_STATE_KEY;
- const char *p, *token;
- settings_t *settings;
-
- settings = calloc(1, sizeof(settings_t));
- if (!settings)
- return NULL;
-
- if (!settings_string)
- return settings;
-
- /* TODO: unescaping? */
- for (token = p = settings_string; ;p++) {
-
- switch (state) {
- case SETTINGS_FSM_STATE_COMMA:
- token = p;
- state = SETTINGS_FSM_STATE_KEY;
- break;
-
- case SETTINGS_FSM_STATE_KEY:
- if (*p == '=' || *p == ',' || *p == '\0') {
- add_value(settings, strndup(token, p - token), NULL);
-
- if (*p == '=')
- state = SETTINGS_FSM_STATE_EQUAL;
- else if (*p == ',')
- state = SETTINGS_FSM_STATE_COMMA;
- }
- break;
-
- case SETTINGS_FSM_STATE_EQUAL:
- token = p;
- state = SETTINGS_FSM_STATE_VALUE;
- break;
-
- case SETTINGS_FSM_STATE_VALUE:
- if (*p == ',' || *p == '\0') {
- settings->values[settings->num - 1] = strndup(token, p - token);
- state = SETTINGS_FSM_STATE_COMMA;
- }
- break;
-
- default:
- assert(0);
- }
-
- if (*p == '\0')
- break;
- }
-
- /* FIXME: this should probably never leave a value or key entry NULL */
-
- return settings;
-}
-
-
-/* free structure attained via settings_new() */
-settings_t * settings_free(settings_t *settings)
-{
-
- if (settings) {
- for (unsigned i = 0; i < settings->num; i++) {
- free((void *)settings->keys[i]);
- free((void *)settings->values[i]);
- }
-
- free((void *)settings->keys);
- free((void *)settings->values);
- free(settings);
- }
-
- return NULL;
-}
-
-
-/* find key= in settings, return dup of value side or NULL if missing */
-const char * settings_get_value(const settings_t *settings, const char *key)
-{
- int i;
-
- assert(settings);
- assert(key);
-
- for (i = 0; i < settings->num; i++) {
- if (!strcmp(key, settings->keys[i]))
- return settings->values[i];
- }
-
- return NULL;
-}
-
-
-/* return positional key from settings */
-const char * settings_get_key(const settings_t *settings, unsigned pos)
-{
- assert(settings);
-
- if (pos < settings->num)
- return settings->keys[pos];
-
- return NULL;
-}
-
-
-/* add key=value to the settings,
- * or just key if value is NULL.
- */
-/* returns < 0 on error */
-int settings_add_value(settings_t *settings, const char *key, const char *value)
-{
- assert(settings);
- assert(key);
-
- return add_value(settings, strdup(key), value ? strdup(value) : NULL);
-}
-
-
-/* apply the supplied setting description generators to the supplied settings */
-/* returns 0 when input settings are complete */
-/* returns 1 when input settings are incomplete, storing the next setting's description needed in *next_setting */
-/* returns -errno on error */
-int settings_apply_desc_generators(const settings_t *settings, const setting_desc_generator_t generators[], unsigned n_generators, void *setup_context, setting_desc_t **next_setting)
-{
- unsigned i;
- setting_desc_t *next;
-
- assert(settings);
- assert(generators);
- assert(n_generators > 0);
- assert(next_setting);
-
- for (i = 0; i < n_generators; i++) {
- const setting_desc_generator_t *g = &generators[i];
- const char *value;
- setting_desc_t *desc;
- int r;
-
- r = g->func(setup_context, &desc);
- if (r < 0)
- return r;
-
- assert(desc);
-
- value = settings_get_value(settings, g->key);
- if (value) {
- int r;
-
- r = setting_desc_check(desc, value);
- setting_desc_free(desc);
- if (r < 0)
- return r;
-
- if (g->value_ptr)
- *g->value_ptr = value;
-
- continue;
- }
-
- *next_setting = desc;
-
- return 1;
- }
-
- return 0;
-}
-
-
-/* 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 setting_desc_clone(const setting_desc_t *desc, setting_desc_t **res_desc)
-{
- setting_desc_t *d;
-
- assert(desc);
- assert(desc->name);
- assert(desc->preferred); /* XXX: require a preferred default? */
- assert(!desc->annotations || desc->values);
- assert(res_desc);
-
- d = calloc(1, sizeof(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 (desc->values) {
- unsigned i;
-
- for (i = 0; desc->values[i]; i++);
-
- d->values = calloc(i + 1, sizeof(*desc->values));
-
- if (desc->annotations)
- d->annotations = calloc(i + 1, sizeof(*desc->annotations));
-
- for (i = 0; desc->values[i]; i++) {
- d->values[i] = strdup(desc->values[i]);
-
- if (desc->annotations) {
- assert(desc->annotations[i]);
- d->annotations[i] = strdup(desc->annotations[i]);
- }
- }
- }
-
- d->random = desc->random;
-
- /* TODO: handle allocation errors above... */
- *res_desc = d;
-
- return 0;
-}
-
-
-setting_desc_t * setting_desc_free(setting_desc_t *desc)
-{
- if (desc) {
- free((void *)desc->name);
- free((void *)desc->key);
- free((void *)desc->regex);
- free((void *)desc->preferred);
-
- if (desc->values) {
- for (unsigned i = 0; desc->values[i]; i++) {
- free((void *)desc->values[i]);
-
- if (desc->annotations)
- free((void *)desc->annotations[i]);
- }
-
- free((void *)desc->values);
- free((void *)desc->annotations);
- }
-
- free(desc);
- }
-
- return NULL;
-}
-
-
-int setting_desc_check(const setting_desc_t *desc, const char *value)
-{
- assert(desc);
-
- if (desc->values) {
-
- for (int i = 0; desc->values[i]; i++) {
- if (!strcasecmp(desc->values[i], value))
- return 0;
- }
-
- return -EINVAL;
- }
-
- /* TODO: apply regex check */
-
- return 0;
-}
-
-
-/* wrapper around sprintf for convenient buffer size computation */
-/* supply NULL buf when computing size, size and offset are ignored.
- * supply non-NULL for actual writing into buf of size bytes @ offset.
- * return value is number of bytes (potentially if !buf) written
- */
-static int snpf(char *buf, size_t size, off_t offset, const char *format, ...)
-{
- size_t avail = 0;
- va_list ap;
- int r;
-
- if (buf) {
- assert(size > offset);
-
- avail = size - offset;
- buf += offset;
- }
-
- va_start(ap, format);
- r = vsnprintf(buf, avail, format, ap);
- va_end(ap);
-
- return r;
-}
-
-
-char * settings_as_arg(const settings_t *settings)
-{
- char *buf = NULL;
- size_t off, size;
-
- /* intentionally avoided open_memstream for portability reasons */
- for (;;) {
- unsigned i;
-
- for (i = off = 0; i < settings->num; i++) {
- if (i > 0)
- off += snpf(buf, size, off, ",");
-
- off += snpf(buf, size, off, "%s", settings->keys[i]);
-
- if (settings->values[i])
- off += snpf(buf, size, off, "=%s", settings->values[i]);
- }
-
- if (!buf) {
- size = off + 1;
- buf = calloc(size, sizeof(char));
- if (!buf)
- return NULL;
-
- continue;
- }
-
- break;
- }
-
- return buf;
-}
© All Rights Reserved