Home | History | Annotate | Line # | Download | only in keama
      1  1.1  christos /*	$NetBSD: data.h,v 1.3 2022/04/03 01:10:59 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.3  christos  * Copyright (C) 2017-2022 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.3  christos  *   PO Box 360
     20  1.3  christos  *   Newmarket, NH 03857 USA
     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