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