blob: ffd188afdc2041d43f358aaba2e1e077e3e1fd6e [file] [log] [blame]
Radek Krejci5aeea3a2018-09-05 13:29:36 +02001/**
2 * @file tree_schema.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libyang representation of YANG schema trees.
5 *
6 * Copyright (c) 2015 - 2018 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_SCHEMA_H_
16#define LY_TREE_SCHEMA_H_
17
18#include <stdint.h>
19
Radek Krejci70853c52018-10-15 14:46:16 +020020#ifdef __cplusplus
21extern "C" {
22#endif
23
Radek Krejci5aeea3a2018-09-05 13:29:36 +020024/**
25 * @defgroup schematree Schema Tree
26 * @{
27 *
28 * Data structures and functions to manipulate and access schema tree.
29 */
30
Radek Krejci0af5f5d2018-09-07 15:00:30 +020031/**
Radek Krejci5fac3592018-10-12 15:23:45 +020032 * @brief Helper macro to go through 0-terminated arrays
33 *
34 * Use with opening curly bracket '{'.
35 *
36 * @param[in] ARRAY Array to go through
37 * @param[out] ITER Numeric iterator storing available indexes of the ARRAY
38 */
Michal Vasko4f3980b2018-10-15 10:50:48 +020039#define LY_ARRAY_FOR(ARRAY, ITER) for (ITER = 0; (ARRAY) && *((void **)((ARRAY) + ITER)); ++ITER)
Radek Krejci5fac3592018-10-12 15:23:45 +020040
41/**
42 * @brief Macro to iterate via all sibling elements without affecting the list itself
43 *
44 * Works for all types of nodes despite it is data or schema tree, but all the
45 * parameters must be pointers to the same type.
46 *
47 * Use with opening curly bracket '{'. All parameters must be of the same type.
48 *
49 * @param START Pointer to the starting element.
50 * @param ELEM Iterator.
51 */
52#define LY_LIST_FOR(START, ELEM) \
53 for ((ELEM) = (START); \
54 (ELEM); \
55 (ELEM) = (ELEM)->next)
56
57/**
58 * @ingroup datatree
59 * @brief Macro to iterate via all sibling elements allowing to modify the list itself (e.g. removing elements)
60 *
61 * Use with opening curly bracket '{'. All parameters must be of the same type.
62 *
63 * @param START Pointer to the starting element.
64 * @param NEXT Temporary storage to allow removing of the current iterator content.
65 * @param ELEM Iterator.
66 */
67#define LY_LIST_FOR_SAFE(START, NEXT, ELEM) \
68 for ((ELEM) = (START); \
69 (ELEM) ? (NEXT = (ELEM)->next, 1) : 0; \
70 (ELEM) = (NEXT))
71
72/**
Radek Krejci0af5f5d2018-09-07 15:00:30 +020073 * @brief Schema input formats accepted by libyang [parser functions](@ref howtoschemasparsers).
74 */
75typedef enum {
76 LYS_IN_UNKNOWN = 0, /**< unknown format, used as return value in case of error */
77 LYS_IN_YANG = 1, /**< YANG schema input format */
78 LYS_IN_YIN = 2 /**< YIN schema input format */
79} LYS_INFORMAT;
80
81/**
82 * @brief Schema output formats accepted by libyang [printer functions](@ref howtoschemasprinters).
83 */
84typedef enum {
85 LYS_OUT_UNKNOWN = 0, /**< unknown format, used as return value in case of error */
86 LYS_OUT_YANG = 1, /**< YANG schema output format */
87 LYS_OUT_YIN = 2, /**< YIN schema output format */
88 LYS_OUT_TREE, /**< Tree schema output format, for more information see the [printers](@ref howtoschemasprinters) page */
89 LYS_OUT_INFO, /**< Info schema output format, for more information see the [printers](@ref howtoschemasprinters) page */
90 LYS_OUT_JSON, /**< JSON schema output format, reflecting YIN format with conversion of attributes to object's members */
91} LYS_OUTFORMAT;
92
Radek Krejci5aeea3a2018-09-05 13:29:36 +020093#define LY_REV_SIZE 11 /**< revision data string length (including terminating NULL byte) */
94
Michal Vaskob55f6c12018-09-12 11:13:15 +020095#define LYS_UNKNOWN 0x0000 /**< uninitalized unknown statement node */
96#define LYS_CONTAINER 0x0001 /**< container statement node */
97#define LYS_CHOICE 0x0002 /**< choice statement node */
98#define LYS_LEAF 0x0004 /**< leaf statement node */
99#define LYS_LEAFLIST 0x0008 /**< leaf-list statement node */
100#define LYS_LIST 0x0010 /**< list statement node */
101#define LYS_ANYXML 0x0020 /**< anyxml statement node */
102#define LYS_CASE 0x0040 /**< case statement node */
103#define LYS_USES 0x0080 /**< uses statement node */
104#define LYS_ANYDATA 0x0120 /**< anydata statement node, in tests it can be used for both #LYS_ANYXML and #LYS_ANYDATA */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200105
106/**
107 * @brief YANG import-stmt
108 */
109struct lysp_import {
Michal Vaskod5927ca2018-09-07 15:05:32 +0200110 const char *name; /**< name of the module to import (mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200111 const char *prefix; /**< prefix for the data from the imported schema (mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200112 const char *dsc; /**< description */
113 const char *ref; /**< reference */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200114 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200115 char rev[LY_REV_SIZE]; /**< revision-date of the imported module */
116};
117
118/**
119 * @brief YANG include-stmt
120 */
121struct lysp_include {
Michal Vaskod5927ca2018-09-07 15:05:32 +0200122 const char *name; /**< name of the submodule to include (mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200123 const char *dsc; /**< description */
124 const char *ref; /**< reference */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200125 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200126 char rev[LY_REV_SIZE]; /**< revision-date of the included submodule */
127};
128
129/**
130 * @brief YANG extension-stmt
131 */
132struct lysp_ext {
133 const char *name; /**< extension name */
134 const char *argument; /**< argument name, NULL if not specified */
135 const char *dsc; /**< description statement */
136 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200137 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200138 uint16_t flags; /**< LYS_STATUS_* and LYS_YINELEM values (@ref snodeflags) */
139};
140
141/**
142 * @brief Helper structure for generic storage of the extension instances content.
143 */
144struct lysp_stmt {
145 const char *stmt; /**< identifier of the statement */
146 const char *arg; /**< statement's argument */
147 struct lysp_stmt *next; /**< link to the next statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200148 struct lysp_stmt *child; /**< list of the statement's substatements (linked list) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200149};
150
151/**
Michal Vaskod92e42a2018-09-07 08:35:02 +0200152 * @brief Enum of substatements in which extension instances can appear.
153 */
154typedef enum {
155 LYEXT_SUBSTMT_SELF = 0, /**< extension of the structure itself, not substatement's */
156 LYEXT_SUBSTMT_ARGUMENT, /**< extension of the argument statement, can appear in lys_ext */
157 LYEXT_SUBSTMT_BASE, /**< extension of the base statement, can appear (repeatedly) in lys_type and lys_ident */
158 LYEXT_SUBSTMT_BELONGSTO, /**< extension of the belongs-to statement, can appear in lys_submodule */
159 LYEXT_SUBSTMT_CONTACT, /**< extension of the contact statement, can appear in lys_module */
160 LYEXT_SUBSTMT_DEFAULT, /**< extension of the default statement, can appear in lys_node_leaf, lys_node_leaflist,
161 lys_node_choice and lys_deviate */
162 LYEXT_SUBSTMT_DESCRIPTION, /**< extension of the description statement, can appear in lys_module, lys_submodule,
163 lys_node, lys_import, lys_include, lys_ext, lys_feature, lys_tpdf, lys_restr,
164 lys_ident, lys_deviation, lys_type_enum, lys_type_bit, lys_when and lys_revision */
165 LYEXT_SUBSTMT_ERRTAG, /**< extension of the error-app-tag statement, can appear in lys_restr */
166 LYEXT_SUBSTMT_ERRMSG, /**< extension of the error-message statement, can appear in lys_restr */
167 LYEXT_SUBSTMT_KEY, /**< extension of the key statement, can appear in lys_node_list */
168 LYEXT_SUBSTMT_NAMESPACE, /**< extension of the namespace statement, can appear in lys_module */
169 LYEXT_SUBSTMT_ORGANIZATION, /**< extension of the organization statement, can appear in lys_module and lys_submodule */
170 LYEXT_SUBSTMT_PATH, /**< extension of the path statement, can appear in lys_type */
171 LYEXT_SUBSTMT_PREFIX, /**< extension of the prefix statement, can appear in lys_module, lys_submodule (for
172 belongs-to's prefix) and lys_import */
173 LYEXT_SUBSTMT_PRESENCE, /**< extension of the presence statement, can appear in lys_node_container */
174 LYEXT_SUBSTMT_REFERENCE, /**< extension of the reference statement, can appear in lys_module, lys_submodule,
175 lys_node, lys_import, lys_include, lys_revision, lys_tpdf, lys_restr, lys_ident,
176 lys_ext, lys_feature, lys_deviation, lys_type_enum, lys_type_bit and lys_when */
177 LYEXT_SUBSTMT_REVISIONDATE, /**< extension of the revision-date statement, can appear in lys_import and lys_include */
178 LYEXT_SUBSTMT_UNITS, /**< extension of the units statement, can appear in lys_tpdf, lys_node_leaf,
179 lys_node_leaflist and lys_deviate */
180 LYEXT_SUBSTMT_VALUE, /**< extension of the value statement, can appear in lys_type_enum */
181 LYEXT_SUBSTMT_VERSION, /**< extension of the yang-version statement, can appear in lys_module and lys_submodule */
182 LYEXT_SUBSTMT_MODIFIER, /**< extension of the modifier statement, can appear in lys_restr */
183 LYEXT_SUBSTMT_REQINSTANCE, /**< extension of the require-instance statement, can appear in lys_type */
184 LYEXT_SUBSTMT_YINELEM, /**< extension of the yin-element statement, can appear in lys_ext */
185 LYEXT_SUBSTMT_CONFIG, /**< extension of the config statement, can appear in lys_node and lys_deviate */
186 LYEXT_SUBSTMT_MANDATORY, /**< extension of the mandatory statement, can appear in lys_node_leaf, lys_node_choice,
187 lys_node_anydata and lys_deviate */
188 LYEXT_SUBSTMT_ORDEREDBY, /**< extension of the ordered-by statement, can appear in lys_node_list and lys_node_leaflist */
189 LYEXT_SUBSTMT_STATUS, /**< extension of the status statement, can appear in lys_tpdf, lys_node, lys_ident,
190 lys_ext, lys_feature, lys_type_enum and lys_type_bit */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200191 LYEXT_SUBSTMT_FRACDIGITS, /**< extension of the fraction-digits statement, can appear in lys_type */
Michal Vaskod92e42a2018-09-07 08:35:02 +0200192 LYEXT_SUBSTMT_MAX, /**< extension of the max-elements statement, can appear in lys_node_list,
193 lys_node_leaflist and lys_deviate */
194 LYEXT_SUBSTMT_MIN, /**< extension of the min-elements statement, can appear in lys_node_list,
195 lys_node_leaflist and lys_deviate */
196 LYEXT_SUBSTMT_POSITION, /**< extension of the position statement, can appear in lys_type_bit */
197 LYEXT_SUBSTMT_UNIQUE, /**< extension of the unique statement, can appear in lys_node_list and lys_deviate */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200198 LYEXT_SUBSTMT_IFFEATURE, /**< extension of the if-feature statement */
Michal Vaskod92e42a2018-09-07 08:35:02 +0200199} LYEXT_SUBSTMT;
200
201/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200202 * @brief YANG extension instance
203 */
204struct lysp_ext_instance {
205 const char *name; /**< extension identifier, including possible prefix */
206 const char *argument; /**< optional value of the extension's argument */
Michal Vaskod92e42a2018-09-07 08:35:02 +0200207 LYEXT_SUBSTMT insubstmt; /**< value identifying placement of the extension instance */
208 uint32_t insubstmt_index; /**< in case the instance is in a substatement, this identifies
209 the index of that substatement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200210 struct lysp_stmt *child; /**< list of the extension's substatements (linked list) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200211};
212
213/**
214 * @brief YANG feature-stmt
215 */
216struct lysp_feature {
217 const char *name; /**< feature name (mandatory) */
218 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
219 const char *dsc; /**< description statement */
220 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200221 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200222 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values allowed */
223};
224
225/**
226 * @brief YANG identity-stmt
227 */
228struct lysp_ident {
229 const char *name; /**< identity name (mandatory), including possible prefix */
230 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
231 const char **bases; /**< list of base identifiers (NULL-terminated) */
232 const char *dsc; /**< description statement */
233 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200234 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200235 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_ values are allowed */
236};
237
Michal Vasko71e64ca2018-09-07 16:30:29 +0200238/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200239 * @brief Covers restrictions: range, length, pattern, must
240 */
241struct lysp_restr {
242 const char *arg; /**< The restriction expression/value (mandatory);
243 in case of pattern restriction, the first byte has a special meaning:
244 0x06 (ACK) for regular match and 0x15 (NACK) for invert-match */
245 const char *emsg; /**< error-message */
246 const char *eapptag; /**< error-app-tag value */
247 const char *dsc; /**< description */
248 const char *ref; /**< reference */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200249 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200250};
251
252/**
Michal Vasko71e64ca2018-09-07 16:30:29 +0200253 * @brief YANG revision-stmt
254 */
255struct lysp_revision {
256 char rev[LY_REV_SIZE]; /**< revision date (madatory) */
257 const char *dsc; /**< description statement */
258 const char *ref; /**< reference statement */
259 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
260};
261
262/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200263 * @brief Enumeration/Bit value definition
264 */
265struct lysp_type_enum {
266 const char *name; /**< name (mandatory) */
267 const char *dsc; /**< description statement */
268 const char *ref; /**< reference statement */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200269 int64_t value; /**< enum's value or bit's position */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200270 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200271 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200272 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_ and LYS_SET_VALUE
273 values are allowed */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200274};
275
276/**
277 * @brief YANG type-stmt
278 *
279 * Some of the items in the structure may be mandatory, but it is necessary to resolve the type's base type first
280 */
281struct lysp_type {
282 const char *name; /**< name of the type (mandatory) */
283 struct lysp_restr *range; /**< allowed values range - numerical, decimal64 */
284 struct lysp_restr *length; /**< allowed length of the value - string, binary */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200285 struct lysp_restr *patterns; /**< list of patterns (0-terminated) - string */
286 struct lysp_type_enum *enums; /**< list of enum-stmts (0-terminated) - enum */
287 struct lysp_type_enum *bits; /**< list of bit-stmts (0-terminated) - bits */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200288 const char *path; /**< path - leafref */
289 const char **bases; /**< list of base identifiers (NULL-terminated) - identityref */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200290 struct lysp_type *types; /**< list of sub-types (0-terminated) - union */
291 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200292
293 uint8_t fraction_digits; /**< number of fraction digits - decimal64 */
294 uint8_t require_instance; /**< require-instance flag - leafref, instance */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200295 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_SET_REQINST allowed */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200296};
297
298/**
299 * @brief YANG typedef-stmt
300 */
301struct lysp_tpdf {
302 const char *name; /**< name of the newly defined type (mandatory) */
303 const char *units; /**< units of the newly defined type */
304 const char *dflt; /**< default value of the newly defined type */
305 const char *dsc; /**< description statement */
306 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200307 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200308 struct lysp_type type; /**< base type from which the typedef is derived (mandatory) */
309 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values allowed */
310};
311
312/**
313 * @brief YANG grouping-stmt
314 */
315struct lysp_grp {
316 const char *name; /**< grouping name (mandatory) */
317 const char *dsc; /**< description statement */
318 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200319 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
320 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200321 struct lysp_node *data; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200322 struct lysp_action *actions; /**< list of actions (0-terminated) */
323 struct lysp_notif *notifs; /**< list of notifications (0-terminated) */
324 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200325 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values are allowed */
326};
327
328/**
329 * @brief YANG when-stmt
330 */
331struct lysp_when {
332 const char *cond; /**< specified condition (mandatory) */
333 const char *dsc; /**< description statement */
334 const char *ref; /**< reference statement */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200335 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200336};
337
338/**
339 * @brief YANG refine-stmt
340 */
341struct lysp_refine {
342 const char *nodeid; /**< target descendant schema nodeid (mandatory) */
343 const char *dsc; /**< description statement */
344 const char *ref; /**< reference statement */
345 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200346 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200347 const char *presence; /**< presence description */
348 const char **dflts; /**< list of default values (NULL-terminated) */
349 uint32_t min; /**< min-elements constraint */
350 uint32_t max; /**< max-elements constraint, 0 means unbounded */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200351 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200352 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
353};
354
355/**
356 * @brief YANG uses-augment-stmt and augment-stmt
357 */
358struct lysp_augment {
359 const char *nodeid; /**< target schema nodeid (mandatory) - absolute for global augments, descendant for uses's augments */
360 const char *dsc; /**< description statement */
361 const char *ref; /**< reference statement */
362 struct lysp_when *when; /**< when statement */
363 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
364 struct lysp_node *child; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200365 struct lysp_action *actions; /**< list of actions (0-terminated) */
366 struct lysp_notif *notifs; /**< list of notifications (0-terminated) */
367 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200368 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values are allowed */
369};
370
371/**
372 * @defgroup deviatetypes Deviate types
373 * @{
374 */
375#define LYS_DEV_NOT_SUPPORTED 1 /**< deviate type not-supported */
376#define LYS_DEV_ADD 2 /**< deviate type add */
377#define LYS_DEV_DELETE 3 /**< deviate type delete */
378#define LYS_DEV_REPLACE 4 /**< deviate type replace */
379/** @} */
380
381/**
382 * @brief Generic deviate structure to get type and cast to lysp_deviate_* structure
383 */
384struct lysp_deviate {
385 uint8_t mod; /**< [type](@ref deviatetypes) of the deviate modification */
386 struct lysp_deviate *next; /**< next deviate structure in the list */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200387 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200388};
389
390struct lysp_deviate_add {
391 uint8_t mod; /**< [type](@ref deviatetypes) of the deviate modification */
392 struct lysp_deviate *next; /**< next deviate structure in the list */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200393 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
394 const char *units; /**< units of the values */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200395 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200396 const char **uniques; /**< list of uniques specifications (NULL-terminated) */
397 const char **dflts; /**< list of default values (NULL-terminated) */
398 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
399 uint32_t min; /**< min-elements constraint */
400 uint32_t max; /**< max-elements constraint, 0 means unbounded */
401};
402
403struct lysp_deviate_del {
404 uint8_t mod; /**< [type](@ref deviatetypes) of the deviate modification */
405 struct lysp_deviate *next; /**< next deviate structure in the list */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200406 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
407 const char *units; /**< units of the values */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200408 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200409 const char **uniques; /**< list of uniques specifications (NULL-terminated) */
410 const char **dflts; /**< list of default values (NULL-terminated) */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200411 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200412};
413
414struct lysp_deviate_rpl {
415 uint8_t mod; /**< [type](@ref deviatetypes) of the deviate modification */
416 struct lysp_deviate *next; /**< next deviate structure in the list */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200417 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
418 struct lysp_type *type; /**< type of the node */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200419 const char *units; /**< units of the values */
420 const char *dflt; /**< default value */
421 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
422 uint32_t min; /**< min-elements constraint */
423 uint32_t max; /**< max-elements constraint, 0 means unbounded */
424};
425
426struct lysp_deviation {
Michal Vaskob55f6c12018-09-12 11:13:15 +0200427 const char *nodeid; /**< target absolute schema nodeid (mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200428 const char *dsc; /**< description statement */
429 const char *ref; /**< reference statement */
430 struct lysp_deviate* deviates; /**< list of deviate specifications (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200431 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200432};
433
Michal Vaskob55f6c12018-09-12 11:13:15 +0200434#define LYS_CONFIG_W 0x01 /**< config true; */
435#define LYS_CONFIG_R 0x02 /**< config false; */
436#define LYS_CONFIG_MASK 0x03 /**< mask for config value */
437#define LYS_STATUS_CURR 0x08 /**< status current; */
438#define LYS_STATUS_DEPRC 0x10 /**< status deprecated; */
439#define LYS_STATUS_OBSLT 0x20 /**< status obsolete; */
440#define LYS_STATUS_MASK 0x38 /**< mask for status value */
441#define LYS_MAND_TRUE 0x40 /**< mandatory true; applicable only to
442 ::lys_node_choice, ::lys_node_leaf and ::lys_node_anydata */
443#define LYS_MAND_FALSE 0x80 /**< mandatory false; applicable only to
444 ::lys_node_choice, ::lys_node_leaf and ::lys_node_anydata */
445#define LYS_MAND_MASK 0xc0 /**< mask for mandatory values */
446#define LYS_ORDBY_SYSTEM 0x100 /**< ordered-by system lists, applicable only to
447 ::lys_node_list and ::lys_node_leaflist */
448#define LYS_ORDBY_USER 0x200 /**< ordered-by user lists, applicable only to
449 ::lys_node_list and ::lys_node_leaflist */
450#define LYS_ORDBY_MASK 0x300 /**< mask for ordered-by flags */
451#define LYS_FENABLED 0x100 /**< feature enabled flag, applicable only to ::lys_feature */
452#define LYS_AUTOASSIGNED 0x01 /**< value was auto-assigned, applicable only to
453 ::lys_type enum and bits flags */
454#define LYS_YINELEM_TRUE 0x01 /**< yin-element true for extension's argument */
455#define LYS_YINELEM_FALSE 0x02 /**< yin-element false for extension's argument */
456#define LYS_YINELEM_MASK 0x03 /**< mask for yin-element value */
457#define LYS_SET_VALUE 0x01 /**< value attribute is set */
458#define LYS_SET_MAX 0x400 /**< max attribute is set */
459#define LYS_SET_MIN 0x800 /**< min attribute is set */
460#define LYS_SET_REQINST 0x01 /**< require_instance attribute is set */
461
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200462/**
463 * @brief Generic YANG data node
464 */
465struct lysp_node {
466 uint16_t nodetype; /**< type of the node (mandatory) */
467 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
468 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
469 const char *name; /**< node name (mandatory) */
470 const char *dsc; /**< description statement */
471 const char *ref; /**< reference statement */
472 struct lysp_when *when; /**< when statement */
473 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200474 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200475};
476
477/**
478 * @brief Extension structure of the lysp_node for YANG container
479 */
480struct lysp_node_container {
481 uint16_t nodetype; /**< LYS_CONTAINER */
482 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
483 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
484 const char *name; /**< node name (mandatory) */
485 const char *dsc; /**< description statement */
486 const char *ref; /**< reference statement */
487 struct lysp_when *when; /**< when statement */
488 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200489 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200490
491 /* container */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200492 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200493 const char *presence; /**< presence description */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200494 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
495 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200496 struct lysp_node *child; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200497 struct lysp_action *actions; /**< list of actions (0-terminated) */
498 struct lysp_notif *notifs; /**< list of notifications (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200499};
500
501struct lysp_node_leaf {
502 uint16_t nodetype; /**< LYS_LEAF */
503 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
504 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
505 const char *name; /**< node name (mandatory) */
506 const char *dsc; /**< description statement */
507 const char *ref; /**< reference statement */
508 struct lysp_when *when; /**< when statement */
509 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200510 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200511
512 /* leaf */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200513 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200514 struct lysp_type type; /**< type of the leaf node (mandatory) */
515 const char *units; /**< units of the leaf's type */
516 const char *dflt; /**< default value */
517};
518
519struct lysp_node_leaflist {
520 uint16_t nodetype; /**< LYS_LEAFLIST */
521 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
522 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
523 const char *name; /**< node name (mandatory) */
524 const char *dsc; /**< description statement */
525 const char *ref; /**< reference statement */
526 struct lysp_when *when; /**< when statement */
527 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200528 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200529
530 /* leaf-list */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200531 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200532 struct lysp_type type; /**< type of the leaf node (mandatory) */
533 const char *units; /**< units of the leaf's type */
534 const char **dflts; /**< list of default values (NULL-terminated) */
535 uint32_t min; /**< min-elements constraint */
536 uint32_t max; /**< max-elements constraint, 0 means unbounded */
537};
538
539struct lysp_node_list {
540 uint16_t nodetype; /**< LYS_LIST */
541 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
542 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
543 const char *name; /**< node name (mandatory) */
544 const char *dsc; /**< description statement */
545 const char *ref; /**< reference statement */
546 struct lysp_when *when; /**< when statement */
547 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200548 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200549
550 /* list */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200551 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200552 const char *key; /**< keys specification */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200553 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
554 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200555 struct lysp_node *child; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200556 struct lysp_action *actions; /**< list of actions (0-terminated) */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200557 struct lysp_notif *notifs; /**< list of notifications (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200558 const char **uniques; /**< list of uniques specifications (NULL-terminated) */
559 uint32_t min; /**< min-elements constraint */
560 uint32_t max; /**< max-elements constraint, 0 means unbounded */
561};
562
563struct lysp_node_choice {
564 uint16_t nodetype; /**< LYS_CHOICE */
565 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
566 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
567 const char *name; /**< node name (mandatory) */
568 const char *dsc; /**< description statement */
569 const char *ref; /**< reference statement */
570 struct lysp_when *when; /**< when statement */
571 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200572 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200573
574 /* choice */
575 struct lysp_node *child; /**< list of data nodes (linked list) */
576 const char* dflt; /**< default case */
577};
578
579struct lysp_node_case {
580 uint16_t nodetype; /**< LYS_CASE */
581 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
582 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
583 const char *name; /**< node name (mandatory) */
584 const char *dsc; /**< description statement */
585 const char *ref; /**< reference statement */
586 struct lysp_when *when; /**< when statement */
587 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200588 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200589
590 /* case */
591 struct lysp_node *child; /**< list of data nodes (linked list) */
592};
593
594struct lysp_node_anydata {
595 uint16_t nodetype; /**< LYS_ANYXML || LYS_ANYDATA */
596 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
597 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
598 const char *name; /**< node name (mandatory) */
599 const char *dsc; /**< description statement */
600 const char *ref; /**< reference statement */
601 struct lysp_when *when; /**< when statement */
602 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200603 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200604
605 /* anyxml/anydata */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200606 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200607};
608
609struct lysp_node_uses {
Michal Vaskob55f6c12018-09-12 11:13:15 +0200610 uint16_t nodetype; /**< LYS_USES */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200611 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
612 struct lysp_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
613 const char *name; /**< grouping name reference (mandatory) */
614 const char *dsc; /**< description statement */
615 const char *ref; /**< reference statement */
616 struct lysp_when *when; /**< when statement */
617 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200618 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200619
620 /* uses */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200621 struct lysp_refine *refines; /**< list of uses's refines (0-terminated) */
622 struct lysp_augment *augments; /**< list of uses's augment (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200623};
624
625/**
626 * @brief YANG input-stmt and output-stmt
627 */
628struct lysp_action_inout {
Michal Vaskobc2559f2018-09-07 10:17:50 +0200629 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
630 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
631 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200632 struct lysp_node *data; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200633 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200634};
635
636/**
637 * @brief YANG rpc-stmt and action-stmt
638 */
639struct lysp_action {
640 const char *name; /**< grouping name reference (mandatory) */
641 const char *dsc; /**< description statement */
642 const char *ref; /**< reference statement */
643 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200644 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
645 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Michal Vaskob55f6c12018-09-12 11:13:15 +0200646 struct lysp_action_inout *input; /**< RPC's/Action's input */
647 struct lysp_action_inout *output;/**< RPC's/Action's output */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200648 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200649 uint16_t flags; /**< [schema node flags](@ref snodeflags) */
650};
651
652/**
653 * @brief YANG notification-stmt
654 */
655struct lysp_notif {
656 const char *name; /**< grouping name reference (mandatory) */
657 const char *dsc; /**< description statement */
658 const char *ref; /**< reference statement */
659 const char **iffeatures; /**< list of if-feature expressions (NULL-terminated) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200660 struct lysp_restr *musts; /**< list of must restrictions (0-terminated) */
661 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
662 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200663 struct lysp_node *data; /**< list of data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200664 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200665 uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values are allowed */
666};
667
668/**
Radek Krejcif0fceb62018-09-05 14:58:45 +0200669 * @brief supported YANG schema version values
670 */
671typedef enum LYS_VERSION {
672 LYS_VERSION_UNDEF = 0, /**< no specific version, YANG 1.0 as default */
673 LYS_VERSION_1_0 = 1, /**< YANG 1.0 */
674 LYS_VERSION_1_1 = 2 /**< YANG 1.1 */
675} LYS_VERSION;
676
677/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200678 * @brief Printable YANG schema tree structure representing YANG module.
679 *
680 * Simple structure corresponding to the YANG format. The schema is only syntactically validated.
681 */
682struct lysp_module {
683 struct ly_ctx *ctx; /**< libyang context of the module (mandatory) */
684 const char *name; /**< name of the module (mandatory) */
685 const char *filepath; /**< path, if the schema was read from a file, NULL in case of reading from memory */
686 union {
687 /* module */
Michal Vaskod5927ca2018-09-07 15:05:32 +0200688 const char *ns; /**< namespace of the module (module - mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200689 /* submodule */
Michal Vaskod5927ca2018-09-07 15:05:32 +0200690 const char *belongsto; /**< belongs to parent module (submodule - mandatory) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200691 };
Michal Vaskod5927ca2018-09-07 15:05:32 +0200692 const char *prefix; /**< module prefix or submodule belongsto prefix of main module (mandatory) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200693 struct lysp_import *imports; /**< list of imported modules (0-terminated) */
694 struct lysp_include *includes; /**< list of included submodules (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200695 const char *org; /**< party/company responsible for the module */
696 const char *contact; /**< contact information for the module */
697 const char *dsc; /**< description of the module */
698 const char *ref; /**< cross-reference for the module */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200699 struct lysp_revision *revs; /**< list of the module revisions (0-terminated), the first revision
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200700 in the list is always the last (newest) revision of the module */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200701 struct lysp_ext *extensions; /**< list of extension statements (0-terminated) */
702 struct lysp_feature *features; /**< list of feature definitions (0-terminated) */
703 struct lysp_ident *identities; /**< list of identities (0-terminated) */
704 struct lysp_tpdf *typedefs; /**< list of typedefs (0-terminated) */
705 struct lysp_grp *groupings; /**< list of groupings (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200706 struct lysp_node *data; /**< list of module's top-level data nodes (linked list) */
Michal Vaskobc2559f2018-09-07 10:17:50 +0200707 struct lysp_augment *augments; /**< list of augments (0-terminated) */
708 struct lysp_action *rpcs; /**< list of RPCs (0-terminated) */
709 struct lysp_notif *notifs; /**< list of notifications (0-terminated) */
710 struct lysp_deviation *deviations; /**< list of deviations (0-terminated) */
711 struct lysp_ext_instance *exts; /**< list of the extension instances (0-terminated) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200712
Radek Krejcif0fceb62018-09-05 14:58:45 +0200713 uint8_t submodule:1; /**< flag to distinguish main modules and submodules */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200714 uint8_t implemented:1; /**< flag if the module is implemented, not just imported */
715 uint8_t latest_revision:1; /**< flag if the module was loaded without specific revision and is
716 the latest revision found */
Radek Krejcif0fceb62018-09-05 14:58:45 +0200717 uint8_t version:4; /**< yang-version (LYS_VERSION values) */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200718};
719
720/**
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200721 * @brief Free the printable YANG schema tree structure.
722 *
723 * @param[in] module Printable YANG schema tree structure to free.
724 */
725void lysp_module_free(struct lysp_module *module);
726
727/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200728 * @brief Compiled YANG schema tree structure representing YANG module.
729 *
730 * Semantically validated YANG schema tree for data tree parsing.
731 * Contains only the necessary information for the data validation.
732 */
733struct lysc_module {
734};
735
736/**
Radek Krejci0af5f5d2018-09-07 15:00:30 +0200737 * @brief Compiled YANG data node
738 */
739struct lysc_node {
740};
741
742/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200743 * @brief Available YANG schema tree structures representing YANG module.
744 */
745struct lys_module {
746 struct lysp_module *parsed; /**< Simply parsed (unresolved) YANG schema tree */
747 struct lysc_module *compiled; /**< Compiled and fully validated YANG schema tree for data parsing */
748};
749
750/** @} */
751
Radek Krejci70853c52018-10-15 14:46:16 +0200752#ifdef __cplusplus
753}
754#endif
755
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200756#endif /* LY_TREE_SCHEMA_H_ */