blob: da8ffa1ec4cc8c022b6a5d49941c8d7f1ad4f0f3 [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
Pavol Vican5de33492016-02-22 14:03:24 +010022#include <ctype.h>
Pavol Vican1c203db2016-02-24 14:05:23 +010023#include <pcre.h>
Pavol Vican021488a2016-01-25 23:56:12 +010024#include "parser_yang.h"
25#include "parser_yang_bis.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010026#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010027#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010028
Pavol Vican2a064652016-02-02 22:54:34 +010029static int
30yang_check_string(struct lys_module *module, const char **target, char *what, char *where, char *value, int line)
31{
Pavol Vicanbf805472016-01-26 14:24:56 +010032 if (*target) {
Pavol Vicand72227c2016-02-21 20:29:52 +010033 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010034 free(value);
35 return 1;
36 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010037 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010038 return 0;
39 }
40}
41
Pavol Vican2a064652016-02-02 22:54:34 +010042int
43yang_read_common(struct lys_module *module, char *value, int type, int line)
44{
Pavol Vican6eb14e82016-02-03 12:27:13 +010045 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010046
47 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010048 case MODULE_KEYWORD:
49 module->name = lydict_insert_zc(module->ctx, value);
50 break;
51 case NAMESPACE_KEYWORD:
52 ret = yang_check_string(module, &module->ns, "namespace", "module", value, line);
53 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010054 case ORGANIZATION_KEYWORD:
55 ret = yang_check_string(module, &module->org, "organization", "module", value, line);
56 break;
57 case CONTACT_KEYWORD:
58 ret = yang_check_string(module, &module->contact, "contact", "module", value, line);
59 break;
Pavol Vican2a064652016-02-02 22:54:34 +010060 }
61
Pavol Vican021488a2016-01-25 23:56:12 +010062 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010063}
64
Pavol Vican2a064652016-02-02 22:54:34 +010065int
66yang_read_prefix(struct lys_module *module, void *save, char *value, int type, int line)
67{
Pavol Vican6eb14e82016-02-03 12:27:13 +010068 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +010069
Pavol Vican6eb14e82016-02-03 12:27:13 +010070 if (lyp_check_identifier(value, LY_IDENT_PREFIX, line, module, NULL)) {
71 free(value);
72 return EXIT_FAILURE;
73 }
Pavol Vicanbf805472016-01-26 14:24:56 +010074 switch (type){
Pavol Vican2a064652016-02-02 22:54:34 +010075 case MODULE_KEYWORD:
76 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, line);
77 break;
Pavol Vican6eb14e82016-02-03 12:27:13 +010078 case IMPORT_KEYWORD:
79 ((struct lys_import *)save)->prefix = lydict_insert_zc(module->ctx, value);
80 break;
Pavol Vican2a064652016-02-02 22:54:34 +010081 }
Pavol Vican6eb14e82016-02-03 12:27:13 +010082
Pavol Vicanbf805472016-01-26 14:24:56 +010083 return ret;
84}
Pavol Vican6eb14e82016-02-03 12:27:13 +010085
86void *
87yang_elem_of_array(void **ptr, uint8_t *act_size, int type, int sizeof_struct)
88{
89 void *retval;
90
91 if (!(*act_size % LY_ARRAY_SIZE) && !(*ptr = ly_realloc(*ptr, (*act_size + LY_ARRAY_SIZE) * sizeof_struct))) {
92 LOGMEM;
93 return NULL;
94 }
95 switch (type) {
96 case IMPORT_KEYWORD:
97 retval = &((struct lys_import *)(*ptr))[*act_size];
98 break;
Pavol Vicanbedff692016-02-03 14:29:17 +010099 case REVISION_KEYWORD:
100 retval = &((struct lys_revision *)(*ptr))[*act_size];
101 break;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100102 }
103 (*act_size)++;
104 memset(retval,0,sizeof_struct);
105 return retval;
106}
107
108int
109yang_fill_import(struct lys_module *module, struct lys_import *imp, char *value, int line)
110{
111 int count, i;
112
113 /* check for circular import, store it if passed */
114 if (!module->ctx->models.parsing) {
115 count = 0;
116 } else {
117 for (count = 0; module->ctx->models.parsing[count]; ++count) {
118 if (value == module->ctx->models.parsing[count]) {
119 LOGERR(LY_EVALID, "Circular import dependency on the module \"%s\".", value);
120 goto error;
121 }
122 }
123 }
124 ++count;
125 module->ctx->models.parsing =
126 ly_realloc(module->ctx->models.parsing, (count + 1) * sizeof *module->ctx->models.parsing);
127 if (!module->ctx->models.parsing) {
128 LOGMEM;
129 goto error;
130 }
131 module->ctx->models.parsing[count - 1] = value;
132 module->ctx->models.parsing[count] = NULL;
133
134 /* try to load the module */
135 imp->module = (struct lys_module *)ly_ctx_get_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
136 if (!imp->module) {
137 /* whether to use a user callback is decided in the function */
138 imp->module = (struct lys_module *)ly_ctx_load_module(module->ctx, value, imp->rev[0] ? imp->rev : NULL);
139 }
140
141 /* remove the new module name now that its parsing is finished (even if failed) */
142 if (module->ctx->models.parsing[count] || (module->ctx->models.parsing[count - 1] != value)) {
143 LOGINT;
144 }
145 --count;
146 if (count) {
147 module->ctx->models.parsing[count] = NULL;
148 } else {
149 free(module->ctx->models.parsing);
150 module->ctx->models.parsing = NULL;
151 }
152
153 /* check the result */
154 if (!imp->module) {
155 LOGERR(LY_EVALID, "Importing \"%s\" module into \"%s\" failed.", value, module->name);
156 goto error;
157 }
158
159 module->imp_size++;
160
161 /* check duplicities in imported modules */
162 for (i = 0; i < module->imp_size - 1; i++) {
163 if (!strcmp(module->imp[i].module->name, module->imp[module->imp_size - 1].module->name)) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100164 LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Importing module \"%s\" repeatedly.", module->imp[i].module->name);
Pavol Vican6eb14e82016-02-03 12:27:13 +0100165 goto error;
166 }
167 }
168
169 free(value);
170 return EXIT_SUCCESS;
171
172 error:
173
174 free(value);
175 return EXIT_FAILURE;
176}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100177
178int
179yang_read_description(struct lys_module *module, void *node, char *value, int type, int line)
180{
181 int ret;
182
183 if (!node) {
184 ret = yang_check_string(module, &module->dsc, "description", "module", value, line);
Pavol Vicanbedff692016-02-03 14:29:17 +0100185 } else {
186 switch (type) {
187 case REVISION_KEYWORD:
188 ret = yang_check_string(module, &((struct lys_revision *) node)->dsc, "description", "revision", value, line);
189 break;
Pavol Vicane1354e92016-02-09 14:02:09 +0100190 case FEATURE_KEYWORD:
191 ret = yang_check_string(module, &((struct lys_feature *) node)->dsc, "description", "feature", value, line);
192 break;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100193 case IDENTITY_KEYWORD:
194 ret = yang_check_string(module, &((struct lys_ident *) node)->dsc, "description", "identity", value, line);
195 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100196 case MUST_KEYWORD:
197 ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "must", value, line);
198 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100199 case WHEN_KEYWORD:
200 ret = yang_check_string(module, &((struct lys_when *) node)->dsc, "description", "when" , value, line);
201 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100202 case CONTAINER_KEYWORD:
203 ret = yang_check_string(module, &((struct lys_node_container *) node)->dsc, "description", "container", value, line);
204 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100205 case ANYXML_KEYWORD:
206 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->dsc, "description", "anyxml", value, line);
207 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100208 case CHOICE_KEYWORD:
209 ret = yang_check_string(module, &((struct lys_node_choice *) node)->dsc, "description", "choice", value, line);
210 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100211 case CASE_KEYWORD:
212 ret = yang_check_string(module, &((struct lys_node_case *) node)->dsc, "description", "case", value, line);
213 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100214 case GROUPING_KEYWORD:
215 ret = yang_check_string(module, &((struct lys_node_grp *) node)->dsc, "description", "grouping", value, line);
216 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100217 case LEAF_KEYWORD:
218 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dsc, "description", "leaf", value, line);
219 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100220 case LEAF_LIST_KEYWORD:
221 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->dsc, "description", "leaflist", value, line);
222 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100223 case LIST_KEYWORD:
224 ret = yang_check_string(module, &((struct lys_node_list *) node)->dsc, "description", "list", value, line);
225 break;
Pavol Vican73e7c992016-02-24 12:18:05 +0100226 case LENGTH_KEYWORD:
227 ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "length", value, line);
228 break;
Pavol Vican1c203db2016-02-24 14:05:23 +0100229 case PATTERN_KEYWORD:
230 ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "pattern", value, line);
231 break;
Pavol Vicanaff5c802016-02-24 15:56:45 +0100232 case RANGE_KEYWORD:
233 ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "range", value, line);
234 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100235 case ENUM_KEYWORD:
236 ret = yang_check_string(module, &((struct lys_type_enum *) node)->dsc, "description", "enum", value, line);
237 break;
Pavol Vican9887c682016-02-29 11:32:01 +0100238 case BIT_KEYWORD:
239 ret = yang_check_string(module, &((struct lys_type_bit *) node)->dsc, "description", "bit", value, line);
240 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100241 case TYPEDEF_KEYWORD:
242 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dsc, "description", "typedef", value, line);
243 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100244 case USES_KEYWORD:
245 ret = yang_check_string(module, &((struct lys_node_uses *) node)->dsc, "description", "uses", value, line);
246 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100247 case REFINE_KEYWORD:
248 ret = yang_check_string(module, &((struct lys_refine *) node)->dsc, "description", "refine", value, line);
249 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100250 case AUGMENT_KEYWORD:
251 ret = yang_check_string(module, &((struct lys_node_augment *) node)->dsc, "description", "augment", value, line);
252 break;
Pavol Vican52ed67d2016-03-02 17:46:15 +0100253 case RPC_KEYWORD:
254 ret = yang_check_string(module, &((struct lys_node_rpc *) node)->dsc, "description", "rpc", value, line);
255 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100256 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100257 }
258 return ret;
259}
260
261int
262yang_read_reference(struct lys_module *module, void *node, char *value, int type, int line)
263{
264 int ret;
265
266 if (!node) {
267 ret = yang_check_string(module, &module->ref, "reference", "module", value, line);
Pavol Vicanbedff692016-02-03 14:29:17 +0100268 } else {
269 switch (type) {
270 case REVISION_KEYWORD:
271 ret = yang_check_string(module, &((struct lys_revision *) node)->ref, "reference", "revision", value, line);
272 break;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100273 case FEATURE_KEYWORD:
274 ret = yang_check_string(module, &((struct lys_feature *) node)->ref, "reference", "feature", value, line);
275 break;
276 case IDENTITY_KEYWORD:
277 ret = yang_check_string(module, &((struct lys_ident *) node)->ref, "reference", "identity", value, line);
278 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100279 case MUST_KEYWORD:
Pavol Vican235dbd42016-02-10 10:34:19 +0100280 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "must", value, line);
281 break;
282 case WHEN_KEYWORD:
283 ret = yang_check_string(module, &((struct lys_when *) node)->ref, "reference", "when", value, line);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100284 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100285 case CONTAINER_KEYWORD:
286 ret = yang_check_string(module, &((struct lys_node_container *) node)->ref, "reference", "container", value, line);
287 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100288 case ANYXML_KEYWORD:
289 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "anyxml", value, line);
290 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100291 case CHOICE_KEYWORD:
292 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "choice", value, line);
293 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100294 case CASE_KEYWORD:
295 ret = yang_check_string(module, &((struct lys_node_anyxml *) node)->ref, "reference", "case", value, line);
296 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100297 case GROUPING_KEYWORD:
298 ret = yang_check_string(module, &((struct lys_node_grp *) node)->ref, "reference", "grouping", value, line);
299 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100300 case LEAF_KEYWORD:
301 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->ref, "reference", "leaf", value, line);
302 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100303 case LEAF_LIST_KEYWORD:
304 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->ref, "reference", "leaflist", value, line);
305 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100306 case LIST_KEYWORD:
307 ret = yang_check_string(module, &((struct lys_node_list *) node)->ref, "reference", "list", value, line);
308 break;
Pavol Vican73e7c992016-02-24 12:18:05 +0100309 case LENGTH_KEYWORD:
310 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "length", value, line);
311 break;
Pavol Vican1c203db2016-02-24 14:05:23 +0100312 case PATTERN_KEYWORD:
313 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "pattern", value, line);
314 break;
Pavol Vicanaff5c802016-02-24 15:56:45 +0100315 case RANGE_KEYWORD:
316 ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "range", value, line);
317 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100318 case ENUM_KEYWORD:
319 ret = yang_check_string(module, &((struct lys_type_enum *) node)->ref, "reference", "enum", value, line);
320 break;
Pavol Vican9887c682016-02-29 11:32:01 +0100321 case BIT_KEYWORD:
322 ret = yang_check_string(module, &((struct lys_type_bit *) node)->ref, "reference", "bit", value, line);
323 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100324 case TYPEDEF_KEYWORD:
325 ret = yang_check_string(module, &((struct lys_tpdf *) node)->ref, "reference", "typedef", value, line);
326 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100327 case USES_KEYWORD:
328 ret = yang_check_string(module, &((struct lys_node_uses *) node)->ref, "reference", "uses", value, line);
329 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100330 case REFINE_KEYWORD:
331 ret = yang_check_string(module, &((struct lys_refine *) node)->ref, "reference", "refine", value, line);
332 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100333 case AUGMENT_KEYWORD:
334 ret = yang_check_string(module, &((struct lys_node_augment *) node)->ref, "reference", "augment", value, line);
335 break;
Pavol Vican52ed67d2016-03-02 17:46:15 +0100336 case RPC_KEYWORD:
337 ret = yang_check_string(module, &((struct lys_node_rpc *) node)->ref, "reference", "rpc", value, line);
338 break;
Pavol Vicanbedff692016-02-03 14:29:17 +0100339 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100340 }
341 return ret;
342}
Pavol Vicanbedff692016-02-03 14:29:17 +0100343
344void *
345yang_read_revision(struct lys_module *module, char *value)
346{
347 struct lys_revision *retval;
348
Pavol Vican1eeb1992016-02-09 11:10:45 +0100349 retval = &module->rev[module->rev_size];
Pavol Vicanbedff692016-02-03 14:29:17 +0100350
351 /* first member of array is last revision */
Pavol Vican1eeb1992016-02-09 11:10:45 +0100352 if (module->rev_size && strcmp(module->rev[0].date, value) < 0) {
Pavol Vicanbedff692016-02-03 14:29:17 +0100353 memcpy(retval->date, module->rev[0].date, LY_REV_SIZE);
354 memcpy(module->rev[0].date, value, LY_REV_SIZE);
355 retval->dsc = module->rev[0].dsc;
356 retval->ref = module->rev[0].ref;
357 retval = module->rev;
358 retval->dsc = NULL;
359 retval->ref = NULL;
360 } else {
361 memcpy(retval->date, value, LY_REV_SIZE);
362 }
Pavol Vican1eeb1992016-02-09 11:10:45 +0100363 module->rev_size++;
Pavol Vicanbedff692016-02-03 14:29:17 +0100364 free(value);
365 return retval;
366}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100367
368int
Pavol Vicana1827962016-02-29 15:39:42 +0100369yang_add_elem(struct lys_node_array **node, uint32_t *size)
Pavol Vican1eeb1992016-02-09 11:10:45 +0100370{
371 if (!*size % LY_ARRAY_SIZE) {
372 if (!(*node = ly_realloc(*node, (*size + LY_ARRAY_SIZE) * sizeof **node))) {
373 LOGMEM;
374 return EXIT_FAILURE;
375 } else {
376 memset(*node+*size,0,LY_ARRAY_SIZE*sizeof **node);
377 }
378 }
379 (*size)++;
380 return EXIT_SUCCESS;
381}
Pavol Vicane1354e92016-02-09 14:02:09 +0100382
383void *
384yang_read_feature(struct lys_module *module, char *value, int line)
385{
386 struct lys_feature *retval;
387
388 /* check uniqueness of feature's names */
389 if (lyp_check_identifier(value, LY_IDENT_FEATURE, line, module, NULL)) {
390 goto error;
391 }
392 retval = &module->features[module->features_size];
393 retval->name = lydict_insert_zc(module->ctx, value);
394 retval->module = module;
395 module->features_size++;
396 return retval;
397
398error:
399 free(value);
400 return NULL;
401}
402
403int
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100404yang_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 +0100405{
406 const char *exp;
407 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100408 struct lys_feature *f;
409 struct lys_node *n;
Pavol Vicane1354e92016-02-09 14:02:09 +0100410
411 if (!(exp = transform_schema2json(module, value, line))) {
412 free(value);
413 return EXIT_FAILURE;
414 }
415 free(value);
416
417 /* hack - store pointer to the parent node for later status check */
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100418 if (type == FEATURE_KEYWORD) {
419 f = (struct lys_feature *) ptr;
420 f->features[f->features_size] = f;
421 ret = unres_schema_add_str(module, unres, &f->features[f->features_size], UNRES_IFFEAT, exp, line);
422 f->features_size++;
423 } else {
424 n = (struct lys_node *) ptr;
425 n->features[n->features_size] = (struct lys_feature *) n;
426 ret = unres_schema_add_str(module, unres, &n->features[n->features_size], UNRES_IFFEAT, exp, line);
427 n->features_size++;
428 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100429
430 lydict_remove(module->ctx, exp);
431 if (ret == -1) {
432
433 return EXIT_FAILURE;
434 }
435 return EXIT_SUCCESS;
436}
437
438static int
439yang_check_flags(uint8_t *flags, uint8_t mask, char *what, char *where, int value, int line)
440{
441 if (*flags & mask) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100442 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, what, where);
Pavol Vicane1354e92016-02-09 14:02:09 +0100443 return EXIT_FAILURE;
444 } else {
Pavol Vican945187f2016-02-11 10:12:33 +0100445 *flags |= value;
Pavol Vicane1354e92016-02-09 14:02:09 +0100446 return EXIT_SUCCESS;
447 }
448}
449
450int
451yang_read_status(void *node, int value, int type, int line)
452{
453 int retval;
454
455 switch (type) {
456 case FEATURE_KEYWORD:
457 retval = yang_check_flags(&((struct lys_feature *) node)->flags, LYS_STATUS_MASK, "status", "feature", value, line);
458 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100459 case IDENTITY_KEYWORD:
Pavol Vicanbbdef532016-02-09 14:52:12 +0100460 retval = yang_check_flags(&((struct lys_ident *) node)->flags, LYS_STATUS_MASK, "status", "identity", value, line);
461 break;
Pavol Vican7c8ae122016-02-10 11:01:50 +0100462 case CONTAINER_KEYWORD:
463 retval = yang_check_flags(&((struct lys_node_container *) node)->flags, LYS_STATUS_MASK, "status", "container", value, line);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100464 break;
465 case ANYXML_KEYWORD:
466 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "anyxml", value, line);
467 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100468 case CHOICE_KEYWORD:
469 retval = yang_check_flags(&((struct lys_node_anyxml *) node)->flags, LYS_STATUS_MASK, "status", "choice", value, line);
470 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100471 case CASE_KEYWORD:
472 retval = yang_check_flags(&((struct lys_node_case *) node)->flags, LYS_STATUS_MASK, "status", "case", value, line);
473 break;
Pavol Vican12f53c32016-02-11 11:40:00 +0100474 case GROUPING_KEYWORD:
475 retval = yang_check_flags(&((struct lys_node_grp *) node)->flags, LYS_STATUS_MASK, "status", "grouping", value, line);
476 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100477 case LEAF_KEYWORD:
478 retval = yang_check_flags(&((struct lys_node_leaf *) node)->flags, LYS_STATUS_MASK, "status", "leaf", value, line);
479 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100480 case LEAF_LIST_KEYWORD:
481 retval = yang_check_flags(&((struct lys_node_leaflist *) node)->flags, LYS_STATUS_MASK, "status", "leaflist", value, line);
482 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100483 case LIST_KEYWORD:
484 retval = yang_check_flags(&((struct lys_node_list *) node)->flags, LYS_STATUS_MASK, "status", "list", value, line);
485 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100486 case ENUM_KEYWORD:
487 retval = yang_check_flags(&((struct lys_type_enum *) node)->flags, LYS_STATUS_MASK, "status", "enum", value, line);
Pavol Vican9887c682016-02-29 11:32:01 +0100488 break;
489 case BIT_KEYWORD:
490 retval = yang_check_flags(&((struct lys_type_bit *) node)->flags, LYS_STATUS_MASK, "status", "bit", value, line);
491 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100492 case TYPEDEF_KEYWORD:
493 retval = yang_check_flags(&((struct lys_tpdf *) node)->flags, LYS_STATUS_MASK, "status", "typedef", value, line);
494 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100495 case USES_KEYWORD:
496 retval = yang_check_flags(&((struct lys_node_uses *) node)->flags, LYS_STATUS_MASK, "status", "uses", value, line);
497 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100498 case AUGMENT_KEYWORD:
499 retval = yang_check_flags(&((struct lys_node_augment *) node)->flags, LYS_STATUS_MASK, "status", "augment", value, line);
500 break;
Pavol Vican52ed67d2016-03-02 17:46:15 +0100501 case RPC_KEYWORD:
502 retval = yang_check_flags(&((struct lys_node_rpc *) node)->flags, LYS_STATUS_MASK, "status", "rpc", value, line);
503 break;
Pavol Vicane1354e92016-02-09 14:02:09 +0100504 }
505 return retval;
506}
Pavol Vicanbbdef532016-02-09 14:52:12 +0100507
508void *
509yang_read_identity(struct lys_module *module, char *value)
510{
511 struct lys_ident *ret;
512
513 ret = &module->ident[module->ident_size];
514 ret->name = lydict_insert_zc(module->ctx, value);
515 ret->module = module;
516 module->ident_size++;
517 return ret;
518}
519
520int
521yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres, int line)
522{
523 const char *exp;
524
525 if (ident->base) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100526 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, "base", "identity");
Pavol Vicanbbdef532016-02-09 14:52:12 +0100527 return EXIT_FAILURE;
528 }
Pavol Vicanbbdef532016-02-09 14:52:12 +0100529 exp = transform_schema2json(module, value, line);
530 free(value);
531 if (!exp) {
532 return EXIT_FAILURE;
533 }
534 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp, line) == -1) {
535 lydict_remove(module->ctx, exp);
536 return EXIT_FAILURE;
537 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100538
539 /* hack - store some address due to detection of unresolved base*/
540 if (!ident->base) {
541 ident->base = (void *)1;
542 }
543
Pavol Vicanbbdef532016-02-09 14:52:12 +0100544 lydict_remove(module->ctx, exp);
545 return EXIT_SUCCESS;
546}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100547
548void *
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100549yang_read_must(struct lys_module *module, struct lys_node *node, char *value, int type, int line)
550{
551 struct lys_restr *retval;
552
553 switch (type) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100554 case CONTAINER_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100555 retval = &((struct lys_node_container *)node)->must[((struct lys_node_container *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100556 break;
557 case ANYXML_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100558 retval = &((struct lys_node_anyxml *)node)->must[((struct lys_node_anyxml *)node)->must_size++];
559 break;
560 case LEAF_KEYWORD:
561 retval = &((struct lys_node_leaf *)node)->must[((struct lys_node_leaf *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100562 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100563 case LEAF_LIST_KEYWORD:
564 retval = &((struct lys_node_leaflist *)node)->must[((struct lys_node_leaflist *)node)->must_size++];
565 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100566 case LIST_KEYWORD:
567 retval = &((struct lys_node_list *)node)->must[((struct lys_node_list *)node)->must_size++];
568 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100569 case REFINE_KEYWORD:
570 retval = &((struct lys_refine *)node)->must[((struct lys_refine *)node)->must_size++];
571 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100572 }
573 retval->expr = transform_schema2json(module, value, line);
574 if (!retval->expr || lyxp_syntax_check(retval->expr, line)) {
575 goto error;
576 }
577 free(value);
578 return retval;
579
580error:
581 free(value);
582 return NULL;
583}
584
585int
586yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, int type, int message, int line)
587{
588 int ret;
589 char *exp;
590
591 switch (type) {
592 case MUST_KEYWORD:
593 exp = "must";
594 break;
Pavol Vican73e7c992016-02-24 12:18:05 +0100595 case LENGTH_KEYWORD:
596 exp = "length";
597 break;
Pavol Vican1c203db2016-02-24 14:05:23 +0100598 case PATTERN_KEYWORD:
599 exp = "pattern";
600 break;
Pavol Vicanaff5c802016-02-24 15:56:45 +0100601 case RANGE_KEYWORD:
602 exp = "range";
603 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100604 }
605 if (message==ERROR_APP_TAG_KEYWORD) {
606 ret = yang_check_string(module, &save->eapptag, "error_app_tag", exp, value, line);
607 } else {
608 ret = yang_check_string(module, &save->emsg, "error_app_tag", exp, value, line);
609 }
610 return ret;
611}
Pavol Vicanb5687112016-02-09 22:35:59 +0100612
613int
614yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value, int line)
615{
616 if (cont->presence) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100617 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100618 free(value);
619 return EXIT_FAILURE;
620 } else {
621 cont->presence = lydict_insert_zc(module->ctx, value);
622 return EXIT_SUCCESS;
623 }
624}
625
626int
627yang_read_config(void *node, int value, int type, int line)
628{
629 int ret;
630
631 switch (type) {
632 case CONTAINER_KEYWORD:
633 ret = yang_check_flags(&((struct lys_node_container *)node)->flags, LYS_CONFIG_MASK, "config", "container", value, line);
634 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100635 case ANYXML_KEYWORD:
636 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_CONFIG_MASK, "config", "anyxml", value, line);
637 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100638 case CHOICE_KEYWORD:
639 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_CONFIG_MASK, "config", "choice", value, line);
640 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100641 case LEAF_KEYWORD:
642 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_CONFIG_MASK, "config", "leaf", value, line);
643 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100644 case LEAF_LIST_KEYWORD:
Pavol Vican5de33492016-02-22 14:03:24 +0100645 ret = yang_check_flags(&((struct lys_node_leaflist *)node)->flags, LYS_CONFIG_MASK, "config", "leaflist", value, line);
646 break;
647 case LIST_KEYWORD:
648 ret = yang_check_flags(&((struct lys_node_list *)node)->flags, LYS_CONFIG_MASK, "config", "list", value, line);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100649 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100650 case REFINE_KEYWORD:
651 ret = yang_check_flags(&((struct lys_refine *)node)->flags, LYS_CONFIG_MASK, "config", "refine", value, line);
652 break;
Pavol Vicanb5687112016-02-09 22:35:59 +0100653 }
654 return ret;
655}
Pavol Vican235dbd42016-02-10 10:34:19 +0100656
657void *
658yang_read_when(struct lys_module *module, struct lys_node *node, int type, char *value, int line)
659{
660 struct lys_when *retval;
661
662 retval = calloc(1, sizeof *retval);
663 if (!retval) {
664 LOGMEM;
665 free(value);
666 return NULL;
667 }
668 retval->cond = transform_schema2json(module, value, line);
669 if (!retval->cond || lyxp_syntax_check(retval->cond, line)) {
670 goto error;
671 }
672 switch (type) {
673 case CONTAINER_KEYWORD:
674 if (((struct lys_node_container *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100675 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100676 goto error;
677 }
678 ((struct lys_node_container *)node)->when = retval;
679 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100680 case ANYXML_KEYWORD:
Pavol Vican8c82fa82016-02-10 13:13:24 +0100681 if (((struct lys_node_anyxml *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100682 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "anyxml");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100683 goto error;
684 }
685 ((struct lys_node_anyxml *)node)->when = retval;
686 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100687 case CHOICE_KEYWORD:
688 if (((struct lys_node_choice *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100689 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100690 goto error;
691 }
692 ((struct lys_node_choice *)node)->when = retval;
693 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100694 case CASE_KEYWORD:
695 if (((struct lys_node_case *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100696 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100697 goto error;
698 }
699 ((struct lys_node_case *)node)->when = retval;
700 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100701 case LEAF_KEYWORD:
702 if (((struct lys_node_leaf *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100703 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100704 goto error;
705 }
706 ((struct lys_node_leaf *)node)->when = retval;
707 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100708 case LEAF_LIST_KEYWORD:
709 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vicand72227c2016-02-21 20:29:52 +0100710 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100711 goto error;
712 }
713 ((struct lys_node_leaflist *)node)->when = retval;
714 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100715 case LIST_KEYWORD:
716 if (((struct lys_node_list *)node)->when) {
717 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "list");
718 goto error;
719 }
720 ((struct lys_node_list *)node)->when = retval;
721 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100722 case USES_KEYWORD:
723 if (((struct lys_node_uses *)node)->when) {
724 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "uses");
725 goto error;
726 }
727 ((struct lys_node_uses *)node)->when = retval;
728 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100729 case AUGMENT_KEYWORD:
730 if (((struct lys_node_augment *)node)->when) {
731 LOGVAL(LYE_TOOMANY, line, LY_VLOG_LYS, node, "when", "augment");
732 goto error;
733 }
734 ((struct lys_node_augment *)node)->when = retval;
735 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100736 }
737 free(value);
738 return retval;
739
740error:
741 free(value);
742 lys_when_free(module->ctx, retval);
743 return NULL;
744}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100745
746void *
Pavol Vican7cadfe72016-02-11 12:33:34 +0100747yang_read_node(struct lys_module *module, struct lys_node *parent, char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100748{
Pavol Vican7cadfe72016-02-11 12:33:34 +0100749 struct lys_node *node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100750
Pavol Vican7cadfe72016-02-11 12:33:34 +0100751 node = calloc(1, sizeof_struct);
752 if (!node) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100753 LOGMEM;
754 return NULL;
755 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100756 node->module = module;
757 node->name = lydict_insert_zc(module->ctx, value);
758 node->nodetype = nodetype;
759 node->prev = node;
760
761 /* insert the node into the schema tree */
762 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
763 lydict_remove(module->ctx, node->name);
764 free(node);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100765 return NULL;
766 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100767 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100768}
769
770int
771yang_read_mandatory(void *node, int value, int type, int line)
772{
773 int ret;
774
775 switch (type) {
776 case ANYXML_KEYWORD:
777 ret = yang_check_flags(&((struct lys_node_anyxml *)node)->flags, LYS_MAND_MASK, "mandatory", "anyxml", value, line);
778 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100779 case CHOICE_KEYWORD:
780 ret = yang_check_flags(&((struct lys_node_choice *)node)->flags, LYS_MAND_MASK, "mandatory", "choice", value, line);
781 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100782 case LEAF_KEYWORD:
783 ret = yang_check_flags(&((struct lys_node_leaf *)node)->flags, LYS_MAND_MASK, "mandatory", "leaf", value, line);
784 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100785 case REFINE_KEYWORD:
786 ret = yang_check_flags(&((struct lys_refine *)node)->flags, LYS_MAND_MASK, "mandatory", "refine", value, line);
787 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100788 }
789 return ret;
790}
791
792int
793yang_read_default(struct lys_module *module, void *node, char *value, int type, int line)
794{
795 int ret;
796
797 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100798 case LEAF_KEYWORD:
799 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, line);
800 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100801 case TYPEDEF_KEYWORD:
802 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, line);
803 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100804 }
805 return ret;
806}
807
808int
809yang_read_units(struct lys_module *module, void *node, char *value, int type, int line)
810{
811 int ret;
812
813 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100814 case LEAF_KEYWORD:
815 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, line);
816 break;
817 case LEAF_LIST_KEYWORD:
818 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, line);
819 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100820 case TYPEDEF_KEYWORD:
821 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, line);
822 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100823 }
824 return ret;
825}
Pavol Vican5de33492016-02-22 14:03:24 +0100826
827int
828yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres, int line)
829{
830 char *exp, *value;
831
832 exp = value = (char *) list->keys;
833 while ((value = strpbrk(value, " \t\n"))) {
834 list->keys_size++;
835 while (isspace(*value)) {
836 value++;
837 }
838 }
839 list->keys_size++;
840 list->keys = calloc(list->keys_size, sizeof *list->keys);
841 if (!list->keys) {
842 LOGMEM;
843 goto error;
844 }
845 if (unres_schema_add_str(module, unres, list, UNRES_LIST_KEYS, exp, line) == -1) {
846 goto error;
847 }
848 free(exp);
849 return EXIT_SUCCESS;
850
851error:
852 free(exp);
853 return EXIT_FAILURE;
854}
855
856int
857yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
858{
859 uint8_t k;
860 int i, j;
861 char *value, *vaux;
862 struct lys_unique *unique;
863 struct type_ident *ident;
864
865 for(k=0; k<list->unique_size; k++) {
866 unique = &list->unique[k];
867 ident = (struct type_ident *)list->unique[k].expr;
868
869 /* count the number of unique leafs in the value */
870 vaux = value = ident->s;
871 while ((vaux = strpbrk(vaux, " \t\n"))) {
872 unique->expr_size++;
873 while (isspace(*vaux)) {
874 vaux++;
875 }
876 }
877 unique->expr_size++;
878 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
879 if (!unique->expr) {
880 LOGMEM;
881 goto error;
882 }
883
884 for (i = 0; i < unique->expr_size; i++) {
885 vaux = strpbrk(value, " \t\n");
886 if (!vaux) {
887 /* the last token, lydict_insert() will count its size on its own */
888 vaux = value;
889 }
890
891 /* store token into unique structure */
892 unique->expr[i] = lydict_insert(module->ctx, value, vaux - value);
893
894 /* check that the expression does not repeat */
895 for (j = 0; j < i; j++) {
896 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
897 LOGVAL(LYE_INARG, ident->line, LY_VLOG_LYS, list, unique->expr[i], "unique");
898 LOGVAL(LYE_SPEC, 0, 0, NULL, "The identifier is not unique");
899 goto error;
900 }
901 }
902
903 /* try to resolve leaf */
904 if (unres) {
905 unres_schema_add_str(module, unres, (struct lys_node *)list, UNRES_LIST_UNIQ, unique->expr[i], ident->line);
906 } else {
907 if (resolve_unique((struct lys_node *)list, value, 0, ident->line)) {
908 goto error;
909 }
910 }
911
912 /* move to next token */
913 value = vaux;
914 while(isspace(*value)) {
915 value++;
916 }
917 }
918 free(ident);
919 }
920 return EXIT_SUCCESS;
921
922error:
923 free(ident);
924 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100925}
926
Pavol Vican1ff0e222016-02-26 12:27:01 +0100927static int
928yang_read_identyref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres, int line)
929{
930 const char *value, *tmp;
931 int rc, ret = EXIT_FAILURE;
932
933 value = tmp = type->info.lref.path;
934 /* store in the JSON format */
935 value = transform_schema2json(module, value, line);
936 if (!value) {
937 goto end;
938 }
939 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value, line);
940 lydict_remove(module->ctx, value);
941
942 if (rc == -1) {
943 goto end;
944 }
945
946 ret = EXIT_SUCCESS;
947
948end:
949 lydict_remove(module->ctx, tmp);
950 return ret;
951}
952
Pavol Vican73e7c992016-02-24 12:18:05 +0100953int
954yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct unres_schema *unres)
955{
956 int i, rc;
957 int ret = -1;
958 const char *name, *value;
959 LY_DATA_TYPE base;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100960 struct yang_type *typ_tmp;
Pavol Vican73e7c992016-02-24 12:18:05 +0100961
Pavol Vican0df02b02016-03-01 10:28:50 +0100962 base = typ->type->base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100963 value = transform_schema2json(module, typ->name, typ->line);
964 if (!value) {
965 goto error;
966 }
967
968 i = parse_identifier(value);
969 if (i < 1) {
970 LOGVAL(LYE_INCHAR, typ->line, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
971 lydict_remove(module->ctx, value);
972 goto error;
973 }
974 /* module name*/
975 name = value;
976 if (value[i]) {
977 typ->type->module_name = lydict_insert(module->ctx, value, i);
978 name += i;
979 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
980 LOGVAL(LYE_INCHAR, typ->line, LY_VLOG_NONE, NULL, name[0], name);
981 lydict_remove(module->ctx, value);
982 goto error;
983 }
984 ++name;
985 }
986
987 rc = resolve_superior_type(name, typ->type->module_name, module, parent, &typ->type->der);
988 lydict_remove(module->ctx, value);
989 if (rc == -1) {
990 LOGVAL(LYE_INMOD, typ->line, LY_VLOG_NONE, NULL, typ->type->module_name);
991 goto error;
992
993 /* the type could not be resolved or it was resolved to an unresolved typedef*/
994 } else if (rc == EXIT_FAILURE) {
995 ret = EXIT_FAILURE;
996 goto error;
997 }
Pavol Vican73e7c992016-02-24 12:18:05 +0100998 typ->type->base = typ->type->der->type.base;
999 if (base == 0) {
Pavol Vican07ea68d2016-02-25 12:01:37 +01001000 base = typ->type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +01001001 }
1002 switch (base) {
1003 case LY_TYPE_STRING:
1004 if (typ->type->base == LY_TYPE_BINARY) {
1005 if (typ->type->info.str.pat_count) {
1006 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001007 typ->type->base = base;
Pavol Vican73e7c992016-02-24 12:18:05 +01001008 goto error;
1009 }
1010 typ->type->info.binary.length = typ->type->info.str.length;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001011 if (typ->type->info.binary.length && lyp_check_length_range(typ->type->info.binary.length->expr, typ->type)) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001012 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.binary.length->expr, "length");
1013 goto error;
1014 }
1015 } else if (typ->type->base == LY_TYPE_STRING) {
Pavol Vican07ea68d2016-02-25 12:01:37 +01001016 if (typ->type->info.str.length && lyp_check_length_range(typ->type->info.str.length->expr, typ->type)) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001017 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.str.length->expr, "length");
1018 goto error;
1019 }
Pavol Vicanaff5c802016-02-24 15:56:45 +01001020 } else {
1021 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1022 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001023 }
Pavol Vicanaff5c802016-02-24 15:56:45 +01001024 break;
1025 case LY_TYPE_DEC64:
1026 if (typ->type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +01001027 if (typ->type->info.dec64.range && lyp_check_length_range(typ->type->info.dec64.range->expr, typ->type)) {
Pavol Vicanaff5c802016-02-24 15:56:45 +01001028 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.dec64.range->expr, "range");
1029 goto error;
1030 }
Pavol Vican07ea68d2016-02-25 12:01:37 +01001031 /* mandatory sub-statement(s) check */
1032 if (!typ->type->info.dec64.dig && !typ->type->der->type.der) {
1033 /* decimal64 type directly derived from built-in type requires fraction-digits */
1034 LOGVAL(LYE_MISSSTMT2, typ->line, LY_VLOG_NONE, NULL, "fraction-digits", "type");
1035 goto error;
1036 }
1037 if (typ->type->info.dec64.dig && typ->type->der->type.der) {
1038 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
1039 LOGVAL(LYE_INSTMT, typ->line, LY_VLOG_NONE, NULL, "fraction-digits");
1040 goto error;
1041 }
Pavol Vicanaff5c802016-02-24 15:56:45 +01001042 } else if (typ->type->base >= LY_TYPE_INT8 && typ->type->base <=LY_TYPE_UINT64) {
1043 if (typ->type->info.dec64.dig) {
1044 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
1045 typ->type->base = base;
1046 goto error;
1047 }
1048 typ->type->info.num.range = typ->type->info.dec64.range;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001049 if (typ->type->info.num.range && lyp_check_length_range(typ->type->info.num.range->expr, typ->type)) {
Pavol Vicanaff5c802016-02-24 15:56:45 +01001050 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.num.range->expr, "range");
1051 goto error;
1052 }
1053 } else {
1054 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1055 goto error;
1056 }
1057 break;
Pavol Vican79a763d2016-02-25 15:41:27 +01001058 case LY_TYPE_ENUM:
1059 if (typ->type->base != LY_TYPE_ENUM) {
1060 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1061 goto error;
1062 }
1063 if (!typ->type->der->type.der && !typ->type->info.enums.count) {
1064 /* type is derived directly from buit-in enumeartion type and enum statement is required */
1065 LOGVAL(LYE_MISSSTMT2, typ->line, LY_VLOG_NONE, NULL, "enum", "type");
1066 goto error;
1067 }
1068 if (typ->type->der->type.der && typ->type->info.enums.count) {
1069 /* type is not directly derived from buit-in enumeration type and enum statement is prohibited */
1070 LOGVAL(LYE_INSTMT, typ->line, LY_VLOG_NONE, NULL, "enum");
1071 goto error;
1072 }
Pavol Vican1ff0e222016-02-26 12:27:01 +01001073 break;
1074 case LY_TYPE_LEAFREF:
1075 if (typ->type->base == LY_TYPE_IDENT && typ->flags & LYS_TYPE_BASE) {
1076 if (yang_read_identyref(module, typ->type, unres, typ->line)) {
1077 goto error;
1078 }
Pavol Vican191613a2016-02-26 16:21:32 +01001079 } else if (typ->type->base == LY_TYPE_LEAFREF) {
1080 if (typ->type->info.lref.path && !typ->type->der->type.der) {
1081 value = typ->type->info.lref.path;
1082 /* store in the JSON format */
1083 typ->type->info.lref.path = transform_schema2json(module, value, typ->line);
1084 lydict_remove(module->ctx, value);
1085 if (!typ->type->info.lref.path) {
1086 goto error;
1087 }
1088 if (unres_schema_add_node(module, unres, typ->type, UNRES_TYPE_LEAFREF, parent, typ->line) == -1) {
1089 goto error;
1090 }
1091 } else if (!typ->type->info.lref.path && !typ->type->der->type.der) {
1092 LOGVAL(LYE_MISSSTMT2, typ->line, LY_VLOG_NONE, NULL, "path", "type");
1093 goto error;
1094 } else {
1095 LOGVAL(LYE_INSTMT, typ->line, LY_VLOG_NONE, NULL, "path");
1096 goto error;
1097 }
Pavol Vican1ff0e222016-02-26 12:27:01 +01001098 } else {
1099 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1100 goto error;
1101 }
1102 break;
1103 case LY_TYPE_IDENT:
1104 if (typ->type->der->type.der) {
1105 /* this is just a derived type with no base specified/required */
1106 break;
1107 } else {
1108 LOGVAL(LYE_MISSSTMT2, typ->line, LY_VLOG_NONE, NULL, "base", "type");
1109 goto error;
1110 }
1111 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001112 case LY_TYPE_UNION:
1113 if (typ->type->base != LY_TYPE_UNION) {
1114 typ->type->base = LY_TYPE_UNION;
1115 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1116 goto error;
1117 }
1118 if (!typ->type->info.uni.types) {
1119 if (typ->type->der->type.der) {
1120 /* this is just a derived type with no additional type specified/required */
1121 break;
1122 }
1123 LOGVAL(LYE_MISSSTMT2, typ->line, LY_VLOG_NONE, NULL, "type", "(union) type");
1124 goto error;
1125 }
1126 for (i = 0; i < typ->type->info.uni.count; i++) {
1127 typ_tmp = (struct yang_type *)typ->type->info.uni.types[i].der;
1128 if (unres_schema_add_node(module, unres, &typ->type->info.uni.types[i], UNRES_TYPE_DER, parent, typ_tmp->line)) {
1129 goto error;
1130 }
1131 if (typ->type->info.uni.types[i].base == LY_TYPE_EMPTY) {
1132 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, "empty", typ->name);
1133 goto error;
1134 } else if (typ->type->info.uni.types[i].base == LY_TYPE_LEAFREF) {
1135 LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, "leafref", typ->name);
1136 goto error;
1137 }
1138 }
1139 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001140
1141 default:
1142 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
1143 if (typ->type->base != base) {
1144 LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
1145 goto error;
1146 }
1147 } else {
1148 LOGINT;
1149 goto error;
1150 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001151 }
1152 return EXIT_SUCCESS;
1153
1154error:
Pavol Vicana1827962016-02-29 15:39:42 +01001155 typ->type->base = base;
Pavol Vican73e7c992016-02-24 12:18:05 +01001156 if (typ->type->module_name) {
1157 lydict_remove(module->ctx, typ->type->module_name);
1158 typ->type->module_name = NULL;
1159 }
1160 return ret;
1161}
1162
1163void *
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001164yang_read_type(void *parent, char *value, int type, int line)
Pavol Vican73e7c992016-02-24 12:18:05 +01001165{
1166 struct yang_type *typ;
Pavol Vican73e7c992016-02-24 12:18:05 +01001167
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001168 typ = calloc(1, sizeof *typ);
1169 if (!typ) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001170 LOGMEM;
1171 return NULL;
1172 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001173
1174 typ->flags = LY_YANG_STRUCTURE_FLAG;
1175 switch (type) {
1176 case LEAF_KEYWORD:
1177 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1178 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1179 typ->type = &((struct lys_node_leaf *)parent)->type;
1180 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001181 case LEAF_LIST_KEYWORD:
1182 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1183 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1184 typ->type = &((struct lys_node_leaflist *)parent)->type;
1185 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001186 case UNION_KEYWORD:
1187 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1188 typ->type = (struct lys_type *)parent;
1189 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001190 case TYPEDEF_KEYWORD:
1191 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1192 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican73e7c992016-02-24 12:18:05 +01001193 }
1194 typ->name = value;
1195 typ->line = line;
Pavol Vican73e7c992016-02-24 12:18:05 +01001196 return typ;
1197}
1198
1199void *
1200yang_read_length(struct lys_module *module, struct yang_type *typ, char *value, int line)
1201{
1202 struct lys_restr **length;
1203
1204 if (typ->type->base == 0 || typ->type->base == LY_TYPE_STRING) {
1205 length = &typ->type->info.str.length;
1206 typ->type->base = LY_TYPE_STRING;
1207 } else if (typ->type->base == LY_TYPE_BINARY) {
1208 length = &typ->type->info.binary.length;
1209 } else {
1210 LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Unexpected length statement.");
1211 goto error;
1212 }
1213
1214 if (*length) {
1215 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, "length", "type");
1216 }
1217 *length = calloc(1, sizeof **length);
1218 if (!*length) {
1219 LOGMEM;
1220 goto error;
1221 }
1222 (*length)->expr = lydict_insert_zc(module->ctx, value);
1223 return *length;
1224
1225error:
1226 free(value);
1227 return NULL;
1228
1229}
Pavol Vican1c203db2016-02-24 14:05:23 +01001230
1231void *
1232yang_read_pattern(struct lys_module *module, struct yang_type *typ, char *value, int line)
1233{
1234 pcre *precomp;
1235 int err_offset;
1236 const char *err_ptr;
1237
1238 /* check that the regex is valid */
1239 precomp = pcre_compile(value, PCRE_NO_AUTO_CAPTURE, &err_ptr, &err_offset, NULL);
1240 if (!precomp) {
1241 LOGVAL(LYE_INREGEX, line, LY_VLOG_NONE, NULL, value, err_ptr);
1242 free(value);
1243 return NULL;
1244 }
1245 free(precomp);
1246
1247 typ->type->info.str.patterns[typ->type->info.str.pat_count].expr = lydict_insert_zc(module->ctx, value);
1248 typ->type->info.str.pat_count++;
1249 return &typ->type->info.str.patterns[typ->type->info.str.pat_count-1];
1250}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001251
1252void *
1253yang_read_range(struct lys_module *module, struct yang_type *typ, char *value, int line)
1254{
1255 if (typ->type->base != 0 && typ->type->base != LY_TYPE_DEC64) {
1256 LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Unexpected range statement.");
1257 goto error;
1258 }
1259 typ->type->base = LY_TYPE_DEC64;
1260 if (typ->type->info.dec64.range) {
1261 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, "range", "type");
1262 goto error;
1263 }
1264 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1265 if (!typ->type->info.dec64.range) {
1266 LOGMEM;
1267 goto error;
1268 }
1269 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1270 return typ->type->info.dec64.range;
1271
1272error:
1273 free(value);
1274 return NULL;
1275}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001276
1277int
1278yang_read_fraction(struct yang_type *typ, uint32_t value, int line)
1279{
1280 if (typ->type->base == 0 || typ->type->base == LY_TYPE_DEC64) {
1281 typ->type->base = LY_TYPE_DEC64;
1282 } else {
1283 LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
1284 goto error;
1285 }
1286 if (typ->type->info.dec64.dig) {
1287 LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, "fraction-digits", "type");
1288 goto error;
1289 }
1290 /* range check */
1291 if (value < 1 || value > 18) {
1292 LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
1293 goto error;
1294 }
1295 typ->type->info.dec64.dig = value;
1296 return EXIT_SUCCESS;
1297
1298error:
1299 return EXIT_FAILURE;
1300}
Pavol Vican79a763d2016-02-25 15:41:27 +01001301
1302void *
1303yang_read_enum(struct lys_module *module, struct yang_type *typ, char *value, int line)
1304{
1305 struct lys_type_enum *enm;
1306 int i;
1307
1308 enm = &typ->type->info.enums.enm[typ->type->info.enums.count];
1309 enm->name = lydict_insert_zc(module->ctx, value);
1310
1311 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1312 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
1313 LOGVAL(LYE_ENUM_WS, line, LY_VLOG_NONE, NULL, enm->name);
1314 goto error;
1315 }
1316
1317 /* check the name uniqueness */
1318 for (i = 0; i < typ->type->info.enums.count; i++) {
1319 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[typ->type->info.enums.count].name)) {
1320 LOGVAL(LYE_ENUM_DUPNAME, line, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
1321 goto error;
1322 }
1323 }
1324
1325 typ->type->info.enums.count++;
1326 return enm;
1327
1328error:
1329 typ->type->info.enums.count++;
1330 return NULL;
1331}
1332
1333int
1334yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign, int line)
1335{
1336 int i, j;
1337
1338 if (!assign) {
1339 /* assign value automatically */
1340 if (*value > INT32_MAX) {
1341 LOGVAL(LYE_INARG, line, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
1342 goto error;
1343 }
1344 enm->value = *value;
1345 enm->flags |= LYS_AUTOASSIGNED;
1346 (*value)++;
1347 }
1348
1349 /* check that the value is unique */
1350 j = typ->type->info.enums.count-1;
1351 for (i = 0; i < j; i++) {
1352 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
1353 LOGVAL(LYE_ENUM_DUPVAL, line, LY_VLOG_NONE, NULL,
1354 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name);
1355 goto error;
1356 }
1357 }
1358
1359 return EXIT_SUCCESS;
1360
1361error:
1362 return EXIT_FAILURE;
1363}
Pavol Vican9887c682016-02-29 11:32:01 +01001364
1365void *
1366yang_read_bit(struct lys_module *module, struct yang_type *typ, char *value, int line)
1367{
1368 int i;
1369 struct lys_type_bit *bit;
1370
1371 bit = &typ->type->info.bits.bit[typ->type->info.bits.count];
1372 if (lyp_check_identifier(value, LY_IDENT_SIMPLE, line, NULL, NULL)) {
1373 LOGVAL(LYE_PATH, 0, LY_VLOG_NONE, NULL);
1374 free(value);
1375 goto error;
1376 }
1377 bit->name = lydict_insert_zc(module->ctx, value);
1378
1379 /* check the name uniqueness */
1380 for (i = 0; i < typ->type->info.bits.count; i++) {
1381 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
1382 LOGVAL(LYE_BITS_DUPNAME, line, LY_VLOG_NONE, NULL, bit->name);
1383 typ->type->info.bits.count++;
1384 goto error;
1385 }
1386 }
1387 typ->type->info.bits.count++;
1388 return bit;
1389
1390error:
1391 return NULL;
1392}
1393
1394int
1395yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign, int line)
1396{
1397 int i,j;
1398 struct lys_type_bit bit_tmp;
1399
1400 if (!assign) {
1401 /* assign value automatically */
1402 if (*value > UINT32_MAX) {
1403 LOGVAL(LYE_INARG, line, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
1404 goto error;
1405 }
1406 bit->pos = (uint32_t)*value;
1407 bit->flags |= LYS_AUTOASSIGNED;
1408 (*value)++;
1409 }
1410
1411 j = typ->type->info.bits.count - 1;
1412 /* check that the value is unique */
1413 for (i = 0; i < j; i++) {
1414 if (typ->type->info.bits.bit[i].pos == bit->pos) {
1415 LOGVAL(LYE_BITS_DUPVAL, line, LY_VLOG_NONE, NULL, bit->pos, bit->name);
1416 goto error;
1417 }
1418 }
1419
1420 /* keep them ordered by position */
1421 while (j && typ->type->info.bits.bit[j - 1].pos > typ->type->info.bits.bit[j].pos) {
1422 /* switch them */
Pavol Vican9b032132016-02-29 15:18:38 +01001423 memcpy(&bit_tmp, &typ->type->info.bits.bit[j], sizeof bit_tmp);
1424 memcpy(&typ->type->info.bits.bit[j], &typ->type->info.bits.bit[j - 1], sizeof bit_tmp);
1425 memcpy(&typ->type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican9887c682016-02-29 11:32:01 +01001426 j--;
1427 }
1428
1429 return EXIT_SUCCESS;
1430
1431error:
1432 return EXIT_FAILURE;
1433}
Pavol Vican0df02b02016-03-01 10:28:50 +01001434
1435void *
1436yang_read_typedef(struct lys_module *module, struct lys_node *parent, char *value, int line)
1437{
1438 struct lys_tpdf *ret;
1439
1440 if (lyp_check_identifier(value, LY_IDENT_TYPE, line, module, parent)) {
1441 free(value);
1442 return NULL;
1443 }
1444 if (!parent) {
1445 ret = &module->tpdf[module->tpdf_size];
1446 ret->type.parent = NULL;
1447 module->tpdf_size++;
Pavol Vican21238f52016-03-01 12:39:52 +01001448 } else {
1449 switch (parent->nodetype) {
1450 case LYS_GROUPING:
1451 ret = &((struct lys_node_grp *)parent)->tpdf[((struct lys_node_grp *)parent)->tpdf_size];
Pavol Vican21238f52016-03-01 12:39:52 +01001452 ((struct lys_node_grp *)parent)->tpdf_size++;
1453 break;
Pavol Vican535d50e2016-03-01 13:05:33 +01001454 case LYS_CONTAINER:
1455 ret = &((struct lys_node_container *)parent)->tpdf[((struct lys_node_container *)parent)->tpdf_size];
1456 ((struct lys_node_container *)parent)->tpdf_size++;
1457 break;
Pavol Vican09f04b82016-03-01 14:02:28 +01001458 case LYS_LIST:
1459 ret = &((struct lys_node_list *)parent)->tpdf[((struct lys_node_list *)parent)->tpdf_size];
1460 ((struct lys_node_list *)parent)->tpdf_size++;
1461 break;
Pavol Vican52ed67d2016-03-02 17:46:15 +01001462 case LYS_RPC:
1463 ret = &((struct lys_node_rpc *)parent)->tpdf[((struct lys_node_rpc *)parent)->tpdf_size];
1464 ((struct lys_node_rpc *)parent)->tpdf_size++;
1465 break;
Pavol Vican21238f52016-03-01 12:39:52 +01001466 }
Pavol Vican535d50e2016-03-01 13:05:33 +01001467 ret->type.parent = (struct lys_tpdf *)parent;
Pavol Vican0df02b02016-03-01 10:28:50 +01001468 }
1469
1470 ret->name = lydict_insert_zc(module->ctx, value);
1471 ret->module = module;
1472 return ret;
1473}
Pavol Vican1003ead2016-03-02 12:24:52 +01001474
1475void *
1476yang_read_refine(struct lys_module *module, struct lys_node_uses *uses, char *value, int line)
1477{
1478 struct lys_refine *rfn;
1479
1480 rfn = &uses->refine[uses->refine_size];
1481 uses->refine_size++;
1482 rfn->target_name = transform_schema2json(module, value, line);
1483 free(value);
1484 if (!rfn->target_name) {
1485 return NULL;
1486 }
1487 return rfn;
1488}
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001489
1490void *
1491yang_read_augment(struct lys_module *module, struct lys_node *parent, char *value, int line)
1492{
1493 struct lys_node_augment *aug;
1494 uint16_t *size;
1495
1496 if (parent) {
1497 aug = &((struct lys_node_uses *)parent)->augment[((struct lys_node_uses *)parent)->augment_size];
1498 } else {
1499 aug = &module->augment[module->augment_size];
1500 }
1501 aug->nodetype = LYS_AUGMENT;
1502 aug->target_name = transform_schema2json(module, value, line);
1503 free(value);
1504 if (!aug->target_name) {
1505 return NULL;
1506 }
1507 aug->parent = parent;
1508 aug->module = module;
1509 if (parent) {
1510 ((struct lys_node_uses *)parent)->augment_size++;
1511 } else {
1512 module->augment_size++;
1513 }
1514 return aug;
1515}