#ifndef ECOLI_CONFIG_
#define ECOLI_CONFIG_
+#include <sys/queue.h>
#include <stdbool.h>
#include <stdint.h>
+#include <stdio.h>
+
+#ifndef EC_COUNT_OF //XXX
+#define EC_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \
+ ((size_t)(!(sizeof(x) % sizeof(0[x])))))
+#endif
struct ec_config;
struct ec_keyval;
/** 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);
* Next in list, only valid if type is list.
*/
TAILQ_ENTRY(ec_config) next;
-
- /** Associated schema. Only valid if type is dict. */
- const struct ec_config_schema *schema;
- size_t schema_len; /**< Schema length. */
};
/* schema */
* Validate a configuration schema array.
*
* @param schema
- * Pointer to the first element of the schema array.
- * @param schema_len
- * Length of the schema array.
+ * Pointer to the first element of the schema array. The array
+ * must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
* @return
* 0 if the schema is valid, or -1 on error (errno is set).
*/
-int ec_config_schema_validate(const struct ec_config_schema *schema,
- size_t schema_len);
+int ec_config_schema_validate(const struct ec_config_schema *schema);
/**
* Dump a configuration schema array.
* @param out
* Output stream on which the dump will be sent.
* @param schema
- * Pointer to the first element of the schema array.
- * @param schema_len
- * Length of the schema array.
+ * Pointer to the first element of the schema array. The array
+ * must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
+ */
+void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema);
+
+/**
+ * Find a schema entry matching the key.
+ *
+ * Browse the schema array and lookup for the given key.
+ *
+ * @param schema
+ * Pointer to the first element of the schema array. The array
+ * must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
+ * @return
+ * The schema entry if it matches a key, or NULL if not found.
*/
-void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema,
- size_t schema_len);
+const struct ec_config_schema *
+ec_config_schema_lookup(const struct ec_config_schema *schema,
+ const char *key);
+
+/**
+ * Get the type of a schema entry.
+ *
+ * @param schema_elt
+ * Pointer to an element of the schema array.
+ * @return
+ * The type of the schema entry.
+ */
+enum ec_config_type
+ec_config_schema_type(const struct ec_config_schema *schema_elt);
+
+/**
+ * Get the subschema of a schema entry.
+ *
+ * @param schema_elt
+ * Pointer to an element of the schema array.
+ * @return
+ * The subschema if any, or NULL.
+ */
+const struct ec_config_schema *
+ec_config_schema_sub(const struct ec_config_schema *schema_elt);
+
+/**
+ * Check if a key name is reserved in a config dict.
+ *
+ * Some key names are reserved and should not be used in configs.
+ *
+ * @param name
+ * The name of the key to test.
+ * @return
+ * True if the key name is reserved and must not be used, else false.
+ */
+bool ec_config_key_is_reserved(const char *name);
+
+/**
+ * Array of reserved key names.
+ */
+extern const char *ec_config_reserved_keys[];
/* config */
+/**
+ * Get the type of the configuration.
+ *
+ * @param config
+ * The configuration.
+ * @return
+ * The configuration type.
+ */
+enum ec_config_type ec_config_get_type(const struct ec_config *config);
+
/**
* Create a boolean configuration value.
*
/**
* Create a hash table configuration value.
*
- * @param schema
- * Optional pointer to the first element of the schema array. Set
- * it to NULL if no schema should be attached.
- * @param schema_len
- * Length of the schema array. Set to 0 if no schema.
* @return
- * The configuration object containing an empty hash table, or NULL on
+ * A configuration object containing an empty hash table, or NULL on
* error (errno is set).
*/
-struct ec_config *ec_config_dict(const struct ec_config_schema *schema,
- size_t schema_len);
+struct ec_config *ec_config_dict(void);
/**
* Create a list configuration value.
* @param value
* The value configuration to add in the list. The value object
* will be freed when freeing the list object. On error, the
- * value object is freed.
+ * value object is also freed.
* @return
* 0 on success, else -1 (errno is set).
*/
-int ec_config_add(struct ec_config *list, struct ec_config *value);
+int ec_config_list_add(struct ec_config *list, struct ec_config *value);
-void ec_config_free(struct ec_config *config);
+/**
+ * Remove an element from a list.
+ *
+ * The element is freed and should not be accessed.
+ *
+ * @param list
+ * The list configuration.
+ * @param config
+ * The element to remove from the list.
+ * @return
+ * 0 on success, -1 on error (errno is set).
+ */
+int ec_config_list_del(struct ec_config *list, struct ec_config *config);
-int ec_config_validate(const struct ec_config *dict);
+/**
+ * Validate a configuration.
+ *
+ * @param dict
+ * A hash table configuration to validate.
+ * @param schema
+ * Pointer to the first element of the schema array. The array
+ * must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
+ * @return
+ * 0 on success, -1 on error (errno is set).
+ */
+int ec_config_validate(const struct ec_config *dict,
+ const struct ec_config_schema *schema);
-/* value is consumed */
-int ec_config_set(struct ec_config *dict, const char *key,
+/**
+ * Set a value in a hash table configuration
+ *
+ * @param dict
+ * A hash table configuration to validate.
+ * @param key
+ * The key to update.
+ * @param value
+ * The value to set. The value object will be freed when freeing the
+ * dict object. On error, the value object is also freed.
+ * @return
+ * 0 on success, -1 on error (errno is set).
+ */
+int ec_config_dict_set(struct ec_config *dict, const char *key,
struct ec_config *value);
+/**
+ * Remove an element from a hash table configuration.
+ *
+ * The element is freed and should not be accessed.
+ *
+ * @param dict
+ * A hash table configuration to validate.
+ * @param key
+ * The key of the configuration to delete.
+ * @return
+ * 0 on success, -1 on error (errno is set).
+ */
+int ec_config_dict_del(struct ec_config *config, const char *key);
+
/**
* Compare two configurations.
*/
/**
* Get configuration value.
*/
-struct ec_config *ec_config_get(struct ec_config *config,
+struct ec_config *ec_config_dict_get(const struct ec_config *config,
const char *key);
/**
struct ec_config *
ec_config_list_next(struct ec_config *list, struct ec_config *config);
-/**
- * Remove an element from a list.
- *
- * The element is freed and should not be accessed.
- *
- * @param list
- * The list configuration.
- * @param config
- * The element to remove from the list.
- */
-void ec_config_del(struct ec_config *list, struct ec_config *config);
-
/**
* Free a configuration.
*
int ec_config_cmp(const struct ec_config *value1,
const struct ec_config *value2);
+/**
+ * Duplicate a configuration.
+ *
+ * @param config
+ * The configuration to duplicate.
+ * @return
+ * The duplicated configuration, or NULL on error (errno is set).
+ */
+struct ec_config *
+ec_config_dup(const struct ec_config *config);
+
/**
* Dump a configuration.
*