save
[protos/libecoli.git] / lib / ecoli_config.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #ifndef ECOLI_CONFIG_
6 #define ECOLI_CONFIG_
7
8 #include <stdbool.h>
9 #include <stdint.h>
10
11 struct ec_config;
12 struct ec_keyval;
13
14 /**
15  * The type identifier for a config value.
16  */
17 enum ec_config_type {
18         EC_CONFIG_TYPE_NONE = 0,
19         EC_CONFIG_TYPE_BOOL,
20         EC_CONFIG_TYPE_INT64,
21         EC_CONFIG_TYPE_UINT64,
22         EC_CONFIG_TYPE_STRING,
23         EC_CONFIG_TYPE_NODE,
24         EC_CONFIG_TYPE_LIST,
25         EC_CONFIG_TYPE_DICT,
26 };
27
28 /**
29  * Structure describing the format of a configuration value.
30  *
31  * This structure is used in a const array which is referenced by a
32  * struct ec_config. Each entry of the array represents a key/value
33  * storage of the configuration dictionary.
34  */
35 struct ec_config_schema {
36         const char *key;          /**< The key string (NULL for list elts). */
37         const char *desc;         /**< A description of the value. */
38         enum ec_config_type type; /**< Type of the value */
39
40         /** If type is dict or list, the schema of the dict or list
41          * elements. Else must be NULL. */
42         const struct ec_config_schema *subschema;
43
44         /** The subschema array len in case of dict (> 0) or list (set
45          * to 1). Else must be 0. */
46         size_t subschema_len;
47
48 };
49
50 TAILQ_HEAD(ec_config_list, ec_config);
51
52 /**
53  * Structure storing data.
54  */
55 struct ec_config {
56         /** type of value stored in the union */
57         enum ec_config_type type;
58
59         union {
60                 bool boolean;
61                 int64_t i64;
62                 uint64_t u64;
63                 char *string;
64                 struct ec_node *node;
65                 struct ec_keyval *dict;
66                 struct ec_config_list list;
67         };
68
69         /**
70          * Valid if type is list.
71          */
72         TAILQ_ENTRY(ec_config) next;
73
74         /** Associated schema. Can be set if type is dict. */
75         const struct ec_config_schema *schema;
76         size_t schema_len;           /**< Schema length. */
77 };
78
79 /* schema */
80
81 int ec_config_schema_validate(const struct ec_config_schema *schema,
82                         size_t schema_len);
83
84 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema,
85                         size_t schema_len);
86
87
88 /* config */
89
90 struct ec_config *ec_config_bool(bool boolean);
91 struct ec_config *ec_config_i64(int64_t i64);
92 struct ec_config *ec_config_u64(uint64_t u64);
93 /* duplicate string */
94 struct ec_config *ec_config_string(const char *string);
95 /* "consume" the node */
96 struct ec_config *ec_config_node(struct ec_node *node);
97 /* "consume" the dict */
98 struct ec_config *ec_config_dict(void);
99 struct ec_config *ec_config_list(void);
100
101 int ec_config_add(struct ec_config *list, struct ec_config *value);
102
103 int ec_config_set_schema(struct ec_config *dict,
104                         const struct ec_config_schema *schema,
105                         size_t schema_len);
106
107 void ec_config_free(struct ec_config *config);
108
109 int ec_config_validate(const struct ec_config *dict);
110
111 /* value is consumed */
112 int ec_config_set(struct ec_config *dict, const char *key,
113                 struct ec_config *value);
114
115 /**
116  * Compare two configurations.
117  */
118 int ec_config_cmp(const struct ec_config *config1,
119                 const struct ec_config *config2);
120
121 /**
122  * Get configuration value.
123  */
124 const struct ec_config *ec_config_get(const struct ec_config *config,
125                                 const char *key);
126
127 /* */
128
129 const struct ec_config_schema *
130 ec_config_schema_lookup(const struct ec_config_schema *schema,
131                         size_t schema_len, const char *key,
132                         enum ec_config_type type);
133
134 void ec_config_free(struct ec_config *value);
135
136 int ec_config_cmp(const struct ec_config *value1,
137                 const struct ec_config *value2);
138
139 char *ec_config_str(const struct ec_config *value);
140
141 void ec_config_dump(FILE *out, const struct ec_config *config);
142
143 #endif