1*13df4856Schristos /* $NetBSD: data.h,v 1.3 2022/04/03 01:10:59 christos Exp $ */ 236f889b1Schristos 336f889b1Schristos /* 4*13df4856Schristos * Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC") 536f889b1Schristos * 636f889b1Schristos * Permission to use, copy, modify, and distribute this software for any 736f889b1Schristos * purpose with or without fee is hereby granted, provided that the above 836f889b1Schristos * copyright notice and this permission notice appear in all copies. 936f889b1Schristos * 1036f889b1Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1136f889b1Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1236f889b1Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1336f889b1Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1436f889b1Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1536f889b1Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1636f889b1Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1736f889b1Schristos * 1836f889b1Schristos * Internet Systems Consortium, Inc. 19*13df4856Schristos * PO Box 360 20*13df4856Schristos * Newmarket, NH 03857 USA 2136f889b1Schristos * <info@isc.org> 2236f889b1Schristos * http://www.isc.org/ 2336f889b1Schristos */ 2436f889b1Schristos 2536f889b1Schristos #ifndef DATA_H 2636f889b1Schristos #define DATA_H 2736f889b1Schristos 2836f889b1Schristos #include <stdint.h> 2936f889b1Schristos #include <stdio.h> 3036f889b1Schristos 3136f889b1Schristos /* From FreeBSD sys/queue.h */ 3236f889b1Schristos 3336f889b1Schristos /* 3436f889b1Schristos * Tail queue declarations. 3536f889b1Schristos */ 3636f889b1Schristos #define TAILQ_HEAD(name, type) \ 3736f889b1Schristos struct name { \ 3836f889b1Schristos struct type *tqh_first; /* first element */ \ 3936f889b1Schristos struct type **tqh_last; /* addr of last next element */ \ 4036f889b1Schristos } 4136f889b1Schristos 4236f889b1Schristos #define TAILQ_ENTRY(type) \ 4336f889b1Schristos struct { \ 4436f889b1Schristos struct type *tqe_next; /* next element */ \ 4536f889b1Schristos struct type **tqe_prev; /* address of previous next element */ \ 4636f889b1Schristos } 4736f889b1Schristos 4836f889b1Schristos /* 4936f889b1Schristos * Tail queue functions. 5036f889b1Schristos */ 5136f889b1Schristos #define TAILQ_CONCAT(head1, head2) do { \ 5236f889b1Schristos if (!TAILQ_EMPTY(head2)) { \ 5336f889b1Schristos *(head1)->tqh_last = (head2)->tqh_first; \ 5436f889b1Schristos (head2)->tqh_first->next.tqe_prev = (head1)->tqh_last; \ 5536f889b1Schristos (head1)->tqh_last = (head2)->tqh_last; \ 5636f889b1Schristos TAILQ_INIT((head2)); \ 5736f889b1Schristos } \ 5836f889b1Schristos } while (0) 5936f889b1Schristos 6036f889b1Schristos #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 6136f889b1Schristos 6236f889b1Schristos #define TAILQ_FIRST(head) ((head)->tqh_first) 6336f889b1Schristos 6436f889b1Schristos #define TAILQ_FOREACH(var, head) \ 6536f889b1Schristos for ((var) = TAILQ_FIRST((head)); \ 6636f889b1Schristos (var); \ 6736f889b1Schristos (var) = TAILQ_NEXT((var))) 6836f889b1Schristos 6936f889b1Schristos #define TAILQ_FOREACH_SAFE(var, head, tvar) \ 7036f889b1Schristos for ((var) = TAILQ_FIRST((head)); \ 7136f889b1Schristos (var) && ((tvar) = TAILQ_NEXT((var)), 1); \ 7236f889b1Schristos (var) = (tvar)) 7336f889b1Schristos 7436f889b1Schristos #define TAILQ_INIT(head) do { \ 7536f889b1Schristos TAILQ_FIRST((head)) = NULL; \ 7636f889b1Schristos (head)->tqh_last = &TAILQ_FIRST((head)); \ 7736f889b1Schristos } while (0) 7836f889b1Schristos 7936f889b1Schristos #define TAILQ_INSERT_AFTER(head, listelm, elm) do { \ 8036f889b1Schristos if ((TAILQ_NEXT((elm)) = TAILQ_NEXT((listelm))) != NULL) \ 8136f889b1Schristos TAILQ_NEXT((elm))->next.tqe_prev = \ 8236f889b1Schristos &TAILQ_NEXT((elm)); \ 8336f889b1Schristos else { \ 8436f889b1Schristos (head)->tqh_last = &TAILQ_NEXT((elm)); \ 8536f889b1Schristos } \ 8636f889b1Schristos TAILQ_NEXT((listelm)) = (elm); \ 8736f889b1Schristos (elm)->next.tqe_prev = &TAILQ_NEXT((listelm)); \ 8836f889b1Schristos } while (0) 8936f889b1Schristos 9036f889b1Schristos #define TAILQ_INSERT_BEFORE(listelm, elm) do { \ 9136f889b1Schristos (elm)->next.tqe_prev = (listelm)->next.tqe_prev; \ 9236f889b1Schristos TAILQ_NEXT((elm)) = (listelm); \ 9336f889b1Schristos *(listelm)->next.tqe_prev = (elm); \ 9436f889b1Schristos (listelm)->next.tqe_prev = &TAILQ_NEXT((elm)); \ 9536f889b1Schristos } while (0) 9636f889b1Schristos 9736f889b1Schristos #define TAILQ_INSERT_HEAD(head, elm) do { \ 9836f889b1Schristos if ((TAILQ_NEXT((elm)) = TAILQ_FIRST((head))) != NULL) \ 9936f889b1Schristos TAILQ_FIRST((head))->next.tqe_prev = \ 10036f889b1Schristos &TAILQ_NEXT((elm)); \ 10136f889b1Schristos else \ 10236f889b1Schristos (head)->tqh_last = &TAILQ_NEXT((elm)); \ 10336f889b1Schristos TAILQ_FIRST((head)) = (elm); \ 10436f889b1Schristos (elm)->next.tqe_prev = &TAILQ_FIRST((head)); \ 10536f889b1Schristos } while (0) 10636f889b1Schristos 10736f889b1Schristos #define TAILQ_INSERT_TAIL(head, elm) do { \ 10836f889b1Schristos TAILQ_NEXT((elm)) = NULL; \ 10936f889b1Schristos (elm)->next.tqe_prev = (head)->tqh_last; \ 11036f889b1Schristos *(head)->tqh_last = (elm); \ 11136f889b1Schristos (head)->tqh_last = &TAILQ_NEXT((elm)); \ 11236f889b1Schristos } while (0) 11336f889b1Schristos 11436f889b1Schristos #define TAILQ_LAST(head, headname) \ 11536f889b1Schristos (*(((struct headname *)((head)->tqh_last))->tqh_last)) 11636f889b1Schristos 11736f889b1Schristos #define TAILQ_NEXT(elm) ((elm)->next.tqe_next) 11836f889b1Schristos 11936f889b1Schristos #define TAILQ_PREV(elm, headname) \ 12036f889b1Schristos (*(((struct headname *)((elm)->next.tqe_prev))->tqh_last)) 12136f889b1Schristos 12236f889b1Schristos #define TAILQ_REMOVE(head, elm) do { \ 12336f889b1Schristos if ((TAILQ_NEXT((elm))) != NULL) \ 12436f889b1Schristos TAILQ_NEXT((elm))->next.tqe_prev = \ 12536f889b1Schristos (elm)->next.tqe_prev; \ 12636f889b1Schristos else \ 12736f889b1Schristos (head)->tqh_last = (elm)->next.tqe_prev; \ 12836f889b1Schristos *(elm)->next.tqe_prev = TAILQ_NEXT((elm)); \ 12936f889b1Schristos (elm)->next.tqe_next = (void *)-1; \ 13036f889b1Schristos (elm)->next.tqe_prev = (void *)-1; \ 13136f889b1Schristos } while (0) 13236f889b1Schristos 13336f889b1Schristos #define TAILQ_SWAP(head1, head2, type) do { \ 13436f889b1Schristos struct type *swap_first = (head1)->tqh_first; \ 13536f889b1Schristos struct type **swap_last = (head1)->tqh_last; \ 13636f889b1Schristos (head1)->tqh_first = (head2)->tqh_first; \ 13736f889b1Schristos (head1)->tqh_last = (head2)->tqh_last; \ 13836f889b1Schristos (head2)->tqh_first = swap_first; \ 13936f889b1Schristos (head2)->tqh_last = swap_last; \ 14036f889b1Schristos if ((swap_first = (head1)->tqh_first) != NULL) \ 14136f889b1Schristos swap_first->next.tqe_prev = &(head1)->tqh_first; \ 14236f889b1Schristos else \ 14336f889b1Schristos (head1)->tqh_last = &(head1)->tqh_first; \ 14436f889b1Schristos if ((swap_first = (head2)->tqh_first) != NULL) \ 14536f889b1Schristos swap_first->next.tqe_prev = &(head2)->tqh_first; \ 14636f889b1Schristos else \ 14736f889b1Schristos (head2)->tqh_last = &(head2)->tqh_first; \ 14836f889b1Schristos } while (0) 14936f889b1Schristos 15036f889b1Schristos /* From bind9 lib/isc/include/isc/boolean.h */ 15136f889b1Schristos 15236f889b1Schristos typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t; 15336f889b1Schristos 15436f889b1Schristos #define ISC_FALSE isc_boolean_false 15536f889b1Schristos #define ISC_TRUE isc_boolean_true 15636f889b1Schristos #define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE) 15736f889b1Schristos 15836f889b1Schristos /* From Kea src/lib/cc/data.h */ 15936f889b1Schristos 16036f889b1Schristos struct element; 16136f889b1Schristos 16236f889b1Schristos /* Element types */ 16336f889b1Schristos #define ELEMENT_NONE 0 16436f889b1Schristos #define ELEMENT_INTEGER 1 16536f889b1Schristos #define ELEMENT_REAL 2 16636f889b1Schristos #define ELEMENT_BOOLEAN 3 16736f889b1Schristos #define ELEMENT_NULL 4 16836f889b1Schristos #define ELEMENT_STRING 5 16936f889b1Schristos #define ELEMENT_LIST 6 17036f889b1Schristos #define ELEMENT_MAP 7 17136f889b1Schristos 17236f889b1Schristos /* Element string */ 17336f889b1Schristos struct string { 17436f889b1Schristos size_t length; /* string length */ 17536f889b1Schristos char *content; /* string data */ 17636f889b1Schristos }; 17736f889b1Schristos 17836f889b1Schristos struct string *allocString(void); 17936f889b1Schristos /* In makeString() l == -1 means use strlen(s) */ 18036f889b1Schristos struct string *makeString(int l, const char *s); 18136f889b1Schristos /* format ZlLsSbBfXI6 + h */ 18236f889b1Schristos struct string *makeStringExt(int l, const char *s, char fmt); 18336f889b1Schristos /* format 6lLIsSbBj */ 18436f889b1Schristos struct string *makeStringArray(int l, const char *s, char fmt); 18536f889b1Schristos void appendString(struct string *s, const char *a); 18636f889b1Schristos void concatString(struct string *s, const struct string *a); 18736f889b1Schristos isc_boolean_t eqString(const struct string *s, const struct string *o); 18836f889b1Schristos /* quoting */ 18936f889b1Schristos struct string *quote(struct string *); 19036f889b1Schristos 19136f889b1Schristos /* Comments */ 19236f889b1Schristos struct comment { 19336f889b1Schristos char *line; /* comment line */ 19436f889b1Schristos TAILQ_ENTRY(comment) next; /* next line */ 19536f889b1Schristos }; 19636f889b1Schristos TAILQ_HEAD(comments, comment); 19736f889b1Schristos 19836f889b1Schristos struct comment *createComment(const char *line); 19936f889b1Schristos 20036f889b1Schristos /* Element list */ 20136f889b1Schristos TAILQ_HEAD(list, element); 20236f889b1Schristos 20336f889b1Schristos /* Element map */ 20436f889b1Schristos TAILQ_HEAD(map, element); 20536f889b1Schristos 20636f889b1Schristos /* Element value */ 20736f889b1Schristos union value { 20836f889b1Schristos int64_t int_value; /* integer */ 20936f889b1Schristos double double_value; /* real */ 21036f889b1Schristos isc_boolean_t bool_value; /* boolean */ 21136f889b1Schristos /**/ /* null */ 21236f889b1Schristos struct string string_value; /* string */ 21336f889b1Schristos struct list list_value; /* list */ 21436f889b1Schristos struct map map_value; /* map */ 21536f889b1Schristos }; 21636f889b1Schristos 21736f889b1Schristos /* Element */ 21836f889b1Schristos struct element { 21936f889b1Schristos int type; /* element type (ELEMENT_XXX) */ 22036f889b1Schristos int kind; /* element kind (e.g. ROOT_GROUP) */ 22136f889b1Schristos isc_boolean_t skip; /* skip as not converted */ 22236f889b1Schristos char *key; /* element key (for map) */ 22336f889b1Schristos union value value; /* value */ 22436f889b1Schristos struct comments comments; /* associated comments */ 22536f889b1Schristos TAILQ_ENTRY(element) next; /* next item in list or map chain */ 22636f889b1Schristos }; 22736f889b1Schristos 22836f889b1Schristos /* Value getters */ 22936f889b1Schristos int64_t intValue(const struct element *e); 23036f889b1Schristos double doubleValue(const struct element *e); 23136f889b1Schristos isc_boolean_t boolValue(const struct element *e); 23236f889b1Schristos struct string *stringValue(struct element *e); 23336f889b1Schristos struct list *listValue(struct element *e); 23436f889b1Schristos struct map *mapValue(struct element *e); 23536f889b1Schristos 23636f889b1Schristos /* Creators */ 23736f889b1Schristos struct element *create(void); 23836f889b1Schristos struct element *createInt(int64_t i); 23936f889b1Schristos struct element *createDouble(double d); 24036f889b1Schristos struct element *createBool(isc_boolean_t b); 24136f889b1Schristos struct element *createNull(void); 24236f889b1Schristos struct element *createString(const struct string *s); 24336f889b1Schristos struct element *createList(void); 24436f889b1Schristos struct element *createMap(void); 24536f889b1Schristos 24636f889b1Schristos /* Reset */ 24736f889b1Schristos void resetInt(struct element *e, int64_t i); 24836f889b1Schristos void resetDouble(struct element *e, double d); 24936f889b1Schristos void resetBool(struct element *e, isc_boolean_t b); 25036f889b1Schristos void resetNull(struct element *e); 25136f889b1Schristos void resetString(struct element *e, const struct string *s); 25236f889b1Schristos void resetList(struct element *e); 25336f889b1Schristos void resetMap(struct element *e); 25436f889b1Schristos void resetBy(struct element *e, struct element *o); 25536f889b1Schristos 25636f889b1Schristos /* List functions */ 25736f889b1Schristos struct element *listGet(struct element *l, int i); 25836f889b1Schristos void listSet(struct element *l, struct element *e, int i); 25936f889b1Schristos void listPush(struct element *l, struct element *e); 26036f889b1Schristos void listRemove(struct element *l, int i); 26136f889b1Schristos size_t listSize(const struct element *l); 26236f889b1Schristos void concat(struct element *l, struct element *o); 26336f889b1Schristos 26436f889b1Schristos /* Map functions */ 26536f889b1Schristos struct element *mapGet(struct element *m, const char *k); 26636f889b1Schristos void mapSet(struct element *m, struct element *e, const char *k); 26736f889b1Schristos void mapRemove(struct element *m, const char *k); 26836f889b1Schristos isc_boolean_t mapContains(const struct element *m, const char *k); 26936f889b1Schristos size_t mapSize(const struct element *m); 27036f889b1Schristos void merge(struct element *m, struct element *o); 27136f889b1Schristos 27236f889b1Schristos /* Tools */ 27336f889b1Schristos const char *type2name(int t); 27436f889b1Schristos int name2type(const char *n); 27536f889b1Schristos void print(FILE *fp, const struct element *e, 27636f889b1Schristos isc_boolean_t skip, unsigned indent); 27736f889b1Schristos void printList(FILE *fp, const struct list *l, 27836f889b1Schristos isc_boolean_t skip, unsigned indent); 27936f889b1Schristos void printMap(FILE *fp, const struct map *m, 28036f889b1Schristos isc_boolean_t skip, unsigned indent); 28136f889b1Schristos void printString(FILE *fp, const struct string *s); 28236f889b1Schristos isc_boolean_t skip_to_end(const struct element *e); 28336f889b1Schristos 28436f889b1Schristos struct element *copy(struct element *e); 28536f889b1Schristos struct element *copyList(struct element *l); 28636f889b1Schristos struct element *copyMap(struct element *m); 28736f889b1Schristos 28836f889b1Schristos /* Handles */ 28936f889b1Schristos TAILQ_HEAD(handles, handle); 29036f889b1Schristos 29136f889b1Schristos struct handle { 29236f889b1Schristos unsigned order; /* order */ 29336f889b1Schristos char *key; /* key */ 29436f889b1Schristos struct element *value; /* value */ 29536f889b1Schristos struct handles values; /* children */ 29636f889b1Schristos TAILQ_ENTRY(handle) next; /* siblings */ 29736f889b1Schristos }; 29836f889b1Schristos 29936f889b1Schristos struct handle* mapPop(struct element *); 30036f889b1Schristos void derive(struct handle *, struct handle *); 30136f889b1Schristos 30236f889b1Schristos /* Hexadecimal literals */ 30336f889b1Schristos struct string *hexaValue(struct element *); 30436f889b1Schristos struct element *createHexa(struct string *); 30536f889b1Schristos 30636f889b1Schristos #endif /* DATA_H */ 307