data.h revision 1.1 1 1.1 christos /* $NetBSD: data.h,v 1.1 2020/08/03 21:09:08 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 2017 by Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.1 christos * Permission to use, copy, modify, and distribute this software for any
7 1.1 christos * purpose with or without fee is hereby granted, provided that the above
8 1.1 christos * copyright notice and this permission notice appear in all copies.
9 1.1 christos *
10 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 1.1 christos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 christos *
18 1.1 christos * Internet Systems Consortium, Inc.
19 1.1 christos * 950 Charter Street
20 1.1 christos * Redwood City, CA 94063
21 1.1 christos * <info (at) isc.org>
22 1.1 christos * http://www.isc.org/
23 1.1 christos */
24 1.1 christos
25 1.1 christos #ifndef DATA_H
26 1.1 christos #define DATA_H
27 1.1 christos
28 1.1 christos #include <stdint.h>
29 1.1 christos #include <stdio.h>
30 1.1 christos
31 1.1 christos /* From FreeBSD sys/queue.h */
32 1.1 christos
33 1.1 christos /*
34 1.1 christos * Tail queue declarations.
35 1.1 christos */
36 1.1 christos #define TAILQ_HEAD(name, type) \
37 1.1 christos struct name { \
38 1.1 christos struct type *tqh_first; /* first element */ \
39 1.1 christos struct type **tqh_last; /* addr of last next element */ \
40 1.1 christos }
41 1.1 christos
42 1.1 christos #define TAILQ_ENTRY(type) \
43 1.1 christos struct { \
44 1.1 christos struct type *tqe_next; /* next element */ \
45 1.1 christos struct type **tqe_prev; /* address of previous next element */ \
46 1.1 christos }
47 1.1 christos
48 1.1 christos /*
49 1.1 christos * Tail queue functions.
50 1.1 christos */
51 1.1 christos #define TAILQ_CONCAT(head1, head2) do { \
52 1.1 christos if (!TAILQ_EMPTY(head2)) { \
53 1.1 christos *(head1)->tqh_last = (head2)->tqh_first; \
54 1.1 christos (head2)->tqh_first->next.tqe_prev = (head1)->tqh_last; \
55 1.1 christos (head1)->tqh_last = (head2)->tqh_last; \
56 1.1 christos TAILQ_INIT((head2)); \
57 1.1 christos } \
58 1.1 christos } while (0)
59 1.1 christos
60 1.1 christos #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
61 1.1 christos
62 1.1 christos #define TAILQ_FIRST(head) ((head)->tqh_first)
63 1.1 christos
64 1.1 christos #define TAILQ_FOREACH(var, head) \
65 1.1 christos for ((var) = TAILQ_FIRST((head)); \
66 1.1 christos (var); \
67 1.1 christos (var) = TAILQ_NEXT((var)))
68 1.1 christos
69 1.1 christos #define TAILQ_FOREACH_SAFE(var, head, tvar) \
70 1.1 christos for ((var) = TAILQ_FIRST((head)); \
71 1.1 christos (var) && ((tvar) = TAILQ_NEXT((var)), 1); \
72 1.1 christos (var) = (tvar))
73 1.1 christos
74 1.1 christos #define TAILQ_INIT(head) do { \
75 1.1 christos TAILQ_FIRST((head)) = NULL; \
76 1.1 christos (head)->tqh_last = &TAILQ_FIRST((head)); \
77 1.1 christos } while (0)
78 1.1 christos
79 1.1 christos #define TAILQ_INSERT_AFTER(head, listelm, elm) do { \
80 1.1 christos if ((TAILQ_NEXT((elm)) = TAILQ_NEXT((listelm))) != NULL) \
81 1.1 christos TAILQ_NEXT((elm))->next.tqe_prev = \
82 1.1 christos &TAILQ_NEXT((elm)); \
83 1.1 christos else { \
84 1.1 christos (head)->tqh_last = &TAILQ_NEXT((elm)); \
85 1.1 christos } \
86 1.1 christos TAILQ_NEXT((listelm)) = (elm); \
87 1.1 christos (elm)->next.tqe_prev = &TAILQ_NEXT((listelm)); \
88 1.1 christos } while (0)
89 1.1 christos
90 1.1 christos #define TAILQ_INSERT_BEFORE(listelm, elm) do { \
91 1.1 christos (elm)->next.tqe_prev = (listelm)->next.tqe_prev; \
92 1.1 christos TAILQ_NEXT((elm)) = (listelm); \
93 1.1 christos *(listelm)->next.tqe_prev = (elm); \
94 1.1 christos (listelm)->next.tqe_prev = &TAILQ_NEXT((elm)); \
95 1.1 christos } while (0)
96 1.1 christos
97 1.1 christos #define TAILQ_INSERT_HEAD(head, elm) do { \
98 1.1 christos if ((TAILQ_NEXT((elm)) = TAILQ_FIRST((head))) != NULL) \
99 1.1 christos TAILQ_FIRST((head))->next.tqe_prev = \
100 1.1 christos &TAILQ_NEXT((elm)); \
101 1.1 christos else \
102 1.1 christos (head)->tqh_last = &TAILQ_NEXT((elm)); \
103 1.1 christos TAILQ_FIRST((head)) = (elm); \
104 1.1 christos (elm)->next.tqe_prev = &TAILQ_FIRST((head)); \
105 1.1 christos } while (0)
106 1.1 christos
107 1.1 christos #define TAILQ_INSERT_TAIL(head, elm) do { \
108 1.1 christos TAILQ_NEXT((elm)) = NULL; \
109 1.1 christos (elm)->next.tqe_prev = (head)->tqh_last; \
110 1.1 christos *(head)->tqh_last = (elm); \
111 1.1 christos (head)->tqh_last = &TAILQ_NEXT((elm)); \
112 1.1 christos } while (0)
113 1.1 christos
114 1.1 christos #define TAILQ_LAST(head, headname) \
115 1.1 christos (*(((struct headname *)((head)->tqh_last))->tqh_last))
116 1.1 christos
117 1.1 christos #define TAILQ_NEXT(elm) ((elm)->next.tqe_next)
118 1.1 christos
119 1.1 christos #define TAILQ_PREV(elm, headname) \
120 1.1 christos (*(((struct headname *)((elm)->next.tqe_prev))->tqh_last))
121 1.1 christos
122 1.1 christos #define TAILQ_REMOVE(head, elm) do { \
123 1.1 christos if ((TAILQ_NEXT((elm))) != NULL) \
124 1.1 christos TAILQ_NEXT((elm))->next.tqe_prev = \
125 1.1 christos (elm)->next.tqe_prev; \
126 1.1 christos else \
127 1.1 christos (head)->tqh_last = (elm)->next.tqe_prev; \
128 1.1 christos *(elm)->next.tqe_prev = TAILQ_NEXT((elm)); \
129 1.1 christos (elm)->next.tqe_next = (void *)-1; \
130 1.1 christos (elm)->next.tqe_prev = (void *)-1; \
131 1.1 christos } while (0)
132 1.1 christos
133 1.1 christos #define TAILQ_SWAP(head1, head2, type) do { \
134 1.1 christos struct type *swap_first = (head1)->tqh_first; \
135 1.1 christos struct type **swap_last = (head1)->tqh_last; \
136 1.1 christos (head1)->tqh_first = (head2)->tqh_first; \
137 1.1 christos (head1)->tqh_last = (head2)->tqh_last; \
138 1.1 christos (head2)->tqh_first = swap_first; \
139 1.1 christos (head2)->tqh_last = swap_last; \
140 1.1 christos if ((swap_first = (head1)->tqh_first) != NULL) \
141 1.1 christos swap_first->next.tqe_prev = &(head1)->tqh_first; \
142 1.1 christos else \
143 1.1 christos (head1)->tqh_last = &(head1)->tqh_first; \
144 1.1 christos if ((swap_first = (head2)->tqh_first) != NULL) \
145 1.1 christos swap_first->next.tqe_prev = &(head2)->tqh_first; \
146 1.1 christos else \
147 1.1 christos (head2)->tqh_last = &(head2)->tqh_first; \
148 1.1 christos } while (0)
149 1.1 christos
150 1.1 christos /* From bind9 lib/isc/include/isc/boolean.h */
151 1.1 christos
152 1.1 christos typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t;
153 1.1 christos
154 1.1 christos #define ISC_FALSE isc_boolean_false
155 1.1 christos #define ISC_TRUE isc_boolean_true
156 1.1 christos #define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE)
157 1.1 christos
158 1.1 christos /* From Kea src/lib/cc/data.h */
159 1.1 christos
160 1.1 christos struct element;
161 1.1 christos
162 1.1 christos /* Element types */
163 1.1 christos #define ELEMENT_NONE 0
164 1.1 christos #define ELEMENT_INTEGER 1
165 1.1 christos #define ELEMENT_REAL 2
166 1.1 christos #define ELEMENT_BOOLEAN 3
167 1.1 christos #define ELEMENT_NULL 4
168 1.1 christos #define ELEMENT_STRING 5
169 1.1 christos #define ELEMENT_LIST 6
170 1.1 christos #define ELEMENT_MAP 7
171 1.1 christos
172 1.1 christos /* Element string */
173 1.1 christos struct string {
174 1.1 christos size_t length; /* string length */
175 1.1 christos char *content; /* string data */
176 1.1 christos };
177 1.1 christos
178 1.1 christos struct string *allocString(void);
179 1.1 christos /* In makeString() l == -1 means use strlen(s) */
180 1.1 christos struct string *makeString(int l, const char *s);
181 1.1 christos /* format ZlLsSbBfXI6 + h */
182 1.1 christos struct string *makeStringExt(int l, const char *s, char fmt);
183 1.1 christos /* format 6lLIsSbBj */
184 1.1 christos struct string *makeStringArray(int l, const char *s, char fmt);
185 1.1 christos void appendString(struct string *s, const char *a);
186 1.1 christos void concatString(struct string *s, const struct string *a);
187 1.1 christos isc_boolean_t eqString(const struct string *s, const struct string *o);
188 1.1 christos /* quoting */
189 1.1 christos struct string *quote(struct string *);
190 1.1 christos
191 1.1 christos /* Comments */
192 1.1 christos struct comment {
193 1.1 christos char *line; /* comment line */
194 1.1 christos TAILQ_ENTRY(comment) next; /* next line */
195 1.1 christos };
196 1.1 christos TAILQ_HEAD(comments, comment);
197 1.1 christos
198 1.1 christos struct comment *createComment(const char *line);
199 1.1 christos
200 1.1 christos /* Element list */
201 1.1 christos TAILQ_HEAD(list, element);
202 1.1 christos
203 1.1 christos /* Element map */
204 1.1 christos TAILQ_HEAD(map, element);
205 1.1 christos
206 1.1 christos /* Element value */
207 1.1 christos union value {
208 1.1 christos int64_t int_value; /* integer */
209 1.1 christos double double_value; /* real */
210 1.1 christos isc_boolean_t bool_value; /* boolean */
211 1.1 christos /**/ /* null */
212 1.1 christos struct string string_value; /* string */
213 1.1 christos struct list list_value; /* list */
214 1.1 christos struct map map_value; /* map */
215 1.1 christos };
216 1.1 christos
217 1.1 christos /* Element */
218 1.1 christos struct element {
219 1.1 christos int type; /* element type (ELEMENT_XXX) */
220 1.1 christos int kind; /* element kind (e.g. ROOT_GROUP) */
221 1.1 christos isc_boolean_t skip; /* skip as not converted */
222 1.1 christos char *key; /* element key (for map) */
223 1.1 christos union value value; /* value */
224 1.1 christos struct comments comments; /* associated comments */
225 1.1 christos TAILQ_ENTRY(element) next; /* next item in list or map chain */
226 1.1 christos };
227 1.1 christos
228 1.1 christos /* Value getters */
229 1.1 christos int64_t intValue(const struct element *e);
230 1.1 christos double doubleValue(const struct element *e);
231 1.1 christos isc_boolean_t boolValue(const struct element *e);
232 1.1 christos struct string *stringValue(struct element *e);
233 1.1 christos struct list *listValue(struct element *e);
234 1.1 christos struct map *mapValue(struct element *e);
235 1.1 christos
236 1.1 christos /* Creators */
237 1.1 christos struct element *create(void);
238 1.1 christos struct element *createInt(int64_t i);
239 1.1 christos struct element *createDouble(double d);
240 1.1 christos struct element *createBool(isc_boolean_t b);
241 1.1 christos struct element *createNull(void);
242 1.1 christos struct element *createString(const struct string *s);
243 1.1 christos struct element *createList(void);
244 1.1 christos struct element *createMap(void);
245 1.1 christos
246 1.1 christos /* Reset */
247 1.1 christos void resetInt(struct element *e, int64_t i);
248 1.1 christos void resetDouble(struct element *e, double d);
249 1.1 christos void resetBool(struct element *e, isc_boolean_t b);
250 1.1 christos void resetNull(struct element *e);
251 1.1 christos void resetString(struct element *e, const struct string *s);
252 1.1 christos void resetList(struct element *e);
253 1.1 christos void resetMap(struct element *e);
254 1.1 christos void resetBy(struct element *e, struct element *o);
255 1.1 christos
256 1.1 christos /* List functions */
257 1.1 christos struct element *listGet(struct element *l, int i);
258 1.1 christos void listSet(struct element *l, struct element *e, int i);
259 1.1 christos void listPush(struct element *l, struct element *e);
260 1.1 christos void listRemove(struct element *l, int i);
261 1.1 christos size_t listSize(const struct element *l);
262 1.1 christos void concat(struct element *l, struct element *o);
263 1.1 christos
264 1.1 christos /* Map functions */
265 1.1 christos struct element *mapGet(struct element *m, const char *k);
266 1.1 christos void mapSet(struct element *m, struct element *e, const char *k);
267 1.1 christos void mapRemove(struct element *m, const char *k);
268 1.1 christos isc_boolean_t mapContains(const struct element *m, const char *k);
269 1.1 christos size_t mapSize(const struct element *m);
270 1.1 christos void merge(struct element *m, struct element *o);
271 1.1 christos
272 1.1 christos /* Tools */
273 1.1 christos const char *type2name(int t);
274 1.1 christos int name2type(const char *n);
275 1.1 christos void print(FILE *fp, const struct element *e,
276 1.1 christos isc_boolean_t skip, unsigned indent);
277 1.1 christos void printList(FILE *fp, const struct list *l,
278 1.1 christos isc_boolean_t skip, unsigned indent);
279 1.1 christos void printMap(FILE *fp, const struct map *m,
280 1.1 christos isc_boolean_t skip, unsigned indent);
281 1.1 christos void printString(FILE *fp, const struct string *s);
282 1.1 christos isc_boolean_t skip_to_end(const struct element *e);
283 1.1 christos
284 1.1 christos struct element *copy(struct element *e);
285 1.1 christos struct element *copyList(struct element *l);
286 1.1 christos struct element *copyMap(struct element *m);
287 1.1 christos
288 1.1 christos /* Handles */
289 1.1 christos TAILQ_HEAD(handles, handle);
290 1.1 christos
291 1.1 christos struct handle {
292 1.1 christos unsigned order; /* order */
293 1.1 christos char *key; /* key */
294 1.1 christos struct element *value; /* value */
295 1.1 christos struct handles values; /* children */
296 1.1 christos TAILQ_ENTRY(handle) next; /* siblings */
297 1.1 christos };
298 1.1 christos
299 1.1 christos struct handle* mapPop(struct element *);
300 1.1 christos void derive(struct handle *, struct handle *);
301 1.1 christos
302 1.1 christos /* Hexadecimal literals */
303 1.1 christos struct string *hexaValue(struct element *);
304 1.1 christos struct element *createHexa(struct string *);
305 1.1 christos
306 1.1 christos #endif /* DATA_H */
307