blob: bf86260c4fa0c8f4bcd5ab7fd0851a32c7010830 [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
Michal Vasko9f96a052020-03-10 09:41:45 +010018#include "tree_data.h"
19
Radek Krejcie7b95092019-05-15 11:03:07 +020020#ifdef __cplusplus
21extern "C" {
22#endif
23
24/**
Radek Krejcie7b95092019-05-15 11:03:07 +020025 * @brief Macro selector for other LY_ARRAY_* macros, do not use directly!
26 */
27#define LY_ARRAY_SELECT(_1, _2, NAME, ...) NAME
28
29/**
30 * @brief Helper macro to go through sized-arrays with a pointer iterator.
31 *
32 * Use with opening curly bracket (`{`).
33 *
34 * @param[in] ARRAY Array to go through
35 * @param[in] TYPE Type of the records in the ARRAY
36 * @param[out] ITER Iterating pointer to the item being processed in each loop
37 */
38#define LY_ARRAY_FOR_ITER(ARRAY, TYPE, ITER) \
39 for (ITER = ARRAY; \
40 (ARRAY) && ((void*)ITER - (void*)ARRAY)/(sizeof(TYPE)) < (*((uint32_t*)(ARRAY) - 1)); \
41 ITER = (void*)((TYPE*)ITER + 1))
42
43/**
44 * @brief Helper macro to go through sized-arrays with a numeric iterator.
45 *
46 * Use with opening curly bracket (`{`).
47 *
48 * To access an item with the INDEX value, use always LY_ARRAY_INDEX macro!
49 *
50 * @param[in] ARRAY Array to go through
51 * @param[out] INDEX Iterating index of the item being processed in each loop
52 */
53#define LY_ARRAY_FOR_INDEX(ARRAY, INDEX) \
54 for (INDEX = 0; \
55 ARRAY && INDEX < (*((uint32_t*)(ARRAY) - 1)); \
56 ++INDEX)
57
58/**
59 * @defgroup schematree Schema Tree
60 * @{
61 *
62 * Data structures and functions to manipulate and access schema tree.
63 */
64
65/**
66 * @brief Get a number of records in the ARRAY.
67 *
68 * Does not check if array exists!
69 */
70#define LY_ARRAY_SIZE(ARRAY) (*((uint32_t*)(ARRAY) - 1))
71
72/**
73 * @brief Sized-array iterator (for-loop).
74 *
75 * Use with opening curly bracket (`{`).
76 *
77 * There are 2 variants:
78 *
79 * LY_ARRAY_FOR(ARRAY, TYPE, ITER)
80 *
81 * 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
82 * providing the items of the ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_ITER macro
83 *
84 * LY_ARRAY_FOR(ARRAY, INDEX)
85 *
86 * The ARRAY is again a sized-array to go through, the INDEX is a variable (unsigned integer) for storing iterating ARRAY's index
87 * to access the items of ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
88 */
89#define LY_ARRAY_FOR(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_FOR_ITER, LY_ARRAY_FOR_INDEX)(ARRAY, __VA_ARGS__)
90
91/**
92 * @brief Macro to iterate via all sibling elements without affecting the list itself
93 *
94 * Works for all types of nodes despite it is data or schema tree, but all the
95 * parameters must be pointers to the same type.
96 *
97 * Use with opening curly bracket (`{`). All parameters must be of the same type.
98 *
99 * @param START Pointer to the starting element.
100 * @param ELEM Iterator.
101 */
102#define LY_LIST_FOR(START, ELEM) \
103 for ((ELEM) = (START); \
104 (ELEM); \
105 (ELEM) = (ELEM)->next)
106
107/**
108 * @brief Macro to iterate via all sibling elements allowing to modify the list itself (e.g. removing elements)
109 *
110 * Use with opening curly bracket (`{`). All parameters must be of the same type.
111 *
112 * @param START Pointer to the starting element.
113 * @param NEXT Temporary storage to allow removing of the current iterator content.
114 * @param ELEM Iterator.
115 */
116#define LY_LIST_FOR_SAFE(START, NEXT, ELEM) \
117 for ((ELEM) = (START); \
118 (ELEM) ? (NEXT = (ELEM)->next, 1) : 0; \
119 (ELEM) = (NEXT))
120
121/**
Michal Vasko9f96a052020-03-10 09:41:45 +0100122 * @brief Generic tree node structure.
123 */
124struct ly_node {
125 LYD_FORMAT format;
126 union {
127 struct {
128 const struct lysc_node *schema;
129 struct lyd_meta *meta;
130 } sch;
131 struct {
132 const char *name;
133 struct ly_attr *attr;
134 } xml;
135 };
136 const char *value;
137};
138
139/**
140 * @brief Generic attribute structure.
141 */
142struct ly_attr {
143 struct ly_attr *next;
144 const char *name;
145 const char *value;
146};
147
148/**
Radek Krejcie7b95092019-05-15 11:03:07 +0200149 * @brief YANG built-in types
150 */
151typedef enum
152{
153 LY_TYPE_UNKNOWN = 0, /**< Unknown type */
154 LY_TYPE_BINARY, /**< Any binary data ([RFC 6020 sec 9.8](http://tools.ietf.org/html/rfc6020#section-9.8)) */
155 LY_TYPE_UINT8, /**< 8-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
156 LY_TYPE_UINT16, /**< 16-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
157 LY_TYPE_UINT32, /**< 32-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
158 LY_TYPE_UINT64, /**< 64-bit unsigned integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
159 LY_TYPE_STRING, /**< Human-readable string ([RFC 6020 sec 9.4](http://tools.ietf.org/html/rfc6020#section-9.4)) */
160 LY_TYPE_BITS, /**< A set of bits or flags ([RFC 6020 sec 9.7](http://tools.ietf.org/html/rfc6020#section-9.7)) */
161 LY_TYPE_BOOL, /**< "true" or "false" ([RFC 6020 sec 9.5](http://tools.ietf.org/html/rfc6020#section-9.5)) */
162 LY_TYPE_DEC64, /**< 64-bit signed decimal number ([RFC 6020 sec 9.3](http://tools.ietf.org/html/rfc6020#section-9.3))*/
163 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)) */
164 LY_TYPE_ENUM, /**< Enumerated strings ([RFC 6020 sec 9.6](http://tools.ietf.org/html/rfc6020#section-9.6)) */
165 LY_TYPE_IDENT, /**< A reference to an abstract identity ([RFC 6020 sec 9.10](http://tools.ietf.org/html/rfc6020#section-9.10)) */
166 LY_TYPE_INST, /**< References a data tree node ([RFC 6020 sec 9.13](http://tools.ietf.org/html/rfc6020#section-9.13)) */
167 LY_TYPE_LEAFREF, /**< A reference to a leaf instance ([RFC 6020 sec 9.9](http://tools.ietf.org/html/rfc6020#section-9.9))*/
168 LY_TYPE_UNION, /**< Choice of member types ([RFC 6020 sec 9.12](http://tools.ietf.org/html/rfc6020#section-9.12)) */
169 LY_TYPE_INT8, /**< 8-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
170 LY_TYPE_INT16, /**< 16-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
171 LY_TYPE_INT32, /**< 32-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
172 LY_TYPE_INT64, /**< 64-bit signed integer ([RFC 6020 sec 9.2](http://tools.ietf.org/html/rfc6020#section-9.2)) */
173} LY_DATA_TYPE;
174#define LY_DATA_TYPE_COUNT 20 /**< Number of different types */
175
176/**
177 * @brief Stringified YANG built-in data types
178 */
179extern const char* ly_data_type2str[LY_DATA_TYPE_COUNT];
180
Radek Krejcie7b95092019-05-15 11:03:07 +0200181/** @} */
182
183#ifdef __cplusplus
184}
185#endif
186
187#endif /* LY_TREE_H_ */