Radek Krejci | e7b9509 | 2019-05-15 11:03:07 +0200 | [diff] [blame] | 1 | /** |
| 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 Vasko | 9f96a05 | 2020-03-10 09:41:45 +0100 | [diff] [blame^] | 18 | #include "tree_data.h" |
| 19 | |
Radek Krejci | e7b9509 | 2019-05-15 11:03:07 +0200 | [diff] [blame] | 20 | #ifdef __cplusplus |
| 21 | extern "C" { |
| 22 | #endif |
| 23 | |
| 24 | /** |
Radek Krejci | e7b9509 | 2019-05-15 11:03:07 +0200 | [diff] [blame] | 25 | * @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 Vasko | 9f96a05 | 2020-03-10 09:41:45 +0100 | [diff] [blame^] | 122 | * @brief Generic tree node structure. |
| 123 | */ |
| 124 | struct 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 | */ |
| 142 | struct ly_attr { |
| 143 | struct ly_attr *next; |
| 144 | const char *name; |
| 145 | const char *value; |
| 146 | }; |
| 147 | |
| 148 | /** |
Radek Krejci | e7b9509 | 2019-05-15 11:03:07 +0200 | [diff] [blame] | 149 | * @brief YANG built-in types |
| 150 | */ |
| 151 | typedef 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 | */ |
| 179 | extern const char* ly_data_type2str[LY_DATA_TYPE_COUNT]; |
| 180 | |
Radek Krejci | e7b9509 | 2019-05-15 11:03:07 +0200 | [diff] [blame] | 181 | /** @} */ |
| 182 | |
| 183 | #ifdef __cplusplus |
| 184 | } |
| 185 | #endif |
| 186 | |
| 187 | #endif /* LY_TREE_H_ */ |