save
[protos/libecoli.git] / lib / ecoli_config.h
diff --git a/lib/ecoli_config.h b/lib/ecoli_config.h
new file mode 100644 (file)
index 0000000..fbeffd6
--- /dev/null
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018, Olivier MATZ <zer0@droids-corp.org>
+ */
+
+#ifndef ECOLI_CONFIG_
+#define ECOLI_CONFIG_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct ec_config;
+struct ec_keyval;
+
+/**
+ * The type identifier for a config value.
+ */
+enum ec_config_type {
+       EC_CONFIG_TYPE_NONE = 0,
+       EC_CONFIG_TYPE_BOOL,
+       EC_CONFIG_TYPE_INT64,
+       EC_CONFIG_TYPE_UINT64,
+       EC_CONFIG_TYPE_STRING,
+       EC_CONFIG_TYPE_NODE,
+       EC_CONFIG_TYPE_LIST,
+       EC_CONFIG_TYPE_DICT,
+};
+
+/**
+ * Structure describing the format of a configuration value.
+ *
+ * This structure is used in a const array which is referenced by a
+ * struct ec_config. Each entry of the array represents a key/value
+ * storage of the configuration dictionary.
+ */
+struct ec_config_schema {
+       const char *key;          /**< The key string (NULL for list elts). */
+       const char *desc;         /**< A description of the value. */
+       enum ec_config_type type; /**< Type of the value */
+
+       /** If type is dict or list, the schema of the dict or list
+        * elements. Else must be NULL. */
+       const struct ec_config_schema *subschema;
+
+       /** The subschema array len in case of dict (> 0) or list (set
+        * to 1). Else must be 0. */
+       size_t subschema_len;
+
+};
+
+TAILQ_HEAD(ec_config_list, ec_config);
+
+/**
+ * Structure storing data.
+ */
+struct ec_config {
+       /** type of value stored in the union */
+       enum ec_config_type type;
+
+       union {
+               bool boolean;
+               int64_t i64;
+               uint64_t u64;
+               char *string;
+               struct ec_node *node;
+               struct ec_keyval *dict;
+               struct ec_config_list list;
+       };
+
+       /**
+        * Valid if type is list.
+        */
+       TAILQ_ENTRY(ec_config) next;
+
+       /** Associated schema. Can be set if type is dict. */
+       const struct ec_config_schema *schema;
+       size_t schema_len;           /**< Schema length. */
+};
+
+/* schema */
+
+int ec_config_schema_validate(const struct ec_config_schema *schema,
+                       size_t schema_len);
+
+void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema,
+                       size_t schema_len);
+
+
+/* config */
+
+struct ec_config *ec_config_bool(bool boolean);
+struct ec_config *ec_config_i64(int64_t i64);
+struct ec_config *ec_config_u64(uint64_t u64);
+/* duplicate string */
+struct ec_config *ec_config_string(const char *string);
+/* "consume" the node */
+struct ec_config *ec_config_node(struct ec_node *node);
+/* "consume" the dict */
+struct ec_config *ec_config_dict(void);
+struct ec_config *ec_config_list(void);
+
+int ec_config_add(struct ec_config *list, struct ec_config *value);
+
+int ec_config_set_schema(struct ec_config *dict,
+                       const struct ec_config_schema *schema,
+                       size_t schema_len);
+
+void ec_config_free(struct ec_config *config);
+
+int ec_config_validate(const struct ec_config *dict);
+
+/* value is consumed */
+int ec_config_set(struct ec_config *dict, const char *key,
+               struct ec_config *value);
+
+/**
+ * Compare two configurations.
+ */
+int ec_config_cmp(const struct ec_config *config1,
+               const struct ec_config *config2);
+
+/**
+ * Get configuration value.
+ */
+const struct ec_config *ec_config_get(const struct ec_config *config,
+                               const char *key);
+
+/* */
+
+const struct ec_config_schema *
+ec_config_schema_lookup(const struct ec_config_schema *schema,
+                       size_t schema_len, const char *key,
+                       enum ec_config_type type);
+
+void ec_config_free(struct ec_config *value);
+
+int ec_config_cmp(const struct ec_config *value1,
+               const struct ec_config *value2);
+
+char *ec_config_str(const struct ec_config *value);
+
+void ec_config_dump(FILE *out, const struct ec_config *config);
+
+#endif