blob: 640b1628aab262fbe4d69d0214e9d21b5635c085 [file] [log] [blame]
Pavol Vican021488a2016-01-25 23:56:12 +01001/**
2 * @file parser_yang.c
3 * @author Pavol Vican
4 * @brief YANG parser for libyang
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of the Company nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 */
21
22#include "parser_yang.h"
23#include "parser_yang_bis.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010024#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010025#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010026
Pavol Vican2a064652016-02-02 22:54:34 +010027static int
28yang_check_string(struct lys_module *module, const char **target, char *what, char *where, char *value, int line)
29{
Pavol Vicanbf805472016-01-26 14:24:56 +010030 if (*target) {
Pavol Vican2a064652016-02-02 22:54:34 +010031 LOGVAL(LYE_TOOMANY, line, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010032 free(value);
33 return 1;
34 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010035 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010036 return 0;
37 }
38}
39
Pavol Vican2a064652016-02-02 22:54:34 +010040int
41yang_read_common(struct lys_module *module, char *value, int type, int line)
42{
Pavol Vican6eb14e82016-02-03 12:27:13 +010043 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010044
45 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010046 case MODULE_KEYWORD:
47 module->name = lydict_insert_zc(module->ctx, value);
48 break;
49 case NAMESPACE_KEYWORD:
50 ret = yang_check_string(module, &module->ns, "namespace", "module", value, line);
51 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010052 case ORGANIZATION_KEYWORD:
53 ret = yang_check_string(module, &module->org, "organization", "module", value, line);
54 break;
55 case CONTACT_KEYWORD:
56 ret = yang_check_string(module, &module->contact, "contact", "module", value, line);
57 break;
Pavol Vican2a064652016-02-02 22:54:34 +010058 }
59
Pavol Vican021488a2016-01-25 23:56:12 +010060 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010061}
62
Pavol Vican2a064652016-02-02 22:54:34 +010063int
64yang_read_prefix(struct lys_module *module, void *save, char *value, int type, int line)
65{
Pavol Vican6eb14e82016-02-03 12:27:13 +010066 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +010067
Pavol Vican6eb14e82016-02-03 12:27:13 +010068 if (lyp_check_identifier(value, LY_IDENT_PREFIX, line, module, NULL)) {
69 free(value);
70 return EXIT_FAILURE;
71 }
Pavol Vicanbf805472016-01-26 14:24:56 +010072 switch (type){
Pavol Vican2a064652016-02-02 22:54:34 +010073 case MODULE_KEYWORD:
74 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, line);
75 break;
Pavol Vican6eb14e82016-02-03 12:27:13 +010076 case IMPORT_KEYWORD:
77 ((struct lys_import *)save)->prefix = lydict_insert_zc(module->ctx, value);
78 break;
Pavol Vican2a064652016-02-02 22:54:34 +010079 }
Pavol Vican6eb14e82016-02-03 12:27:13 +010080
Pavol Vicanbf805472016-01-26 14:24:56 +010081 return ret;
82}
Pavol Vican6eb14e82016-02-03 12:27:13 +010083
84void *
85yang_elem_of_array(void **ptr, uint8_t *act_size, int type, int sizeof_struct)
86{
87 void *retval;
88
89 if (!(*act_size % LY_ARRAY_SIZE) && !(*ptr = ly_realloc(*ptr, (*act_size + LY_ARRAY_SIZE) * sizeof_struct))) {
90 LOGMEM;
91 return NULL;
92 }
93 switch (type) {
94 case IMPORT_KEYWORD:
95 retval = &((struct lys_import *)(*ptr))[*act_size];
96 break;
Pavol Vicanbedff692016-02-03 14:29:17 +010097 case REVISION_KEYWORD:
98 retval = &((struct lys_revision *)(*ptr))[*act_size];
99 break;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100100 }
101 (*act_size)++;
102 memset(retval,0,sizeof_struct);
103 return retval;
104}
105
106int
107yang_fill_import(struct lys_module *module, struct lys_import *imp, char *value, int line)
108{
109 int count, i;
110
111 /* check for circular import, store it if passed */
112 if (!module->ctx->models.parsing) {
113 count = 0;
114 } else {
115 for (count = 0; module->ctx->models.parsing[count]; ++count) {
116 if (value == module->ctx->models.parsing[count]) {
117 LOGERR(LY_EVALID, "Circular import dependency on the module \"%s\".", value);
118 goto error;
119 }
120 }
121 }
122 ++count;
123 module->ctx->models.parsing =
124 ly_realloc(module->ctx->models.parsing, (count + 1) * sizeof *module->ctx->models.parsing);
125 if (!module->ctx->models.parsing) {
126 LOGMEM;
127 goto error;
128 }
129 module->ctx->models.parsing[count - 1] = value;
130 module->ctx->models.parsing[count] = NULL;
131
132 /* try to load the module */
133 imp->module = (struct lys_module *)ly_ctx_get_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
134 if (!imp->module) {
135 /* whether to use a user callback is decided in the function */
136 imp->module = (struct lys_module *)ly_ctx_load_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
137 }
138
139 /* remove the new module name now that its parsing is finished (even if failed) */
140 if (module->ctx->models.parsing[count] || (module->ctx->models.parsing[count - 1] != value)) {
141 LOGINT;
142 }
143 --count;
144 if (count) {
145 module->ctx->models.parsing[count] = NULL;
146 } else {
147 free(module->ctx->models.parsing);
148 module->ctx->models.parsing = NULL;
149 }
150
151 /* check the result */
152 if (!imp->module) {
153 LOGERR(LY_EVALID, "Importing \"%s\" module into \"%s\" failed.", value, module->name);
154 goto error;
155 }
156
157 module->imp_size++;
158
159 /* check duplicities in imported modules */
160 for (i = 0; i < module->imp_size - 1; i++) {
161 if (!strcmp(module->imp[i].module->name, module->imp[module->imp_size - 1].module->name)) {
162 LOGVAL(LYE_SPEC, line, "Importing module \"%s\" repeatedly.", module->imp[i].module->name);
163 goto error;
164 }
165 }
166
167 free(value);
168 return EXIT_SUCCESS;
169
170 error:
171
172 free(value);
173 return EXIT_FAILURE;
174}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100175
176int
177yang_read_description(struct lys_module *module, void *node, char *value, int type, int line)
178{
179 int ret;
180
181 if (!node) {
182 ret = yang_check_string(module, &module->dsc, "description", "module", value, line);
Pavol Vicanbedff692016-02-03 14:29:17 +0100183 } else {
184 switch (type) {
185 case REVISION_KEYWORD:
186 ret = yang_check_string(module, &((struct lys_revision *) node)->dsc, "description", "revision", value, line);
187 break;
Pavol Vicane1354e92016-02-09 14:02:09 +0100188 case FEATURE_KEYWORD:
189 ret = yang_check_string(module, &((struct lys_feature *) node)->dsc, "description", "feature", value, line);
190 break;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100191 case IDENTITY_KEYWORD:
192 ret = yang_check_string(module, &((struct lys_ident *) node)->dsc, "description", "identity", value, line);
193 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100194 case MUST_KEYWORD:
195 ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "must", value, line);
196 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100197 case WHEN_KEYWORD:
198 ret = yang_check_string(module, &((struct lys_when *) node)->dsc, "description", "when" , value, line);
199 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100200 case CONTAINER_KEYWORD:
201 ret = yang_check_string(module, &((struct lys_node_container *) node)->dsc, "description", "container", value, line);
202 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100203 case ANYXML_KEYWORD:
204 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->dsc, "description", "anyxml", value, line);
205 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100206 case CHOICE_KEYWORD:
207 ret = yang_check_string(module, &((struct lys_node_choice *) node)->dsc, "description", "choice", value, line);
208 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100209 case CASE_KEYWORD:
210 ret = yang_check_string(module, &((struct lys_node_case *) node)->dsc, "description", "case", value, line);
211 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100212 case GROUPING_KEYWORD:
213 ret = yang_check_string(module, &((struct lys_node_grp *) node)->dsc, "description", "grouping", value, line);
214 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100215 case LEAF_KEYWORD:
216 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dsc, "description", "leaf", value, line);
217 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100218 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100219 }
220 return ret;
221}
222
223int
224yang_read_reference(struct lys_module *module, void *node, char *value, int type, int line)
225{
226 int ret;
227
228 if (!node) {
229 ret = yang_check_string(module, &module->ref, "reference", "module", value, line);
Pavol Vicanbedff692016-02-03 14:29:17 +0100230 } else {
231 switch (type) {
232 case REVISION_KEYWORD:
233 ret = yang_check_string(module, &((struct lys_revision *) node)->ref, "reference", "revision", value, line);
234 break;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100235 case FEATURE_KEYWORD:
236 ret = yang_check_string(module, &((struct lys_feature *) node)->ref, "reference", "feature", value, line);
237 break;
238 case IDENTITY_KEYWORD:
239 ret = yang_check_string(module, &((struct lys_ident *) node)->ref, "reference", "identity", value, line);
240 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100241 case MUST_KEYWORD:
Pavol Vican235dbd42016-02-10 10:34:19 +0100242 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "must", value, line);
243 break;
244 case WHEN_KEYWORD:
245 ret = yang_check_string(module, &((struct lys_when *) node)->ref, "reference", "when", value, line);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100246 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100247 case CONTAINER_KEYWORD:
248 ret = yang_check_string(module, &((struct lys_node_container *) node)->ref, "reference", "container", value, line);
249 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100250 case ANYXML_KEYWORD:
251 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "anyxml", value, line);
252 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100253 case CHOICE_KEYWORD:
254 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "choice", value, line);
255 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100256 case CASE_KEYWORD:
257 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "case", value, line);
258 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100259 case GROUPING_KEYWORD:
260 ret = yang_check_string(module, &((struct lys_node_grp *) node)->ref, "reference", "grouping", value, line);
261 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100262 case LEAF_KEYWORD:
263 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->ref, "reference", "leaf", value, line);
264 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100265 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100266 }
267 return ret;
268}
Pavol Vicanbedff692016-02-03 14:29:17 +0100269
270void *
271yang_read_revision(struct lys_module *module, char *value)
272{
273 struct lys_revision *retval;
274
Pavol Vican1eeb1992016-02-09 11:10:45 +0100275 retval = &module->rev[module->rev_size];
Pavol Vicanbedff692016-02-03 14:29:17 +0100276
277 /* first member of array is last revision */
Pavol Vican1eeb1992016-02-09 11:10:45 +0100278 if (module->rev_size && strcmp(module->rev[0].date, value) < 0) {
Pavol Vicanbedff692016-02-03 14:29:17 +0100279 memcpy(retval->date, module->rev[0].date, LY_REV_SIZE);
280 memcpy(module->rev[0].date, value, LY_REV_SIZE);
281 retval->dsc = module->rev[0].dsc;
282 retval->ref = module->rev[0].ref;
283 retval = module->rev;
284 retval->dsc = NULL;
285 retval->ref = NULL;
286 } else {
287 memcpy(retval->date, value, LY_REV_SIZE);
288 }
Pavol Vican1eeb1992016-02-09 11:10:45 +0100289 module->rev_size++;
Pavol Vicanbedff692016-02-03 14:29:17 +0100290 free(value);
291 return retval;
292}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100293
294int
295yang_add_elem(struct lys_node_array **node, int *size)
296{
297 if (!*size % LY_ARRAY_SIZE) {
298 if (!(*node = ly_realloc(*node, (*size + LY_ARRAY_SIZE) * sizeof **node))) {
299 LOGMEM;
300 return EXIT_FAILURE;
301 } else {
302 memset(*node+*size,0,LY_ARRAY_SIZE*sizeof **node);
303 }
304 }
305 (*size)++;
306 return EXIT_SUCCESS;
307}
Pavol Vicane1354e92016-02-09 14:02:09 +0100308
309void *
310yang_read_feature(struct lys_module *module, char *value, int line)
311{
312 struct lys_feature *retval;
313
314 /* check uniqueness of feature's names */
315 if (lyp_check_identifier(value, LY_IDENT_FEATURE, line, module, NULL)) {
316 goto error;
317 }
318 retval = &module->features[module->features_size];
319 retval->name = lydict_insert_zc(module->ctx, value);
320 retval->module = module;
321 module->features_size++;
322 return retval;
323
324error:
325 free(value);
326 return NULL;
327}
328
329int
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100330yang_read_if_feature(struct lys_module *module, void *ptr, char *value, struct unres_schema *unres, int type, int line)
Pavol Vicane1354e92016-02-09 14:02:09 +0100331{
332 const char *exp;
333 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100334 struct lys_feature *f;
335 struct lys_node *n;
Pavol Vicane1354e92016-02-09 14:02:09 +0100336
337 if (!(exp = transform_schema2json(module, value, line))) {
338 free(value);
339 return EXIT_FAILURE;
340 }
341 free(value);
342
343 /* hack - store pointer to the parent node for later status check */
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100344 if (type == FEATURE_KEYWORD) {
345 f = (struct lys_feature *) ptr;
346 f->features[f->features_size] = f;
347 ret = unres_schema_add_str(module, unres, &f->features[f->features_size], UNRES_IFFEAT, exp, line);
348 f->features_size++;
349 } else {
350 n = (struct lys_node *) ptr;
351 n->features[n->features_size] = (struct lys_feature *) n;
352 ret = unres_schema_add_str(module, unres, &n->features[n->features_size], UNRES_IFFEAT, exp, line);
353 n->features_size++;
354 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100355
356 lydict_remove(module->ctx, exp);
357 if (ret == -1) {
358
359 return EXIT_FAILURE;
360 }
361 return EXIT_SUCCESS;
362}
363
364static int
365yang_check_flags(uint8_t *flags, uint8_t mask, char *what, char *where, int value, int line)
366{
367 if (*flags & mask) {
368 LOGVAL(LYE_TOOMANY, line, what, where);
369 return EXIT_FAILURE;
370 } else {
Pavol Vican945187f2016-02-11 10:12:33 +0100371 *flags |= value;
Pavol Vicane1354e92016-02-09 14:02:09 +0100372 return EXIT_SUCCESS;
373 }
374}
375
376int
377yang_read_status(void *node, int value, int type, int line)
378{
379 int retval;
380
381 switch (type) {
382 case FEATURE_KEYWORD:
383 retval = yang_check_flags(&((struct lys_feature *) node)->flags, LYS_STATUS_MASK, "status", "feature", value, line);
384 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100385 case IDENTITY_KEYWORD:
Pavol Vicanbbdef532016-02-09 14:52:12 +0100386 retval = yang_check_flags(&((struct lys_ident *) node)->flags, LYS_STATUS_MASK, "status", "identity", value, line);
387 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100388 case CONTAINER_KEYWORD:
389 retval = yang_check_flags(&((struct lys_node_container *) node)->flags, LYS_STATUS_MASK, "status", "container", value, line);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100390 break;
391 case ANYXML_KEYWORD:
392 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "anyxml", value, line);
393 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100394 case CHOICE_KEYWORD:
395 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "choice", value, line);
396 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100397 case CASE_KEYWORD:
398 retval = yang_check_flags(&((struct lys_node_case *) node)->flags, LYS_STATUS_MASK, "status", "case", value, line);
399 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100400 case GROUPING_KEYWORD:
401 retval = yang_check_flags(&((struct lys_node_grp *) node)->flags, LYS_STATUS_MASK, "status", "grouping", value, line);
402 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100403 case LEAF_KEYWORD:
404 retval = yang_check_flags(&((struct lys_node_leaf *) node)->flags, LYS_STATUS_MASK, "status", "leaf", value, line);
405 break;
Pavol Vicane1354e92016-02-09 14:02:09 +0100406 }
407 return retval;
408}
Pavol Vicanbbdef532016-02-09 14:52:12 +0100409
410void *
411yang_read_identity(struct lys_module *module, char *value)
412{
413 struct lys_ident *ret;
414
415 ret = &module->ident[module->ident_size];
416 ret->name = lydict_insert_zc(module->ctx, value);
417 ret->module = module;
418 module->ident_size++;
419 return ret;
420}
421
422int
423yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres, int line)
424{
425 const char *exp;
426
427 if (ident->base) {
428 LOGVAL(LYE_TOOMANY, line, "base", "identity");
429 return EXIT_FAILURE;
430 }
Pavol Vicanbbdef532016-02-09 14:52:12 +0100431 exp = transform_schema2json(module, value, line);
432 free(value);
433 if (!exp) {
434 return EXIT_FAILURE;
435 }
436 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp, line) == -1) {
437 lydict_remove(module->ctx, exp);
438 return EXIT_FAILURE;
439 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100440
441 /* hack - store some address due to detection of unresolved base*/
442 if (!ident->base) {
443 ident->base = (void *)1;
444 }
445
Pavol Vicanbbdef532016-02-09 14:52:12 +0100446 lydict_remove(module->ctx, exp);
447 return EXIT_SUCCESS;
448}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100449
450void *
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100451yang_read_must(struct lys_module *module, struct lys_node *node, char *value, int type, int line)
452{
453 struct lys_restr *retval;
454
455 switch (type) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100456 case CONTAINER_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100457 retval = &((struct lys_node_container *)node)->must[((struct lys_node_container *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100458 break;
459 case ANYXML_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100460 retval = &((struct lys_node_anyxml *)node)->must[((struct lys_node_anyxml *)node)->must_size++];
461 break;
462 case LEAF_KEYWORD:
463 retval = &((struct lys_node_leaf *)node)->must[((struct lys_node_leaf *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100464 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100465 }
466 retval->expr = transform_schema2json(module, value, line);
467 if (!retval->expr || lyxp_syntax_check(retval->expr, line)) {
468 goto error;
469 }
470 free(value);
471 return retval;
472
473error:
474 free(value);
475 return NULL;
476}
477
478int
479yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, int type, int message, int line)
480{
481 int ret;
482 char *exp;
483
484 switch (type) {
485 case MUST_KEYWORD:
486 exp = "must";
487 break;
488 }
489 if (message==ERROR_APP_TAG_KEYWORD) {
490 ret = yang_check_string(module, &save->eapptag, "error_app_tag", exp, value, line);
491 } else {
492 ret = yang_check_string(module, &save->emsg, "error_app_tag", exp, value, line);
493 }
494 return ret;
495}
Pavol Vicanb5687112016-02-09 22:35:59 +0100496
497int
498yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value, int line)
499{
500 if (cont->presence) {
501 LOGVAL(LYE_TOOMANY, line, "presence", "container");
502 free(value);
503 return EXIT_FAILURE;
504 } else {
505 cont->presence = lydict_insert_zc(module->ctx, value);
506 return EXIT_SUCCESS;
507 }
508}
509
510int
511yang_read_config(void *node, int value, int type, int line)
512{
513 int ret;
514
515 switch (type) {
516 case CONTAINER_KEYWORD:
517 ret = yang_check_flags(&((struct lys_node_container *)node)->flags, LYS_CONFIG_MASK, "config", "container", value, line);
518 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100519 case ANYXML_KEYWORD:
520 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_CONFIG_MASK, "config", "anyxml", value, line);
521 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100522 case CHOICE_KEYWORD:
523 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_CONFIG_MASK, "config", "choice", value, line);
524 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100525 case LEAF_KEYWORD:
526 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_CONFIG_MASK, "config", "leaf", value, line);
527 break;
Pavol Vicanb5687112016-02-09 22:35:59 +0100528 }
529 return ret;
530}
Pavol Vican235dbd42016-02-10 10:34:19 +0100531
532void *
533yang_read_when(struct lys_module *module, struct lys_node *node, int type, char *value, int line)
534{
535 struct lys_when *retval;
536
537 retval = calloc(1, sizeof *retval);
538 if (!retval) {
539 LOGMEM;
540 free(value);
541 return NULL;
542 }
543 retval->cond = transform_schema2json(module, value, line);
544 if (!retval->cond || lyxp_syntax_check(retval->cond, line)) {
545 goto error;
546 }
547 switch (type) {
548 case CONTAINER_KEYWORD:
549 if (((struct lys_node_container *)node)->when) {
550 LOGVAL(LYE_TOOMANY,line,"when","container");
551 goto error;
552 }
553 ((struct lys_node_container *)node)->when = retval;
554 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100555 case ANYXML_KEYWORD:
Pavol Vican8c82fa82016-02-10 13:13:24 +0100556 if (((struct lys_node_anyxml *)node)->when) {
557 LOGVAL(LYE_TOOMANY,line,"when","anyxml");
558 goto error;
559 }
560 ((struct lys_node_anyxml *)node)->when = retval;
561 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100562 case CHOICE_KEYWORD:
563 if (((struct lys_node_choice *)node)->when) {
564 LOGVAL(LYE_TOOMANY,line,"when","choice");
565 goto error;
566 }
567 ((struct lys_node_choice *)node)->when = retval;
568 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100569 case CASE_KEYWORD:
570 if (((struct lys_node_case *)node)->when) {
571 LOGVAL(LYE_TOOMANY,line,"when","case");
572 goto error;
573 }
574 ((struct lys_node_case *)node)->when = retval;
575 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100576 case LEAF_KEYWORD:
577 if (((struct lys_node_leaf *)node)->when) {
578 LOGVAL(LYE_TOOMANY,line,"when","leaf");
579 goto error;
580 }
581 ((struct lys_node_leaf *)node)->when = retval;
582 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100583 }
584 free(value);
585 return retval;
586
587error:
588 free(value);
589 lys_when_free(module->ctx, retval);
590 return NULL;
591}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100592
593void *
Pavol Vican7cadfe72016-02-11 12:33:34 +0100594yang_read_node(struct lys_module *module, struct lys_node *parent, char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100595{
Pavol Vican7cadfe72016-02-11 12:33:34 +0100596 struct lys_node *node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100597
Pavol Vican7cadfe72016-02-11 12:33:34 +0100598 node = calloc(1, sizeof_struct);
599 if (!node) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100600 LOGMEM;
601 return NULL;
602 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100603 node->module = module;
604 node->name = lydict_insert_zc(module->ctx, value);
605 node->nodetype = nodetype;
606 node->prev = node;
607
608 /* insert the node into the schema tree */
609 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
610 lydict_remove(module->ctx, node->name);
611 free(node);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100612 return NULL;
613 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100614 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100615}
616
617int
618yang_read_mandatory(void *node, int value, int type, int line)
619{
620 int ret;
621
622 switch (type) {
623 case ANYXML_KEYWORD:
624 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_MAND_MASK, "mandatory", "anyxml", value, line);
625 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100626 case CHOICE_KEYWORD:
627 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_MAND_MASK, "mandatory", "choice", value, line);
628 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100629 case LEAF_KEYWORD:
630 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_MAND_MASK, "mandatory", "leaf", value, line);
631 break;
632 }
633 return ret;
634}
635
636int
637yang_read_default(struct lys_module *module, void *node, char *value, int type, int line)
638{
639 int ret;
640
641 switch (type) {
642 case LEAF_KEYWORD:
643 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, line);
644 break;
645 }
646 return ret;
647}
648
649int
650yang_read_units(struct lys_module *module, void *node, char *value, int type, int line)
651{
652 int ret;
653
654 switch (type) {
655 case LEAF_KEYWORD:
656 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, line);
657 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100658 }
659 return ret;
660}