blob: cf1ac16d14212fb7fde49230c25c73c521603e0a [file] [log] [blame]
Radek Krejcie7b95092019-05-15 11:03:07 +02001/**
2 * @file tree.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libyang geenric macros and functions to work with YANG schema or data trees.
5 *
6 * Copyright (c) 2019 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#ifndef LY_TREE_H_
16#define LY_TREE_H_
17
Radek Krejci7eb54ba2020-05-18 16:30:04 +020018#include "inttypes.h"
19
Michal Vasko9f96a052020-03-10 09:41:45 +010020#include "tree_data.h"
21
Radek Krejcie7b95092019-05-15 11:03:07 +020022#ifdef __cplusplus
23extern "C" {
24#endif
25
26/**
Radek Krejci2ff0d572020-05-21 15:27:28 +020027 * @defgroup trees Trees
28 *
29 * Generic macros, functions, etc. to work with both [schema](@ref schematree) and [data](@ref datatree) trees.
30 *
31 * @{
32 */
33
34/**
Radek Krejcic4fa0292020-05-14 10:54:49 +020035 * @brief Type (i.e. size) of the [sized array](@ref sizedarrays)'s size counter.
Radek Krejci7eb54ba2020-05-18 16:30:04 +020036 *
Michal Vaskofd69e1d2020-07-03 11:57:17 +020037 * To print the value via a print format, use LY_PRI_ARRAY_COUNT_TYPE specifier.
Radek Krejcic4fa0292020-05-14 10:54:49 +020038 */
Michal Vaskofd69e1d2020-07-03 11:57:17 +020039#define LY_ARRAY_COUNT_TYPE uint64_t
Radek Krejcic4fa0292020-05-14 10:54:49 +020040
41/**
Radek Krejci7eb54ba2020-05-18 16:30:04 +020042 * @brief Printing format specifier macro for LY_ARRAY_SIZE_TYPE values.
43 */
Michal Vaskofd69e1d2020-07-03 11:57:17 +020044#define LY_PRI_ARRAY_COUNT_TYPE PRIu64
Radek Krejci7eb54ba2020-05-18 16:30:04 +020045
46/**
Radek Krejcie7b95092019-05-15 11:03:07 +020047 * @brief Macro selector for other LY_ARRAY_* macros, do not use directly!
48 */
49#define LY_ARRAY_SELECT(_1, _2, NAME, ...) NAME
50
51/**
52 * @brief Helper macro to go through sized-arrays with a pointer iterator.
53 *
54 * Use with opening curly bracket (`{`).
55 *
56 * @param[in] ARRAY Array to go through
57 * @param[in] TYPE Type of the records in the ARRAY
58 * @param[out] ITER Iterating pointer to the item being processed in each loop
59 */
60#define LY_ARRAY_FOR_ITER(ARRAY, TYPE, ITER) \
61 for (ITER = ARRAY; \
Michal Vaskofd69e1d2020-07-03 11:57:17 +020062 (ARRAY) && ((void*)ITER - (void*)ARRAY)/(sizeof(TYPE)) < (*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
Radek Krejcie7b95092019-05-15 11:03:07 +020063 ITER = (void*)((TYPE*)ITER + 1))
64
65/**
66 * @brief Helper macro to go through sized-arrays with a numeric iterator.
67 *
68 * Use with opening curly bracket (`{`).
69 *
70 * To access an item with the INDEX value, use always LY_ARRAY_INDEX macro!
71 *
72 * @param[in] ARRAY Array to go through
73 * @param[out] INDEX Iterating index of the item being processed in each loop
74 */
75#define LY_ARRAY_FOR_INDEX(ARRAY, INDEX) \
76 for (INDEX = 0; \
Michal Vaskofd69e1d2020-07-03 11:57:17 +020077 ARRAY && INDEX < (*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1)); \
Radek Krejcie7b95092019-05-15 11:03:07 +020078 ++INDEX)
79
80/**
Michal Vaskofd69e1d2020-07-03 11:57:17 +020081 * @brief Get the number of records in the ARRAY.
Radek Krejcie7b95092019-05-15 11:03:07 +020082 *
83 * Does not check if array exists!
84 */
Michal Vaskofd69e1d2020-07-03 11:57:17 +020085#define LY_ARRAY_COUNT(ARRAY) (*((LY_ARRAY_COUNT_TYPE*)(ARRAY) - 1))
Radek Krejcie7b95092019-05-15 11:03:07 +020086
87/**
88 * @brief Sized-array iterator (for-loop).
89 *
90 * Use with opening curly bracket (`{`).
91 *
92 * There are 2 variants:
93 *
94 * LY_ARRAY_FOR(ARRAY, TYPE, ITER)
95 *
96 * Where ARRAY is a sized-array to go through, TYPE is the type of the items in the ARRAY and ITER is a pointer variable
97 * providing the items of the ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_ITER macro
98 *
99 * LY_ARRAY_FOR(ARRAY, INDEX)
100 *
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200101 * The ARRAY is again a sized-array to go through, the INDEX is a variable (LY_ARRAY_COUNT_TYPE) for storing iterating ARRAY's index
Radek Krejcie7b95092019-05-15 11:03:07 +0200102 * to access the items of ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
103 */
104#define LY_ARRAY_FOR(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_FOR_ITER, LY_ARRAY_FOR_INDEX)(ARRAY, __VA_ARGS__)
105
106/**
107 * @brief Macro to iterate via all sibling elements without affecting the list itself
108 *
109 * Works for all types of nodes despite it is data or schema tree, but all the
110 * parameters must be pointers to the same type.
111 *
112 * Use with opening curly bracket (`{`). All parameters must be of the same type.
113 *
114 * @param START Pointer to the starting element.
115 * @param ELEM Iterator.
116 */
117#define LY_LIST_FOR(START, ELEM) \
118 for ((ELEM) = (START); \
119 (ELEM); \
120 (ELEM) = (ELEM)->next)
121
122/**
123 * @brief Macro to iterate via all sibling elements allowing to modify the list itself (e.g. removing elements)
124 *
125 * Use with opening curly bracket (`{`). All parameters must be of the same type.
126 *
127 * @param START Pointer to the starting element.
128 * @param NEXT Temporary storage to allow removing of the current iterator content.
129 * @param ELEM Iterator.
130 */
131#define LY_LIST_FOR_SAFE(START, NEXT, ELEM) \
132 for ((ELEM) = (START); \
133 (ELEM) ? (NEXT = (ELEM)->next, 1) : 0; \
134 (ELEM) = (NEXT))
135
136/**
Michal Vasko4c583e82020-07-17 12:16:14 +0200137 * @brief Macro to iterate via all schema node data instances in data siblings.
138 *
139 * @param START Pointer to the starting sibling. Even if it is not first, all the siblings are searched.
140 * @param SCHEMA Schema node of the searched instances.
141 * @param ELEM Iterator.
142 */
143#define LYD_LIST_FOR_INST(START, SCHEMA, ELEM) \
144 for (lyd_find_sibling_val(START, SCHEMA, NULL, 0, &(ELEM)); \
145 (ELEM) && ((ELEM)->schema == (SCHEMA)); \
146 (ELEM) = (ELEM)->next)
147
148/**
149 * @brief Macro to iterate via all schema node data instances in data siblings allowing to modify the list itself.
150 *
151 * @param START Pointer to the starting sibling. Even if it is not first, all the siblings are searched.
152 * @param SCHEMA Schema node of the searched instances.
153 * @param NEXT Temporary storage to allow removing of the current iterator content.
154 * @param ELEM Iterator.
155 */
156#define LYD_LIST_FOR_INST_SAFE(START, SCHEMA, NEXT, ELEM) \
157 for (lyd_find_sibling_val(START, SCHEMA, NULL, 0, &(ELEM)); \
158 (ELEM) && ((ELEM)->schema == (SCHEMA)) ? ((NEXT) = (ELEM)->next, 1) : 0; \
159 (ELEM) = (NEXT))
160
161/**
Radek Krejcie7b95092019-05-15 11:03:07 +0200162 * @brief YANG built-in types
163 */
164typedef enum
165{
166 LY_TYPE_UNKNOWN = 0, /**< Unknown type */
167 LY_TYPE_BINARY, /**< Any binary data ([RFC 6020 sec 9.8](http://tools.ietf.org/html/rfc6020#section-9.8)) */
168 LY_TYPE_UINT8, /**< 8-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
169 LY_TYPE_UINT16, /**< 16-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
170 LY_TYPE_UINT32, /**< 32-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
171 LY_TYPE_UINT64, /**< 64-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
172 LY_TYPE_STRING, /**< Human-readable string ([RFC 6020 sec 9.4](http://tools.ietf.org/html/rfc6020#section-9.4)) */
173 LY_TYPE_BITS, /**< A set of bits or flags ([RFC 6020 sec 9.7](http://tools.ietf.org/html/rfc6020#section-9.7)) */
174 LY_TYPE_BOOL, /**< "true" or "false" ([RFC 6020 sec 9.5](http://tools.ietf.org/html/rfc6020#section-9.5)) */
175 LY_TYPE_DEC64, /**< 64-bit signed decimal number ([RFC 6020 sec 9.3](http://tools.ietf.org/html/rfc6020#section-9.3))*/
176 LY_TYPE_EMPTY, /**< A leaf that does not have any value ([RFC 6020 sec 9.11](http://tools.ietf.org/html/rfc6020#section-9.11)) */
177 LY_TYPE_ENUM, /**< Enumerated strings ([RFC 6020 sec 9.6](http://tools.ietf.org/html/rfc6020#section-9.6)) */
178 LY_TYPE_IDENT, /**< A reference to an abstract identity ([RFC 6020 sec 9.10](http://tools.ietf.org/html/rfc6020#section-9.10)) */
179 LY_TYPE_INST, /**< References a data tree node ([RFC 6020 sec 9.13](http://tools.ietf.org/html/rfc6020#section-9.13)) */
180 LY_TYPE_LEAFREF, /**< A reference to a leaf instance ([RFC 6020 sec 9.9](http://tools.ietf.org/html/rfc6020#section-9.9))*/
181 LY_TYPE_UNION, /**< Choice of member types ([RFC 6020 sec 9.12](http://tools.ietf.org/html/rfc6020#section-9.12)) */
182 LY_TYPE_INT8, /**< 8-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
183 LY_TYPE_INT16, /**< 16-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
184 LY_TYPE_INT32, /**< 32-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
185 LY_TYPE_INT64, /**< 64-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
186} LY_DATA_TYPE;
187#define LY_DATA_TYPE_COUNT 20 /**< Number of different types */
188
189/**
190 * @brief Stringified YANG built-in data types
191 */
Michal Vasko22df3f02020-08-24 13:29:22 +0200192extern const char *ly_data_type2str[LY_DATA_TYPE_COUNT];
Radek Krejcie7b95092019-05-15 11:03:07 +0200193
Radek Krejci2ff0d572020-05-21 15:27:28 +0200194/** @} trees */
Radek Krejcie7b95092019-05-15 11:03:07 +0200195
196#ifdef __cplusplus
197}
198#endif
199
200#endif /* LY_TREE_H_ */