blob: c1948bdd17f8973ca790a8a6bacbf68b2c1f3dbd [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 Vican339d4ad2016-02-12 12:49:22 +0100218 case LEAF_LIST_KEYWORD:
219 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->dsc, "description", "leaflist", value, line);
220 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100221 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100222 }
223 return ret;
224}
225
226int
227yang_read_reference(struct lys_module *module, void *node, char *value, int type, int line)
228{
229 int ret;
230
231 if (!node) {
232 ret = yang_check_string(module, &module->ref, "reference", "module", value, line);
Pavol Vicanbedff692016-02-03 14:29:17 +0100233 } else {
234 switch (type) {
235 case REVISION_KEYWORD:
236 ret = yang_check_string(module, &((struct lys_revision *) node)->ref, "reference", "revision", value, line);
237 break;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100238 case FEATURE_KEYWORD:
239 ret = yang_check_string(module, &((struct lys_feature *) node)->ref, "reference", "feature", value, line);
240 break;
241 case IDENTITY_KEYWORD:
242 ret = yang_check_string(module, &((struct lys_ident *) node)->ref, "reference", "identity", value, line);
243 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100244 case MUST_KEYWORD:
Pavol Vican235dbd42016-02-10 10:34:19 +0100245 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "must", value, line);
246 break;
247 case WHEN_KEYWORD:
248 ret = yang_check_string(module, &((struct lys_when *) node)->ref, "reference", "when", value, line);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100249 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100250 case CONTAINER_KEYWORD:
251 ret = yang_check_string(module, &((struct lys_node_container *) node)->ref, "reference", "container", value, line);
252 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100253 case ANYXML_KEYWORD:
254 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "anyxml", value, line);
255 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100256 case CHOICE_KEYWORD:
257 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "choice", value, line);
258 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100259 case CASE_KEYWORD:
260 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "case", value, line);
261 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100262 case GROUPING_KEYWORD:
263 ret = yang_check_string(module, &((struct lys_node_grp *) node)->ref, "reference", "grouping", value, line);
264 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100265 case LEAF_KEYWORD:
266 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->ref, "reference", "leaf", value, line);
267 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100268 case LEAF_LIST_KEYWORD:
269 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->ref, "reference", "leaflist", value, line);
270 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100271 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100272 }
273 return ret;
274}
Pavol Vicanbedff692016-02-03 14:29:17 +0100275
276void *
277yang_read_revision(struct lys_module *module, char *value)
278{
279 struct lys_revision *retval;
280
Pavol Vican1eeb1992016-02-09 11:10:45 +0100281 retval = &module->rev[module->rev_size];
Pavol Vicanbedff692016-02-03 14:29:17 +0100282
283 /* first member of array is last revision */
Pavol Vican1eeb1992016-02-09 11:10:45 +0100284 if (module->rev_size && strcmp(module->rev[0].date, value) < 0) {
Pavol Vicanbedff692016-02-03 14:29:17 +0100285 memcpy(retval->date, module->rev[0].date, LY_REV_SIZE);
286 memcpy(module->rev[0].date, value, LY_REV_SIZE);
287 retval->dsc = module->rev[0].dsc;
288 retval->ref = module->rev[0].ref;
289 retval = module->rev;
290 retval->dsc = NULL;
291 retval->ref = NULL;
292 } else {
293 memcpy(retval->date, value, LY_REV_SIZE);
294 }
Pavol Vican1eeb1992016-02-09 11:10:45 +0100295 module->rev_size++;
Pavol Vicanbedff692016-02-03 14:29:17 +0100296 free(value);
297 return retval;
298}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100299
300int
301yang_add_elem(struct lys_node_array **node, int *size)
302{
303 if (!*size % LY_ARRAY_SIZE) {
304 if (!(*node = ly_realloc(*node, (*size + LY_ARRAY_SIZE) * sizeof **node))) {
305 LOGMEM;
306 return EXIT_FAILURE;
307 } else {
308 memset(*node+*size,0,LY_ARRAY_SIZE*sizeof **node);
309 }
310 }
311 (*size)++;
312 return EXIT_SUCCESS;
313}
Pavol Vicane1354e92016-02-09 14:02:09 +0100314
315void *
316yang_read_feature(struct lys_module *module, char *value, int line)
317{
318 struct lys_feature *retval;
319
320 /* check uniqueness of feature's names */
321 if (lyp_check_identifier(value, LY_IDENT_FEATURE, line, module, NULL)) {
322 goto error;
323 }
324 retval = &module->features[module->features_size];
325 retval->name = lydict_insert_zc(module->ctx, value);
326 retval->module = module;
327 module->features_size++;
328 return retval;
329
330error:
331 free(value);
332 return NULL;
333}
334
335int
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100336yang_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 +0100337{
338 const char *exp;
339 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100340 struct lys_feature *f;
341 struct lys_node *n;
Pavol Vicane1354e92016-02-09 14:02:09 +0100342
343 if (!(exp = transform_schema2json(module, value, line))) {
344 free(value);
345 return EXIT_FAILURE;
346 }
347 free(value);
348
349 /* hack - store pointer to the parent node for later status check */
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100350 if (type == FEATURE_KEYWORD) {
351 f = (struct lys_feature *) ptr;
352 f->features[f->features_size] = f;
353 ret = unres_schema_add_str(module, unres, &f->features[f->features_size], UNRES_IFFEAT, exp, line);
354 f->features_size++;
355 } else {
356 n = (struct lys_node *) ptr;
357 n->features[n->features_size] = (struct lys_feature *) n;
358 ret = unres_schema_add_str(module, unres, &n->features[n->features_size], UNRES_IFFEAT, exp, line);
359 n->features_size++;
360 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100361
362 lydict_remove(module->ctx, exp);
363 if (ret == -1) {
364
365 return EXIT_FAILURE;
366 }
367 return EXIT_SUCCESS;
368}
369
370static int
371yang_check_flags(uint8_t *flags, uint8_t mask, char *what, char *where, int value, int line)
372{
373 if (*flags & mask) {
374 LOGVAL(LYE_TOOMANY, line, what, where);
375 return EXIT_FAILURE;
376 } else {
Pavol Vican945187f2016-02-11 10:12:33 +0100377 *flags |= value;
Pavol Vicane1354e92016-02-09 14:02:09 +0100378 return EXIT_SUCCESS;
379 }
380}
381
382int
383yang_read_status(void *node, int value, int type, int line)
384{
385 int retval;
386
387 switch (type) {
388 case FEATURE_KEYWORD:
389 retval = yang_check_flags(&((struct lys_feature *) node)->flags, LYS_STATUS_MASK, "status", "feature", value, line);
390 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100391 case IDENTITY_KEYWORD:
Pavol Vicanbbdef532016-02-09 14:52:12 +0100392 retval = yang_check_flags(&((struct lys_ident *) node)->flags, LYS_STATUS_MASK, "status", "identity", value, line);
393 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100394 case CONTAINER_KEYWORD:
395 retval = yang_check_flags(&((struct lys_node_container *) node)->flags, LYS_STATUS_MASK, "status", "container", value, line);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100396 break;
397 case ANYXML_KEYWORD:
398 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "anyxml", value, line);
399 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100400 case CHOICE_KEYWORD:
401 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "choice", value, line);
402 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100403 case CASE_KEYWORD:
404 retval = yang_check_flags(&((struct lys_node_case *) node)->flags, LYS_STATUS_MASK, "status", "case", value, line);
405 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100406 case GROUPING_KEYWORD:
407 retval = yang_check_flags(&((struct lys_node_grp *) node)->flags, LYS_STATUS_MASK, "status", "grouping", value, line);
408 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100409 case LEAF_KEYWORD:
410 retval = yang_check_flags(&((struct lys_node_leaf *) node)->flags, LYS_STATUS_MASK, "status", "leaf", value, line);
411 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100412 case LEAF_LIST_KEYWORD:
413 retval = yang_check_flags(&((struct lys_node_leaflist *) node)->flags, LYS_STATUS_MASK, "status", "leaflist", value, line);
414 break;
Pavol Vicane1354e92016-02-09 14:02:09 +0100415 }
416 return retval;
417}
Pavol Vicanbbdef532016-02-09 14:52:12 +0100418
419void *
420yang_read_identity(struct lys_module *module, char *value)
421{
422 struct lys_ident *ret;
423
424 ret = &module->ident[module->ident_size];
425 ret->name = lydict_insert_zc(module->ctx, value);
426 ret->module = module;
427 module->ident_size++;
428 return ret;
429}
430
431int
432yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres, int line)
433{
434 const char *exp;
435
436 if (ident->base) {
437 LOGVAL(LYE_TOOMANY, line, "base", "identity");
438 return EXIT_FAILURE;
439 }
Pavol Vicanbbdef532016-02-09 14:52:12 +0100440 exp = transform_schema2json(module, value, line);
441 free(value);
442 if (!exp) {
443 return EXIT_FAILURE;
444 }
445 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp, line) == -1) {
446 lydict_remove(module->ctx, exp);
447 return EXIT_FAILURE;
448 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100449
450 /* hack - store some address due to detection of unresolved base*/
451 if (!ident->base) {
452 ident->base = (void *)1;
453 }
454
Pavol Vicanbbdef532016-02-09 14:52:12 +0100455 lydict_remove(module->ctx, exp);
456 return EXIT_SUCCESS;
457}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100458
459void *
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100460yang_read_must(struct lys_module *module, struct lys_node *node, char *value, int type, int line)
461{
462 struct lys_restr *retval;
463
464 switch (type) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100465 case CONTAINER_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100466 retval = &((struct lys_node_container *)node)->must[((struct lys_node_container *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100467 break;
468 case ANYXML_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100469 retval = &((struct lys_node_anyxml *)node)->must[((struct lys_node_anyxml *)node)->must_size++];
470 break;
471 case LEAF_KEYWORD:
472 retval = &((struct lys_node_leaf *)node)->must[((struct lys_node_leaf *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100473 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100474 case LEAF_LIST_KEYWORD:
475 retval = &((struct lys_node_leaflist *)node)->must[((struct lys_node_leaflist *)node)->must_size++];
476 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100477 }
478 retval->expr = transform_schema2json(module, value, line);
479 if (!retval->expr || lyxp_syntax_check(retval->expr, line)) {
480 goto error;
481 }
482 free(value);
483 return retval;
484
485error:
486 free(value);
487 return NULL;
488}
489
490int
491yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, int type, int message, int line)
492{
493 int ret;
494 char *exp;
495
496 switch (type) {
497 case MUST_KEYWORD:
498 exp = "must";
499 break;
500 }
501 if (message==ERROR_APP_TAG_KEYWORD) {
502 ret = yang_check_string(module, &save->eapptag, "error_app_tag", exp, value, line);
503 } else {
504 ret = yang_check_string(module, &save->emsg, "error_app_tag", exp, value, line);
505 }
506 return ret;
507}
Pavol Vicanb5687112016-02-09 22:35:59 +0100508
509int
510yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value, int line)
511{
512 if (cont->presence) {
513 LOGVAL(LYE_TOOMANY, line, "presence", "container");
514 free(value);
515 return EXIT_FAILURE;
516 } else {
517 cont->presence = lydict_insert_zc(module->ctx, value);
518 return EXIT_SUCCESS;
519 }
520}
521
522int
523yang_read_config(void *node, int value, int type, int line)
524{
525 int ret;
526
527 switch (type) {
528 case CONTAINER_KEYWORD:
529 ret = yang_check_flags(&((struct lys_node_container *)node)->flags, LYS_CONFIG_MASK, "config", "container", value, line);
530 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100531 case ANYXML_KEYWORD:
532 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_CONFIG_MASK, "config", "anyxml", value, line);
533 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100534 case CHOICE_KEYWORD:
535 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_CONFIG_MASK, "config", "choice", value, line);
536 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100537 case LEAF_KEYWORD:
538 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_CONFIG_MASK, "config", "leaf", value, line);
539 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100540 case LEAF_LIST_KEYWORD:
541 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_CONFIG_MASK, "config", "leaflist", value, line);
542 break;
Pavol Vicanb5687112016-02-09 22:35:59 +0100543 }
544 return ret;
545}
Pavol Vican235dbd42016-02-10 10:34:19 +0100546
547void *
548yang_read_when(struct lys_module *module, struct lys_node *node, int type, char *value, int line)
549{
550 struct lys_when *retval;
551
552 retval = calloc(1, sizeof *retval);
553 if (!retval) {
554 LOGMEM;
555 free(value);
556 return NULL;
557 }
558 retval->cond = transform_schema2json(module, value, line);
559 if (!retval->cond || lyxp_syntax_check(retval->cond, line)) {
560 goto error;
561 }
562 switch (type) {
563 case CONTAINER_KEYWORD:
564 if (((struct lys_node_container *)node)->when) {
565 LOGVAL(LYE_TOOMANY,line,"when","container");
566 goto error;
567 }
568 ((struct lys_node_container *)node)->when = retval;
569 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100570 case ANYXML_KEYWORD:
Pavol Vican8c82fa82016-02-10 13:13:24 +0100571 if (((struct lys_node_anyxml *)node)->when) {
572 LOGVAL(LYE_TOOMANY,line,"when","anyxml");
573 goto error;
574 }
575 ((struct lys_node_anyxml *)node)->when = retval;
576 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100577 case CHOICE_KEYWORD:
578 if (((struct lys_node_choice *)node)->when) {
579 LOGVAL(LYE_TOOMANY,line,"when","choice");
580 goto error;
581 }
582 ((struct lys_node_choice *)node)->when = retval;
583 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100584 case CASE_KEYWORD:
585 if (((struct lys_node_case *)node)->when) {
586 LOGVAL(LYE_TOOMANY,line,"when","case");
587 goto error;
588 }
589 ((struct lys_node_case *)node)->when = retval;
590 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100591 case LEAF_KEYWORD:
592 if (((struct lys_node_leaf *)node)->when) {
593 LOGVAL(LYE_TOOMANY,line,"when","leaf");
594 goto error;
595 }
596 ((struct lys_node_leaf *)node)->when = retval;
597 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100598 case LEAF_LIST_KEYWORD:
599 if (((struct lys_node_leaflist *)node)->when) {
600 LOGVAL(LYE_TOOMANY,line,"when","leaflist");
601 goto error;
602 }
603 ((struct lys_node_leaflist *)node)->when = retval;
604 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100605 }
606 free(value);
607 return retval;
608
609error:
610 free(value);
611 lys_when_free(module->ctx, retval);
612 return NULL;
613}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100614
615void *
Pavol Vican7cadfe72016-02-11 12:33:34 +0100616yang_read_node(struct lys_module *module, struct lys_node *parent, char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100617{
Pavol Vican7cadfe72016-02-11 12:33:34 +0100618 struct lys_node *node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100619
Pavol Vican7cadfe72016-02-11 12:33:34 +0100620 node = calloc(1, sizeof_struct);
621 if (!node) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100622 LOGMEM;
623 return NULL;
624 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100625 node->module = module;
626 node->name = lydict_insert_zc(module->ctx, value);
627 node->nodetype = nodetype;
628 node->prev = node;
629
630 /* insert the node into the schema tree */
631 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
632 lydict_remove(module->ctx, node->name);
633 free(node);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100634 return NULL;
635 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100636 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100637}
638
639int
640yang_read_mandatory(void *node, int value, int type, int line)
641{
642 int ret;
643
644 switch (type) {
645 case ANYXML_KEYWORD:
646 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_MAND_MASK, "mandatory", "anyxml", value, line);
647 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100648 case CHOICE_KEYWORD:
649 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_MAND_MASK, "mandatory", "choice", value, line);
650 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100651 case LEAF_KEYWORD:
652 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_MAND_MASK, "mandatory", "leaf", value, line);
653 break;
654 }
655 return ret;
656}
657
658int
659yang_read_default(struct lys_module *module, void *node, char *value, int type, int line)
660{
661 int ret;
662
663 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100664 case LEAF_KEYWORD:
665 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, line);
666 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100667 }
668 return ret;
669}
670
671int
672yang_read_units(struct lys_module *module, void *node, char *value, int type, int line)
673{
674 int ret;
675
676 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100677 case LEAF_KEYWORD:
678 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, line);
679 break;
680 case LEAF_LIST_KEYWORD:
681 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, line);
682 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100683 }
684 return ret;
685}