blob: 85256fd58fa1013b05ffc0d5f3c3d93a5e0f099c [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 *
Pavol Vican9a3a7212016-03-23 10:04:00 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
Pavol Vican021488a2016-01-25 23:56:12 +010013 */
14
Pavol Vican5de33492016-02-22 14:03:24 +010015#include <ctype.h>
Pavol Vican7313fc02016-11-14 01:10:31 +010016#include <assert.h>
Pavol Vican021488a2016-01-25 23:56:12 +010017#include "parser_yang.h"
Pavol Vican8e7110b2016-03-22 17:00:26 +010018#include "parser_yang_lex.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010019#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010020#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010021
Pavol Vican082afd02016-10-25 12:39:15 +020022static void yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size);
23static void yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size);
Pavol Vican7313fc02016-11-14 01:10:31 +010024static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
Pavol Vican05810b62016-11-23 14:07:22 +010025static void free_yang_common(struct lys_module *module, struct lys_node *node);
Pavol Vican3ad50f82016-12-04 15:00:36 +010026static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
27 int config_opt, struct unres_schema *unres);
PavolVican8c33b152017-01-27 12:45:34 +010028void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size);
Pavol Vican082afd02016-10-25 12:39:15 +020029
Michal Vaskofe7e5a72016-05-02 14:49:23 +020030static int
PavolVican196694c2017-01-27 10:33:09 +010031yang_check_string(struct lys_module *module, const char **target, char *what,
32 char *where, char *value, struct lys_node *node)
Pavol Vican2a064652016-02-02 22:54:34 +010033{
Pavol Vicanbf805472016-01-26 14:24:56 +010034 if (*target) {
PavolVican196694c2017-01-27 10:33:09 +010035 LOGVAL(LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010036 free(value);
37 return 1;
38 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010039 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010040 return 0;
41 }
42}
43
Michal Vaskofe7e5a72016-05-02 14:49:23 +020044int
Pavol Vican5f0316a2016-04-05 21:21:11 +020045yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010046{
Pavol Vican6eb14e82016-02-03 12:27:13 +010047 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010048
49 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010050 case MODULE_KEYWORD:
51 module->name = lydict_insert_zc(module->ctx, value);
52 break;
53 case NAMESPACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010054 ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +010055 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010056 case ORGANIZATION_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010057 ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010058 break;
59 case CONTACT_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010060 ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010061 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020062 default:
63 free(value);
64 LOGINT;
65 ret = EXIT_FAILURE;
66 break;
Pavol Vican2a064652016-02-02 22:54:34 +010067 }
68
Pavol Vican021488a2016-01-25 23:56:12 +010069 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010070}
71
Michal Vaskofe7e5a72016-05-02 14:49:23 +020072int
Pavol Vicand0b64c12016-07-15 09:56:19 +020073yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
74{
75 int ret = EXIT_SUCCESS;
76
77 if (repeat) {
Michal Vasko3767fb22016-07-21 12:10:57 +020078 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
79 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020080 } else {
81 if (!strcmp(value, "1")) {
82 if (submodule) {
83 if (module->version > 1) {
84 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
85 ret = EXIT_FAILURE;
86 }
87 } else {
88 module->version = 1;
89 }
90 } else if (!strcmp(value, "1.1")) {
91 if (submodule) {
92 if (module->version != 2) {
93 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
94 ret = EXIT_FAILURE;
95 }
96 } else {
97 module->version = 2;
98 }
99 } else {
100 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
101 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200102 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200103 }
104 free(value);
105 return ret;
106}
107
108int
Pavol Vicane024ab72016-07-27 14:27:43 +0200109yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100110{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100111 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100112
Pavol Vican1cc4e192016-10-24 16:38:31 +0200113 if (!imp && lyp_check_identifier(value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100114 free(value);
115 return EXIT_FAILURE;
116 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200117
118 if (imp) {
PavolVican196694c2017-01-27 10:33:09 +0100119 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
Pavol Vicane024ab72016-07-27 14:27:43 +0200120 } else {
PavolVican196694c2017-01-27 10:33:09 +0100121 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +0100122 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100123
Pavol Vicanbf805472016-01-26 14:24:56 +0100124 return ret;
125}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100126
Pavol Vican1cc4e192016-10-24 16:38:31 +0200127static int
PavolVican7d0b5ab2017-02-01 13:06:53 +0100128yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
129 char *value, struct unres_schema *unres)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100130{
Pavol Vican0da132e2016-03-21 12:03:03 +0100131 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200132 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100133
Pavol Vican1cc4e192016-10-24 16:38:31 +0200134 if (!imp_old->prefix) {
Pavol Vicane024ab72016-07-27 14:27:43 +0200135 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200136 goto error;
137 } else {
138 if (lyp_check_identifier(imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
139 goto error;
140 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200141 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100143 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200144 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100145 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200146 module->imp_size++;
PavolVican7d0b5ab2017-02-01 13:06:53 +0100147 if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200148 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100149 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100150
Pavol Vican6eb14e82016-02-03 12:27:13 +0100151 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200152
153error:
154 free(value);
155 lydict_remove(module->ctx, imp_old->dsc);
156 lydict_remove(module->ctx, imp_old->ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +0100157 lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200158 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100159}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100160
161int
PavolVican196694c2017-01-27 10:33:09 +0100162yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100163{
164 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100165 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100166
PavolVican196694c2017-01-27 10:33:09 +0100167 switch (type) {
168 case MODULE_KEYWORD:
169 ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
170 break;
171 case REVISION_KEYWORD:
172 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
173 break;
174 case IMPORT_KEYWORD:
175 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
176 break;
177 case INCLUDE_KEYWORD:
178 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
179 break;
180 case NODE_PRINT:
181 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
182 break;
183 default:
184 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
185 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100186 }
187 return ret;
188}
189
190int
PavolVican196694c2017-01-27 10:33:09 +0100191yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100192{
193 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100194 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100195
PavolVican196694c2017-01-27 10:33:09 +0100196 switch (type) {
197 case MODULE_KEYWORD:
198 ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
199 break;
200 case REVISION_KEYWORD:
201 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
202 break;
203 case IMPORT_KEYWORD:
204 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
205 break;
206 case INCLUDE_KEYWORD:
207 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
208 break;
209 case NODE_PRINT:
210 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
211 break;
212 default:
213 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
214 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100215 }
216 return ret;
217}
Pavol Vicanbedff692016-02-03 14:29:17 +0100218
PavolVican171717d2017-02-01 14:49:55 +0100219void *
Pavol Vican866d9912016-10-25 09:13:30 +0200220yang_read_revision(struct lys_module *module, char *value, struct lys_revision *retval)
Pavol Vicanbedff692016-02-03 14:29:17 +0100221{
Pavol Vicanbedff692016-02-03 14:29:17 +0100222 /* first member of array is last revision */
Pavol Vican866d9912016-10-25 09:13:30 +0200223 if ((module->rev_size - 1) && strcmp(module->rev[0].date, value) < 0) {
PavolVican171717d2017-02-01 14:49:55 +0100224 memcpy(retval, &module->rev[0], sizeof *retval);
225 memset(&module->rev[0], 0, sizeof *retval);
Pavol Vicanbedff692016-02-03 14:29:17 +0100226 memcpy(module->rev[0].date, value, LY_REV_SIZE);
Pavol Vicanbedff692016-02-03 14:29:17 +0100227 retval = module->rev;
Pavol Vicanbedff692016-02-03 14:29:17 +0100228 } else {
229 memcpy(retval->date, value, LY_REV_SIZE);
230 }
Pavol Vicanbedff692016-02-03 14:29:17 +0100231 free(value);
PavolVican171717d2017-02-01 14:49:55 +0100232 return retval;
Pavol Vicanbedff692016-02-03 14:29:17 +0100233}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100234
235int
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100236yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
237 char *value, struct unres_schema *unres, int parent_is_feature)
Pavol Vicane1354e92016-02-09 14:02:09 +0100238{
239 const char *exp;
240 int ret;
241
Michal Vasko97b32be2016-07-25 10:59:53 +0200242 if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
243 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
244 free(value);
245 return EXIT_FAILURE;
246 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100247
Michal Vasko56d082c2016-10-25 14:00:42 +0200248 if (!(exp = transform_iffeat_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100249 free(value);
250 return EXIT_FAILURE;
251 }
252 free(value);
253
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100254 ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
Pavol Vicane1354e92016-02-09 14:02:09 +0100255 lydict_remove(module->ctx, exp);
Pavol Vicane1354e92016-02-09 14:02:09 +0100256
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100257 return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
Pavol Vicane1354e92016-02-09 14:02:09 +0100258}
259
Pavol Vican4fb66c92016-03-17 10:32:27 +0100260int
Radek Krejci4372b4e2016-04-14 17:42:16 +0200261yang_check_flags(uint16_t *flags, uint16_t mask, char *what, char *where, uint16_t value, int shortint)
Pavol Vicane1354e92016-02-09 14:02:09 +0100262{
263 if (*flags & mask) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100264 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, what, where);
Pavol Vicane1354e92016-02-09 14:02:09 +0100265 return EXIT_FAILURE;
266 } else {
Radek Krejci4372b4e2016-04-14 17:42:16 +0200267 if (shortint) {
268 *((uint8_t *)flags) |= (uint8_t)value;
269 } else {
270 *flags |= value;
271 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100272 return EXIT_SUCCESS;
273 }
274}
275
Pavol Vicanbbdef532016-02-09 14:52:12 +0100276int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100277yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100278{
279 const char *exp;
280
Pavol Vican0adf01d2016-03-22 12:29:33 +0100281 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100282 free(value);
283 if (!exp) {
284 return EXIT_FAILURE;
285 }
Pavol Vican4ffd0ab2016-08-27 16:35:04 +0200286
Pavol Vican0adf01d2016-03-22 12:29:33 +0100287 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100288 lydict_remove(module->ctx, exp);
289 return EXIT_FAILURE;
290 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100291
Pavol Vicanbbdef532016-02-09 14:52:12 +0100292 lydict_remove(module->ctx, exp);
293 return EXIT_SUCCESS;
294}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100295
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100296int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100297yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100298{
299 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100300
Pavol Vicandde090a2016-08-30 15:12:14 +0200301 if (message == ERROR_APP_TAG_KEYWORD) {
PavolVican196694c2017-01-27 10:33:09 +0100302 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100303 } else {
PavolVican196694c2017-01-27 10:33:09 +0100304 ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100305 }
306 return ret;
307}
Pavol Vicanb5687112016-02-09 22:35:59 +0100308
309int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100310yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100311{
312 if (cont->presence) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100313 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100314 free(value);
315 return EXIT_FAILURE;
316 } else {
317 cont->presence = lydict_insert_zc(module->ctx, value);
318 return EXIT_SUCCESS;
319 }
320}
321
Pavol Vican235dbd42016-02-10 10:34:19 +0100322void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200323yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100324{
325 struct lys_when *retval;
326
327 retval = calloc(1, sizeof *retval);
328 if (!retval) {
329 LOGMEM;
330 free(value);
331 return NULL;
332 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100333 retval->cond = transform_schema2json(module, value);
Michal Vasko508a50d2016-09-07 14:50:33 +0200334 if (!retval->cond) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100335 goto error;
336 }
337 switch (type) {
338 case CONTAINER_KEYWORD:
339 if (((struct lys_node_container *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100340 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100341 goto error;
342 }
343 ((struct lys_node_container *)node)->when = retval;
344 break;
Pavol Vicandb7489e2016-08-23 17:23:39 +0200345 case ANYDATA_KEYWORD:
Pavol Vican1f06ba82016-02-10 17:39:50 +0100346 case ANYXML_KEYWORD:
Radek Krejcibf2abff2016-08-23 15:51:52 +0200347 if (((struct lys_node_anydata *)node)->when) {
Pavol Vicandb7489e2016-08-23 17:23:39 +0200348 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100349 goto error;
350 }
Radek Krejcibf2abff2016-08-23 15:51:52 +0200351 ((struct lys_node_anydata *)node)->when = retval;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100352 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100353 case CHOICE_KEYWORD:
354 if (((struct lys_node_choice *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100355 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100356 goto error;
357 }
358 ((struct lys_node_choice *)node)->when = retval;
359 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100360 case CASE_KEYWORD:
361 if (((struct lys_node_case *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100362 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100363 goto error;
364 }
365 ((struct lys_node_case *)node)->when = retval;
366 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100367 case LEAF_KEYWORD:
368 if (((struct lys_node_leaf *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100369 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100370 goto error;
371 }
372 ((struct lys_node_leaf *)node)->when = retval;
373 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100374 case LEAF_LIST_KEYWORD:
375 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100376 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100377 goto error;
378 }
379 ((struct lys_node_leaflist *)node)->when = retval;
380 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100381 case LIST_KEYWORD:
382 if (((struct lys_node_list *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100383 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100384 goto error;
385 }
386 ((struct lys_node_list *)node)->when = retval;
387 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100388 case USES_KEYWORD:
389 if (((struct lys_node_uses *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100390 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100391 goto error;
392 }
393 ((struct lys_node_uses *)node)->when = retval;
394 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100395 case AUGMENT_KEYWORD:
396 if (((struct lys_node_augment *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100397 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100398 goto error;
399 }
400 ((struct lys_node_augment *)node)->when = retval;
401 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200402 default:
403 goto error;
404 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100405 }
406 free(value);
407 return retval;
408
409error:
410 free(value);
411 lys_when_free(module->ctx, retval);
412 return NULL;
413}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100414
415void *
Pavol Vican05810b62016-11-23 14:07:22 +0100416yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
417 char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100418{
Pavol Vican05810b62016-11-23 14:07:22 +0100419 struct lys_node *node, **child;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100420
Pavol Vican7cadfe72016-02-11 12:33:34 +0100421 node = calloc(1, sizeof_struct);
422 if (!node) {
Pavol Vicand1dbfda2016-03-21 10:03:58 +0100423 free(value);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100424 LOGMEM;
425 return NULL;
426 }
PavolVican196694c2017-01-27 10:33:09 +0100427 LOGDBG("YANG: parsing %s statement \"%s\"", strnodetype(nodetype), value);
428 node->name = lydict_insert_zc(module->ctx, value);
Pavol Vican7cadfe72016-02-11 12:33:34 +0100429 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100430 node->nodetype = nodetype;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100431
432 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100433 child = (parent) ? &parent->child : root;
434 if (*child) {
435 (*child)->prev->next = node;
436 (*child)->prev = node;
437 } else {
438 *child = node;
439 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100440 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100441 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100442}
443
444int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200445yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100446{
447 int ret;
448
449 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100450 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100451 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100452 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100453 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100454 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100455 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200456 default:
457 free(value);
458 LOGINT;
459 ret = EXIT_FAILURE;
460 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100461 }
462 return ret;
463}
464
465int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200466yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100467{
468 int ret;
469
470 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100471 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100472 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100473 break;
474 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100475 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100476 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100477 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100478 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100479 break;
PavolVican75af21d2016-12-29 20:04:07 +0100480 case ADD_KEYWORD:
481 case REPLACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100482 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100483 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200484 default:
485 free(value);
486 LOGINT;
487 ret = EXIT_FAILURE;
488 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100489 }
490 return ret;
491}
Pavol Vican5de33492016-02-22 14:03:24 +0100492
493int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100494yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100495{
496 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100497 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100498
499 exp = value = (char *) list->keys;
500 while ((value = strpbrk(value, " \t\n"))) {
501 list->keys_size++;
502 while (isspace(*value)) {
503 value++;
504 }
505 }
506 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100507
508 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100509 list->keys = calloc(list->keys_size, sizeof *list->keys);
510 if (!list->keys) {
511 LOGMEM;
Radek Krejci5c08a992016-11-02 13:30:04 +0100512 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100513 }
Radek Krejci5c08a992016-11-02 13:30:04 +0100514 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
515 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
516 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100517 }
Pavol Vican5de33492016-02-22 14:03:24 +0100518 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100519}
520
521int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100522yang_fill_unique(struct lys_module *module, struct lys_node_list *list, struct lys_unique *unique, char *value, struct unres_schema *unres)
Pavol Vican85f12022016-03-05 16:30:35 +0100523{
524 int i, j;
525 char *vaux;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200526 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100527
528 /* count the number of unique leafs in the value */
529 vaux = value;
530 while ((vaux = strpbrk(vaux, " \t\n"))) {
531 unique->expr_size++;
532 while (isspace(*vaux)) {
533 vaux++;
534 }
535 }
536 unique->expr_size++;
537 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
538 if (!unique->expr) {
539 LOGMEM;
540 goto error;
541 }
542
543 for (i = 0; i < unique->expr_size; i++) {
544 vaux = strpbrk(value, " \t\n");
545 if (!vaux) {
546 /* the last token, lydict_insert() will count its size on its own */
547 vaux = value;
548 }
549
550 /* store token into unique structure */
551 unique->expr[i] = lydict_insert(module->ctx, value, vaux - value);
552
553 /* check that the expression does not repeat */
554 for (j = 0; j < i; j++) {
555 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100556 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
PavolVican196694c2017-01-27 10:33:09 +0100557 LOGVAL(LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100558 goto error;
559 }
560 }
561 /* try to resolve leaf */
562 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200563 unique_info = malloc(sizeof *unique_info);
564 unique_info->list = (struct lys_node *)list;
565 unique_info->expr = unique->expr[i];
566 unique_info->trg_type = &unique->trg_type;
567 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200568 goto error;
569 }
Pavol Vican85f12022016-03-05 16:30:35 +0100570 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200571 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100572 goto error;
573 }
574 }
575
576 /* move to next token */
577 value = vaux;
578 while(isspace(*value)) {
579 value++;
580 }
581 }
582
583 return EXIT_SUCCESS;
584
585error:
586 return EXIT_FAILURE;
587}
588
589int
Pavol Vican5de33492016-02-22 14:03:24 +0100590yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
591{
592 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100593 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100594
595 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100596 str = (char *)list->unique[k].expr;
597 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100598 goto error;
599 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100600 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100601 }
602 return EXIT_SUCCESS;
603
604error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100605 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100606 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100607}
608
Pavol Vican07f220f2016-09-02 13:04:37 +0200609int
Pavol Vican81344ac2016-09-02 14:23:06 +0200610yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100611{
Pavol Vican81344ac2016-09-02 14:23:06 +0200612 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
613 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
614 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100615 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200616 if (stype->type->info.lref.path) {
617 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
618 goto error;
619 }
620 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
621 stype->base = LY_TYPE_LEAFREF;
622 return EXIT_SUCCESS;
623
624error:
625 free(value);
626 return EXIT_FAILURE;
627}
628
629int
630yang_read_require_instance(struct yang_type *stype, int req)
631{
632 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
633 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
634 return EXIT_FAILURE;
635 }
636 if (stype->type->info.lref.req) {
637 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
638 return EXIT_FAILURE;
639 }
640 stype->type->info.lref.req = req;
641 stype->base = LY_TYPE_LEAFREF;
642 return EXIT_SUCCESS;
643}
644
645int
Pavol Vican7313fc02016-11-14 01:10:31 +0100646yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct lys_type *type, int tpdftype, struct unres_schema *unres)
Pavol Vican73e7c992016-02-24 12:18:05 +0100647{
Pavol Vican81344ac2016-09-02 14:23:06 +0200648 int i, j, rc, ret = -1;
649 int8_t req;
Pavol Vican73e7c992016-02-24 12:18:05 +0100650 const char *name, *value;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100651 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200652 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200653 struct lys_type *dertype;
654 struct lys_type_enum *enms_sc = NULL;
655 struct lys_type_bit *bits_sc = NULL;
656 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100657 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100658
Pavol Vican0adf01d2016-03-22 12:29:33 +0100659 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100660 if (!value) {
661 goto error;
662 }
663
664 i = parse_identifier(value);
665 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100666 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100667 lydict_remove(module->ctx, value);
668 goto error;
669 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200670 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100671 name = value;
672 if (value[i]) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100673 type->module_name = lydict_insert(module->ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100674 name += i;
675 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100676 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100677 lydict_remove(module->ctx, value);
678 goto error;
679 }
680 ++name;
681 }
682
Pavol Vican7313fc02016-11-14 01:10:31 +0100683 rc = resolve_superior_type(name, type->module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100684 if (rc == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100685 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, type->module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200686 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100687 goto error;
688
Michal Vasko01c6fd22016-05-20 11:43:05 +0200689 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100690 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200691 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200692 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100693 ret = EXIT_FAILURE;
694 goto error;
695 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200696 lydict_remove(module->ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200697
Pavol Vican7313fc02016-11-14 01:10:31 +0100698 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200699 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200700 * unresolved item left inside the grouping, LY_TYPE_ERR used as a flag for types inside a grouping. */
Radek Krejcic13db382016-08-16 10:52:42 +0200701 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
702 if (siter) {
Radek Krejci6ff885d2017-01-03 14:06:22 +0100703#if __BYTE_ORDER == __LITTLE_ENDIAN
704 if (!((uint8_t*)&((struct lys_node_grp *)siter)->flags)[1]) {
Radek Krejcic13db382016-08-16 10:52:42 +0200705 LOGINT;
706 goto error;
707 }
Radek Krejci6ff885d2017-01-03 14:06:22 +0100708 ((uint8_t*)&((struct lys_node_grp *)siter)->flags)[1]--;
709#else
710 if (!((uint8_t*)&((struct lys_node_grp *)siter)->flags)[0]) {
711 LOGINT;
712 goto error;
713 }
714 ((uint8_t*)&((struct lys_node_grp *)siter)->flags)[0]--;
715#endif
Radek Krejcic13db382016-08-16 10:52:42 +0200716 } else {
717 LOGINT;
718 goto error;
719 }
720 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200721
722 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100723 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
724 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200725 goto error;
726 }
727
Pavol Vican8bd72e42016-08-29 09:53:05 +0200728 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100729 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100730 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100731 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100732 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100733 }
734 switch (base) {
735 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100736 if (type->base == LY_TYPE_BINARY) {
737 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100738 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100739 goto error;
740 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100741 type->info.binary.length = type->info.str.length;
742 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
743 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100744 goto error;
745 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100746 } else if (type->base == LY_TYPE_STRING) {
747 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
748 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100749 goto error;
750 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100751 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100752 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100753 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100754 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100755 break;
756 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100757 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100758 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100759 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100760 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100761 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100762 goto error;
763 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100764 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100765 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100766 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100767 goto error;
768 }
Radek Krejci4800f652016-09-08 14:02:52 +0200769
770 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100771 if (type->der->type.der) {
772 type->info.dec64.dig = type->der->type.info.dec64.dig;
773 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200774 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100775 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
776 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200777 goto error;
778 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100779 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
780 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100781 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100782 goto error;
783 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100784 type->info.num.range = type->info.dec64.range;
785 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
786 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100787 goto error;
788 }
789 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100790 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100791 goto error;
792 }
793 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100794 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100795 if (type->base != LY_TYPE_ENUM) {
796 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100797 goto error;
798 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100799 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200800
801 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100802 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200803 /* type is derived directly from buit-in enumeartion type and enum statement is required */
804 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
805 goto error;
806 }
807 } else {
808 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100809 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200810 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
811 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
812 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
813 goto error;
814 }
815
816 /* restricted enumeration type - the name MUST be used in the base type */
817 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100818 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200819 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100820 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200821 break;
822 }
823 }
824 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100825 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200826 goto error;
827 }
828
Pavol Vican7313fc02016-11-14 01:10:31 +0100829 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200830 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100831 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200832 } else {
833 /* check that the assigned value corresponds to the original
834 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100835 if (type->info.enums.enm[i].value != enms_sc[j].value) {
836 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200837 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
839 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200840 goto error;
841 }
842 }
843 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100844 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100845 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100846 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100847 if (type->base != LY_TYPE_BITS) {
848 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100849 goto error;
850 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100851 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200852
853 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100854 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200855 /* type is derived directly from buit-in bits type and bit statement is required */
856 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
857 goto error;
858 }
859 } else {
860 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100861 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200862 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
863 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
864 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
865 goto error;
866 }
867
868 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100869 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200870 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100871 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200872 break;
873 }
874 }
875 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100876 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200877 goto error;
878 }
879
880 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100881 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200882 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100883 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200884 } else {
885 /* check that the assigned position corresponds to the original
886 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100887 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
888 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200889 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100890 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
891 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200892 goto error;
893 }
894 }
895 }
Pavol Vican03a59442016-03-21 15:23:45 +0100896 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200897
Pavol Vican7313fc02016-11-14 01:10:31 +0100898 for (i = type->info.bits.count - 1; i > 0; i--) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200899 j = i;
900
901 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100902 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200903 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100904 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
905 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
906 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200907 j--;
908 }
Pavol Vican03a59442016-03-21 15:23:45 +0100909 }
910 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100911 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100912 if (type->base == LY_TYPE_INST) {
913 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200914 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100915 goto error;
916 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100917 if ((req = type->info.lref.req)) {
918 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200919 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100920 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200921 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100922 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200923 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
924 goto error;
925 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200926 /* flag resolving for later use */
927 if (!tpdftype) {
928 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
929 if (siter) {
930 /* just a flag - do not resolve */
931 tpdftype = 1;
932 }
933 }
934
Pavol Vican7313fc02016-11-14 01:10:31 +0100935 if (type->info.lref.path) {
936 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200937 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
938 goto error;
939 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100940 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100941 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100942 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100943 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100944 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100945 goto error;
946 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200947 /* try to resolve leafref path only when this is instantiated
948 * leaf, so it is not:
949 * - typedef's type,
950 * - in grouping definition,
951 * - just instantiated in a grouping definition,
952 * because in those cases the nodes referenced in path might not be present
953 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100954 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100955 goto error;
956 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100957 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100958 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100959 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200960 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200961 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100962 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200963 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100964 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200965 goto error;
966 }
Radek Krejci742be352016-07-17 12:18:54 +0200967
Radek Krejci3a5501d2016-07-18 22:03:34 +0200968 /* add pointer to leafref target, only on leaves (not in typedefs) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100969 if (type->info.lref.target && lys_leaf_add_leafref_target(type->info.lref.target, (struct lys_node *)type->parent)) {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200970 goto error;
Radek Krejci742be352016-07-17 12:18:54 +0200971 }
Pavol Vican191613a2016-02-26 16:21:32 +0100972 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100973 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100974 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100975 goto error;
976 }
977 break;
978 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100979 if (type->base != LY_TYPE_IDENT) {
980 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100981 goto error;
982 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100983 if (type->der->type.der) {
984 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200985 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
986 goto error;
987 }
988 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100989 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200990 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
991 goto error;
992 }
993 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100994 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100995 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100996 if (type->base != LY_TYPE_UNION) {
997 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100998 goto error;
999 }
Pavol Vican7313fc02016-11-14 01:10:31 +01001000 if (!type->info.uni.types) {
1001 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +01001002 /* this is just a derived type with no additional type specified/required */
1003 break;
1004 }
Pavol Vican0adf01d2016-03-22 12:29:33 +01001005 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +01001006 goto error;
1007 }
Pavol Vican7313fc02016-11-14 01:10:31 +01001008 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +01001009 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001010 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
1011 yang = (struct yang_type *)dertype->der;
1012 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +01001013 dertype->parent = type->parent;
1014 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001015 dertype->der = (struct lys_tpdf *)yang;
1016 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +01001017 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001018 base = 0;
1019 goto error;
1020 } else {
1021 lydict_remove(module->ctx, yang->name);
1022 free(yang);
1023 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001024 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001025 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001026 if (dertype->base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001027 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
1028 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001029 } else if (dertype->base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001030 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
1031 goto error;
1032 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001033 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001034 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
1035 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
1036 typ->type->info.uni.has_ptr_type = 1;
1037 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001038 }
1039 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001040
1041 default:
1042 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001043 if (type->base != base) {
1044 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001045 goto error;
1046 }
1047 } else {
1048 LOGINT;
1049 goto error;
1050 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001051 }
1052 return EXIT_SUCCESS;
1053
1054error:
Pavol Vican7313fc02016-11-14 01:10:31 +01001055 if (type->module_name) {
1056 lydict_remove(module->ctx, type->module_name);
1057 type->module_name = NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001058 }
Pavol Vican8bd72e42016-08-29 09:53:05 +02001059 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001060 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001061 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001062 return ret;
1063}
1064
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001065void
1066yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1067{
1068 struct lys_type *stype;
1069 struct yang_type *yang;
1070 int i;
1071
1072 for (i = 0; i < type->info.uni.count; ++i) {
1073 stype = &type->info.uni.types[i];
1074 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1075 yang = (struct yang_type *)stype->der;
1076 stype->base = yang->base;
1077 lydict_remove(ctx, yang->name);
1078 free(yang);
1079 } else if (stype->base == LY_TYPE_UNION) {
1080 yang_free_type_union(ctx, stype);
1081 }
1082 }
1083}
1084
Pavol Vican73e7c992016-02-24 12:18:05 +01001085void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001086yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001087{
1088 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001089 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001090
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001091 typ = calloc(1, sizeof *typ);
1092 if (!typ) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001093 LOGMEM;
1094 return NULL;
1095 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001096
1097 typ->flags = LY_YANG_STRUCTURE_FLAG;
1098 switch (type) {
1099 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001100 if (((struct lys_node_leaf *)parent)->type.der) {
1101 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1102 goto error;
1103 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001104 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1105 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1106 typ->type = &((struct lys_node_leaf *)parent)->type;
1107 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001108 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001109 if (((struct lys_node_leaflist *)parent)->type.der) {
1110 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1111 goto error;
1112 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001113 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1114 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1115 typ->type = &((struct lys_node_leaflist *)parent)->type;
1116 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001117 case UNION_KEYWORD:
1118 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1119 typ->type = (struct lys_type *)parent;
1120 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001121 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001122 if (((struct lys_tpdf *)parent)->type.der) {
1123 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1124 goto error;
1125 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001126 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1127 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001128 break;
1129 case REPLACE_KEYWORD:
1130 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001131 dev = (struct lys_deviate *)parent;
1132 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001133 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001134 goto error;
1135 }
PavolVican75af21d2016-12-29 20:04:07 +01001136 dev->type = calloc(1, sizeof *dev->type);
1137 if (!dev->type) {
1138 LOGMEM;
Pavol Vican4766aca2016-03-07 12:42:36 +01001139 goto error;
1140 }
PavolVican75af21d2016-12-29 20:04:07 +01001141 dev->type->der = (struct lys_tpdf *)typ;
1142 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001143 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001144 default:
1145 goto error;
1146 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001147 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001148 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001149 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001150
1151error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001152 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001153 free(typ);
1154 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001155}
1156
1157void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001158yang_read_length(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican73e7c992016-02-24 12:18:05 +01001159{
1160 struct lys_restr **length;
1161
Pavol Vican6b072512016-04-04 10:50:21 +02001162 if (typ->base == 0 || typ->base == LY_TYPE_STRING) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001163 length = &typ->type->info.str.length;
Pavol Vican6b072512016-04-04 10:50:21 +02001164 typ->base = LY_TYPE_STRING;
1165 } else if (typ->base == LY_TYPE_BINARY) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001166 length = &typ->type->info.binary.length;
1167 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001168 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +01001169 goto error;
1170 }
1171
1172 if (*length) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001173 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001174 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001175 }
1176 *length = calloc(1, sizeof **length);
1177 if (!*length) {
1178 LOGMEM;
1179 goto error;
1180 }
1181 (*length)->expr = lydict_insert_zc(module->ctx, value);
1182 return *length;
1183
1184error:
1185 free(value);
1186 return NULL;
1187
1188}
Pavol Vican1c203db2016-02-24 14:05:23 +01001189
Pavol Vican6eecf302016-08-10 11:09:05 +02001190int
1191yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001192{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001193 char *buf;
1194 size_t len;
1195
Michal Vasko0aee5c12016-06-17 14:27:26 +02001196 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001197 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001198 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001199 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001200
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001201 len = strlen(value);
1202 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Pavol Vican6eecf302016-08-10 11:09:05 +02001203
1204 if (!buf) {
1205 LOGMEM;
1206 free(value);
1207 return EXIT_FAILURE;
1208 }
1209
1210 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001211 strcpy(&buf[1], value);
1212 free(value);
1213
Pavol Vican6eecf302016-08-10 11:09:05 +02001214 pattern->expr = lydict_insert_zc(module->ctx, buf);
1215 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001216}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001217
1218void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001219yang_read_range(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001220{
Pavol Vican6b072512016-04-04 10:50:21 +02001221 if (typ->base != 0 && typ->base != LY_TYPE_DEC64) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001222 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001223 goto error;
1224 }
Pavol Vican6b072512016-04-04 10:50:21 +02001225 typ->base = LY_TYPE_DEC64;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001226 if (typ->type->info.dec64.range) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001227 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001228 goto error;
1229 }
1230 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1231 if (!typ->type->info.dec64.range) {
1232 LOGMEM;
1233 goto error;
1234 }
1235 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1236 return typ->type->info.dec64.range;
1237
1238error:
1239 free(value);
1240 return NULL;
1241}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001242
1243int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001244yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001245{
Pavol Vican6b072512016-04-04 10:50:21 +02001246 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1247 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001248 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001249 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001250 goto error;
1251 }
1252 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001253 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001254 goto error;
1255 }
1256 /* range check */
1257 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001258 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001259 goto error;
1260 }
1261 typ->type->info.dec64.dig = value;
1262 return EXIT_SUCCESS;
1263
1264error:
1265 return EXIT_FAILURE;
1266}
Pavol Vican79a763d2016-02-25 15:41:27 +01001267
Pavol Vican874715f2016-10-25 14:52:08 +02001268int
1269yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001270{
Pavol Vican874715f2016-10-25 14:52:08 +02001271 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001272
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001273 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001274 if (!value[0]) {
1275 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1276 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1277 free(value);
1278 goto error;
1279 }
1280
Pavol Vican79a763d2016-02-25 15:41:27 +01001281 enm->name = lydict_insert_zc(module->ctx, value);
1282
1283 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1284 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001285 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001286 goto error;
1287 }
1288
Pavol Vican874715f2016-10-25 14:52:08 +02001289 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001290 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001291 for (i = 0; i < j; i++) {
1292 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[j].name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001293 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001294 goto error;
1295 }
1296 }
1297
Pavol Vican874715f2016-10-25 14:52:08 +02001298 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001299
1300error:
Pavol Vican874715f2016-10-25 14:52:08 +02001301 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001302}
1303
1304int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001305yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001306{
1307 int i, j;
1308
1309 if (!assign) {
1310 /* assign value automatically */
1311 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001312 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001313 goto error;
1314 }
1315 enm->value = *value;
1316 enm->flags |= LYS_AUTOASSIGNED;
1317 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001318 } else if (typ->type->info.enums.enm == enm) {
1319 /* change value, which is assigned automatically, if first enum has value. */
1320 *value = typ->type->info.enums.enm[0].value;
1321 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001322 }
1323
1324 /* check that the value is unique */
1325 j = typ->type->info.enums.count-1;
1326 for (i = 0; i < j; i++) {
1327 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001328 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001329 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1330 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001331 goto error;
1332 }
1333 }
1334
1335 return EXIT_SUCCESS;
1336
1337error:
1338 return EXIT_FAILURE;
1339}
Pavol Vican9887c682016-02-29 11:32:01 +01001340
Pavol Vican59e8dee2016-10-25 15:29:38 +02001341int
1342yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001343{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001344 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001345
PavolVicane87cb932016-12-30 15:36:18 +01001346 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001347 bit->name = lydict_insert_zc(module->ctx, value);
1348 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001349 free(value);
1350 goto error;
1351 }
Pavol Vican9887c682016-02-29 11:32:01 +01001352
Pavol Vican59e8dee2016-10-25 15:29:38 +02001353 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001354 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001355 for (i = 0; i < j; i++) {
Pavol Vican9887c682016-02-29 11:32:01 +01001356 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001357 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001358 goto error;
1359 }
1360 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001361 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001362
1363error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001364 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001365}
1366
1367int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001368yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001369{
1370 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001371
1372 if (!assign) {
1373 /* assign value automatically */
1374 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001375 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001376 goto error;
1377 }
1378 bit->pos = (uint32_t)*value;
1379 bit->flags |= LYS_AUTOASSIGNED;
1380 (*value)++;
1381 }
1382
1383 j = typ->type->info.bits.count - 1;
1384 /* check that the value is unique */
1385 for (i = 0; i < j; i++) {
1386 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001387 LOGVAL(LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
Pavol Vican9887c682016-02-29 11:32:01 +01001388 goto error;
1389 }
1390 }
1391
Pavol Vican9887c682016-02-29 11:32:01 +01001392 return EXIT_SUCCESS;
1393
1394error:
1395 return EXIT_FAILURE;
1396}
Pavol Vican0df02b02016-03-01 10:28:50 +01001397
Pavol Vican3ad50f82016-12-04 15:00:36 +01001398int
1399yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001400{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001401 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001402 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001403 free(value);
1404 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001405 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001406 }
1407 aug->parent = parent;
1408 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001409 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001410}
Pavol Vican220e5a12016-03-03 14:19:43 +01001411
Pavol Vican4c90c642016-03-03 15:06:47 +01001412int
PavolVican75af21d2016-12-29 20:04:07 +01001413yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001414{
PavolVican75af21d2016-12-29 20:04:07 +01001415 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001416 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
Pavol Vican4c90c642016-03-03 15:06:47 +01001417 return EXIT_FAILURE;
Pavol Vican220e5a12016-03-03 14:19:43 +01001418 }
PavolVican75af21d2016-12-29 20:04:07 +01001419 dev->deviate = calloc(1, sizeof *dev->deviate);
1420 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1421 dev->deviate_size = 1;
Pavol Vican4c90c642016-03-03 15:06:47 +01001422 return EXIT_SUCCESS;
Pavol Vican220e5a12016-03-03 14:19:43 +01001423}
1424
1425void *
PavolVican75af21d2016-12-29 20:04:07 +01001426yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001427{
PavolVican75af21d2016-12-29 20:04:07 +01001428 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001429
PavolVican75af21d2016-12-29 20:04:07 +01001430 if (dev->deviate && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001431 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1432 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001433 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001434 }
PavolVican75af21d2016-12-29 20:04:07 +01001435 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1436 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
1437 if (!deviate) {
1438 LOGMEM;
1439 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001440 }
PavolVican75af21d2016-12-29 20:04:07 +01001441 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1442 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001443 }
PavolVican75af21d2016-12-29 20:04:07 +01001444 dev->deviate[dev->deviate_size].mod = mod;
1445 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001446}
1447
1448int
PavolVican75af21d2016-12-29 20:04:07 +01001449yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001450{
1451 const char **stritem;
1452
Pavol Vican85f12022016-03-05 16:30:35 +01001453 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001454 if (dev_target->nodetype == LYS_LEAFLIST) {
1455 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1456 } else if (dev_target->nodetype == LYS_LEAF) {
1457 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001458 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001459 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1460 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001461 goto error;
1462 }
1463
PavolVican75af21d2016-12-29 20:04:07 +01001464 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001465 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001466 if (!ly_strequal(*stritem, deviate->units, 1)) {
1467 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001468 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001469 goto error;
1470 }
1471 /* remove current units value of the target */
1472 lydict_remove(ctx, *stritem);
Pavol Vican4766aca2016-03-07 12:42:36 +01001473 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001474 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001475 /* check that there is no current value */
1476 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001477 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1478 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001479 goto error;
1480 }
1481 } else { /* replace */
1482 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001483 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1484 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001485 goto error;
1486 }
1487 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001488 /* remove current units value of the target ... */
1489 lydict_remove(ctx, *stritem);
1490
1491 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001492 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001493 }
1494
Pavol Vican85f12022016-03-05 16:30:35 +01001495 return EXIT_SUCCESS;
1496
1497error:
1498 return EXIT_FAILURE;
1499}
1500
1501int
PavolVican75af21d2016-12-29 20:04:07 +01001502yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001503{
Pavol Vican85f12022016-03-05 16:30:35 +01001504 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001505 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001506
1507 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001508 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001509 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1510 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001511 goto error;
1512 }
1513
PavolVican75af21d2016-12-29 20:04:07 +01001514 list = (struct lys_node_list *)dev_target;
1515 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001516 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001517 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
1518 if (!unique) {
Pavol Vican85f12022016-03-05 16:30:35 +01001519 LOGMEM;
1520 goto error;
1521 }
PavolVican75af21d2016-12-29 20:04:07 +01001522 list->unique = unique;
1523 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001524 }
1525
1526 return EXIT_SUCCESS;
1527
1528error:
1529 return EXIT_FAILURE;
1530}
1531
1532int
PavolVican75af21d2016-12-29 20:04:07 +01001533yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1534 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001535{
1536 struct lys_node *node;
1537 struct lys_node_choice *choice;
1538 struct lys_node_leaf *leaf;
1539 struct lys_node_leaflist *llist;
1540 int rc, i;
1541 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001542
Pavol Vican38321d02016-08-16 14:56:02 +02001543 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001544 if (dev_target->nodetype == LYS_CHOICE) {
1545 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001546 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1547 if (rc || !node) {
1548 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1549 goto error;
1550 }
PavolVican75af21d2016-12-29 20:04:07 +01001551 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001552 if (!choice->dflt || (choice->dflt != node)) {
1553 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1554 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1555 goto error;
1556 }
1557 } else { /* add or replace */
1558 choice->dflt = node;
1559 if (!choice->dflt) {
1560 /* default branch not found */
1561 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1562 goto error;
1563 }
1564 }
PavolVican75af21d2016-12-29 20:04:07 +01001565 } else if (dev_target->nodetype == LYS_LEAF) {
1566 leaf = (struct lys_node_leaf *)dev_target;
1567 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001568 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1569 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1570 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1571 goto error;
1572 }
1573 /* remove value */
1574 lydict_remove(ctx, leaf->dflt);
1575 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001576 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001577 } else { /* add (already checked) and replace */
1578 /* remove value */
1579 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001580 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001581
1582 /* set new value */
1583 leaf->dflt = lydict_insert(ctx, value, u);
1584
1585 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001586 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001587 }
1588 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001589 llist = (struct lys_node_leaflist *)dev_target;
1590 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001591 /* find and remove the value in target list */
1592 for (i = 0; i < llist->dflt_size; i++) {
1593 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1594 /* match, remove the value */
1595 lydict_remove(llist->module->ctx, llist->dflt[i]);
1596 llist->dflt[i] = NULL;
1597 break;
1598 }
1599 }
1600 if (i == llist->dflt_size) {
1601 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1602 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1603 goto error;
1604 }
1605 } else {
1606 /* add or replace, anyway we place items into the deviate's list
1607 which propagates to the target */
1608 /* we just want to check that the value isn't already in the list */
1609 for (i = 0; i < llist->dflt_size; i++) {
1610 if (ly_strequal(llist->dflt[i], value, 1)) {
1611 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1612 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1613 goto error;
1614 }
1615 }
1616 /* store it in target node */
1617 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1618
1619 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001620 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001621 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001622 }
1623 }
1624
1625 return EXIT_SUCCESS;
1626error:
1627 return EXIT_FAILURE;
1628}
1629
Pavol Vican38321d02016-08-16 14:56:02 +02001630int
PavolVican75af21d2016-12-29 20:04:07 +01001631yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1632 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001633{
PavolVican75af21d2016-12-29 20:04:07 +01001634 int i;
1635 struct lys_node_leaflist *llist;
1636 const char **dflt;
1637
1638 /* check target node type */
1639 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1640 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1641 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1642 goto error;
1643 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1644 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1645 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1646 goto error;
1647 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1648 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1649 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001650 goto error;
1651 }
1652
PavolVican75af21d2016-12-29 20:04:07 +01001653 if (deviate->mod == LY_DEVIATE_ADD) {
1654 /* check that there is no current value */
1655 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1656 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1657 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1658 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1659 goto error;
1660 }
Pavol Vican85f12022016-03-05 16:30:35 +01001661
PavolVican75af21d2016-12-29 20:04:07 +01001662 /* check collision with mandatory/min-elements */
1663 if ((dev_target->flags & LYS_MAND_TRUE) ||
1664 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1665 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1666 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1667 "Adding the \"default\" statement is forbidden on %s statement.",
1668 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1669 goto error;
1670 }
1671 } else if (deviate->mod == LY_DEVIATE_RPL) {
1672 /* check that there was a value before */
1673 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1674 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1675 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1676 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1677 goto error;
1678 }
1679 }
Pavol Vican85f12022016-03-05 16:30:35 +01001680
PavolVican75af21d2016-12-29 20:04:07 +01001681 if (dev_target->nodetype == LYS_LEAFLIST) {
1682 /* reallocate default list in the target */
1683 llist = (struct lys_node_leaflist *)dev_target;
1684 if (deviate->mod == LY_DEVIATE_ADD) {
1685 /* reallocate (enlarge) the unique array of the target */
1686 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
1687 if (!dflt) {
1688 LOGMEM;
1689 goto error;
1690 }
1691 llist->dflt = dflt;
1692 } else if (deviate->mod == LY_DEVIATE_RPL) {
1693 /* reallocate (replace) the unique array of the target */
1694 for (i = 0; i < llist->dflt_size; i++) {
1695 lydict_remove(llist->module->ctx, llist->dflt[i]);
1696 }
1697 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
1698 if (!dflt) {
1699 LOGMEM;
1700 goto error;
1701 }
1702 llist->dflt = dflt;
1703 llist->dflt_size = 0;
1704 }
1705 }
1706
1707 for (i = 0; i < deviate->dflt_size; ++i) {
1708 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1709 goto error;
1710 }
1711 }
Pavol Vican85f12022016-03-05 16:30:35 +01001712
1713 return EXIT_SUCCESS;
1714
1715error:
1716 return EXIT_FAILURE;
1717}
1718
1719int
PavolVican75af21d2016-12-29 20:04:07 +01001720yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001721{
Radek Krejcie00d2312016-08-12 15:27:49 +02001722 struct lys_node *parent;
1723
Pavol Vican85f12022016-03-05 16:30:35 +01001724 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001725 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001726 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1727 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001728 goto error;
1729 }
1730
PavolVican75af21d2016-12-29 20:04:07 +01001731 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001732 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001733 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001734 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1735 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001736 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001737 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001738 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001739 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1740 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1741 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1742 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001743 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001744 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1745 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1746 goto error;
1747 }
Pavol Vican85f12022016-03-05 16:30:35 +01001748 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001749 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001750 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001751 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1752 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001753 goto error;
1754 }
Pavol Vican85f12022016-03-05 16:30:35 +01001755 }
1756
Pavol Vican85f12022016-03-05 16:30:35 +01001757 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001758 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001759
1760 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001761 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001762
Radek Krejcie00d2312016-08-12 15:27:49 +02001763 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001764 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001765 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1766 parent = parent->parent) {
1767 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1768 /* stop also on presence containers */
1769 break;
1770 }
1771 }
1772 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1773 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1774 if (lyp_check_mandatory_choice(parent)) {
1775 goto error;
1776 }
1777 }
1778
Pavol Vican85f12022016-03-05 16:30:35 +01001779 return EXIT_SUCCESS;
1780
1781error:
1782 return EXIT_FAILURE;
1783}
1784
1785int
PavolVican75af21d2016-12-29 20:04:07 +01001786yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001787{
Pavol Vican09adcc32016-08-25 10:51:36 +02001788 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001789
1790 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001791 if (dev_target->nodetype == LYS_LEAFLIST) {
1792 max = &((struct lys_node_leaflist *)dev_target)->max;
1793 min = &((struct lys_node_leaflist *)dev_target)->min;
1794 } else if (dev_target->nodetype == LYS_LIST) {
1795 max = &((struct lys_node_list *)dev_target)->max;
1796 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001797 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001798 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1799 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"%s\" property.", (type) ? "max-elements" : "min-elements");
Pavol Vican85f12022016-03-05 16:30:35 +01001800 goto error;
1801 }
1802
PavolVican75af21d2016-12-29 20:04:07 +01001803 ui32val = (type) ? max : min;
1804 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001805 /* check that there is no current value */
1806 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001807 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1808 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001809 goto error;
1810 }
PavolVican75af21d2016-12-29 20:04:07 +01001811 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001812 /* unfortunately, there is no way to check reliably that there
1813 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001814 }
1815
1816 /* add (already checked) and replace */
1817 /* set new value specified in deviation */
1818 *ui32val = value;
1819
Pavol Vican09adcc32016-08-25 10:51:36 +02001820 /* check min-elements is smaller than max-elements */
1821 if (*max && *min > *max) {
1822 if (type) {
1823 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1824 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1825 } else {
1826 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1827 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1828 }
1829 goto error;
1830 }
1831
Pavol Vican85f12022016-03-05 16:30:35 +01001832 return EXIT_SUCCESS;
1833
1834error:
1835 return EXIT_FAILURE;
1836}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001837
1838int
PavolVican75af21d2016-12-29 20:04:07 +01001839yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1840 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001841{
PavolVican75af21d2016-12-29 20:04:07 +01001842 int i, j, erase_must = 1;
1843 struct lys_restr **trg_must, *must;
1844 uint8_t *trg_must_size, must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001845
PavolVican75af21d2016-12-29 20:04:07 +01001846 /* check target node type */
1847 switch (dev_target->nodetype) {
1848 case LYS_LEAF:
1849 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1850 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001851 break;
PavolVican75af21d2016-12-29 20:04:07 +01001852 case LYS_CONTAINER:
1853 trg_must = &((struct lys_node_container *)dev_target)->must;
1854 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1855 break;
1856 case LYS_LEAFLIST:
1857 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1858 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1859 break;
1860 case LYS_LIST:
1861 trg_must = &((struct lys_node_list *)dev_target)->must;
1862 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1863 break;
1864 case LYS_ANYXML:
1865 case LYS_ANYDATA:
1866 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1867 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1868 break;
1869 default:
1870 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1871 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1872 goto error;
1873 }
1874
1875 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001876 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001877
1878 if (deviate->mod == LY_DEVIATE_ADD) {
1879 /* reallocate the must array of the target */
1880 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
1881 if (!must) {
1882 LOGMEM;
1883 goto error;
1884 }
1885 *trg_must = must;
1886 must_size = *trg_must_size;
1887 for (i = 0; i < deviate->must_size; ++i) {
1888 (*trg_must)[must_size].expr = deviate->must[i].expr;
1889 (*trg_must)[must_size].dsc = deviate->must[i].dsc;
1890 (*trg_must)[must_size].ref = deviate->must[i].ref;
1891 (*trg_must)[must_size].emsg = deviate->must[i].emsg;
1892 (*trg_must)[must_size].eapptag = deviate->must[i].eapptag;
1893 ++must_size;
1894 }
1895 free(deviate->must);
1896 deviate->must = &must[*trg_must_size];
1897 *trg_must_size = must_size;
1898 erase_must = 0;
1899 } else if (deviate->mod == LY_DEVIATE_DEL) {
1900 /* find must to delete, we are ok with just matching conditions */
1901 for (j = 0; j < deviate->must_size; ++j) {
1902 for (i = 0; i < *trg_must_size; i++) {
1903 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1904 /* we have a match, free the must structure ... */
1905 lys_restr_free(module->ctx, &((*trg_must)[i]));
1906 /* ... and maintain the array */
1907 (*trg_must_size)--;
1908 if (i != *trg_must_size) {
1909 (*trg_must)[i].expr = (*trg_must)[*trg_must_size].expr;
1910 (*trg_must)[i].dsc = (*trg_must)[*trg_must_size].dsc;
1911 (*trg_must)[i].ref = (*trg_must)[*trg_must_size].ref;
1912 (*trg_must)[i].eapptag = (*trg_must)[*trg_must_size].eapptag;
1913 (*trg_must)[i].emsg = (*trg_must)[*trg_must_size].emsg;
1914 }
1915 if (!(*trg_must_size)) {
1916 free(*trg_must);
1917 *trg_must = NULL;
1918 } else {
1919 (*trg_must)[*trg_must_size].expr = NULL;
1920 (*trg_must)[*trg_must_size].dsc = NULL;
1921 (*trg_must)[*trg_must_size].ref = NULL;
1922 (*trg_must)[*trg_must_size].eapptag = NULL;
1923 (*trg_must)[*trg_must_size].emsg = NULL;
1924 }
1925
1926 i = -1; /* set match flag */
1927 break;
1928 }
1929 }
1930 if (i != -1) {
1931 /* no match found */
1932 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1933 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1934 goto error;
1935 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001936 }
1937 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001938
PavolVican75af21d2016-12-29 20:04:07 +01001939 /* check XPath dependencies */
1940 if (*trg_must_size && unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001941 goto error;
1942 }
1943
PavolVican75af21d2016-12-29 20:04:07 +01001944 return EXIT_SUCCESS;
1945error:
1946 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1947 for (i = 0; i < deviate->must_size; ++i) {
1948 lys_restr_free(module->ctx, &deviate->must[i]);
1949 }
1950 free(deviate->must);
1951 }
1952 return EXIT_FAILURE;
1953}
1954
1955int
1956yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1957 struct lys_node_list *list, int index, char * value)
1958{
1959 int i, j;
1960
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001961 /* find unique structures to delete */
1962 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001963 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001964 continue;
1965 }
1966
PavolVican75af21d2016-12-29 20:04:07 +01001967 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1968 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001969 break;
1970 }
1971 }
1972
PavolVican75af21d2016-12-29 20:04:07 +01001973 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001974 /* we have a match, free the unique structure ... */
1975 for (j = 0; j < list->unique[i].expr_size; j++) {
1976 lydict_remove(module->ctx, list->unique[i].expr[j]);
1977 }
1978 free(list->unique[i].expr);
1979 /* ... and maintain the array */
1980 list->unique_size--;
1981 if (i != list->unique_size) {
1982 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1983 list->unique[i].expr = list->unique[list->unique_size].expr;
1984 }
1985
1986 if (!list->unique_size) {
1987 free(list->unique);
1988 list->unique = NULL;
1989 } else {
1990 list->unique[list->unique_size].expr_size = 0;
1991 list->unique[list->unique_size].expr = NULL;
1992 }
1993
1994 i = -1; /* set match flag */
1995 break;
1996 }
1997 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001998
1999 if (i != -1) {
2000 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01002001 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
2002 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01002003 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002004 }
2005
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002006 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002007}
Pavol Vican021488a2016-01-25 23:56:12 +01002008
PavolVican75af21d2016-12-29 20:04:07 +01002009int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01002010{
PavolVican75af21d2016-12-29 20:04:07 +01002011 struct lys_node_list *list;
2012 char *str;
2013 uint i;
2014 struct lys_unique *last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002015
PavolVican75af21d2016-12-29 20:04:07 +01002016 if (yang_read_deviate_unique(deviate, dev_target)) {
2017 goto error;
2018 }
2019 list = (struct lys_node_list *)dev_target;
2020 last_unique = &list->unique[list->unique_size];
2021 for (i = 0; i < deviate->unique_size; ++i) {
2022 str = (char *) deviate->unique[i].expr;
2023 if (deviate->mod == LY_DEVIATE_ADD) {
2024 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2025 free(str);
2026 goto error;
2027 }
2028 list->unique_size++;
2029 } else if (deviate->mod == LY_DEVIATE_DEL) {
2030 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2031 free(str);
2032 goto error;
2033 }
2034 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2035 free(str);
2036 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002037 }
2038 }
PavolVican75af21d2016-12-29 20:04:07 +01002039 free(str);
2040 }
2041 if (deviate->mod == LY_DEVIATE_ADD) {
2042 free(deviate->unique);
2043 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002044 }
Pavol Vican38321d02016-08-16 14:56:02 +02002045
Pavol Vican38321d02016-08-16 14:56:02 +02002046
PavolVican75af21d2016-12-29 20:04:07 +01002047 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002048error:
PavolVican75af21d2016-12-29 20:04:07 +01002049 if (deviate->mod == LY_DEVIATE_ADD) {
2050 for (i = i + 1; i < deviate->unique_size; ++i) {
2051 free(deviate->unique[i].expr);
2052 }
2053 free(deviate->unique);
2054 deviate->unique = last_unique;
2055
2056 }
Pavol Vican021488a2016-01-25 23:56:12 +01002057 return EXIT_FAILURE;
2058}
2059
Pavol Vicanec423c92016-10-24 21:33:43 +02002060static int
2061yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2062 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002063{
Pavol Vican55870412016-03-10 12:36:21 +01002064 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002065 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002066 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002067
Pavol Vicanec423c92016-10-24 21:33:43 +02002068 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002069 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002070 if (!rc) {
2071 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002072 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002073 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2074 &trg->inc[trg->inc_size], unres)) {
2075 ret = -1;
2076 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002077 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002078 } else if (rc == -1) {
PavolVican7d0b5ab2017-02-01 13:06:53 +01002079 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002080 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002081 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002082
Pavol Vicanec423c92016-10-24 21:33:43 +02002083 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002084 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002085}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002086
PavolVicanc1807262017-01-31 18:00:27 +01002087struct lys_ext_instance *
2088yang_ext_instance(void *node, enum yytokentype type)
2089{
2090 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2091 LYEXT_PAR parent_type;
2092 uint8_t *size;
2093
2094 switch (type) {
2095 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002096 case SUBMODULE_KEYWORD:
2097 case BELONGS_TO_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002098 ext = &((struct lys_module *)node)->ext;
2099 size = &((struct lys_module *)node)->ext_size;
2100 parent_type = LYEXT_PAR_MODULE;
2101 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002102 case IMPORT_KEYWORD:
2103 ext = &((struct lys_import *)node)->ext;
2104 size = &((struct lys_import *)node)->ext_size;
2105 parent_type = LYEXT_PAR_IMPORT;
2106 break;
2107 case INCLUDE_KEYWORD:
2108 ext = &((struct lys_include *)node)->ext;
2109 size = &((struct lys_include *)node)->ext_size;
2110 parent_type = LYEXT_PAR_INCLUDE;
2111 break;
PavolVican171717d2017-02-01 14:49:55 +01002112 case REVISION_KEYWORD:
2113 ext = &((struct lys_revision *)node)->ext;
2114 size = &((struct lys_revision *)node)->ext_size;
2115 parent_type = LYEXT_PAR_REVISION;
2116 break;
PavolVican70ce7452017-02-01 15:39:39 +01002117 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002118 case CONTAINER_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002119 ext = &((struct lys_node *)node)->ext;
2120 size = &((struct lys_node *)node)->ext_size;
2121 parent_type = LYEXT_PAR_NODE;
2122 break;
PavolVicanc1807262017-01-31 18:00:27 +01002123 default:
2124 LOGINT;
2125 return NULL;
2126 }
2127
2128 instance = calloc(1, sizeof *instance);
2129 if (!instance) {
2130 goto error;
2131 }
2132 instance->parent_type = parent_type;
2133 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2134 if (!tmp) {
2135 goto error;
2136 }
2137 tmp[*size] = instance;
2138 *ext = tmp;
2139 (*size)++;
2140 return instance;
2141
2142error:
2143 LOGMEM;
2144 free(instance);
2145 return NULL;
2146}
2147
2148void *
2149yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
2150 enum yytokentype actual_type, enum yytokentype backup_type)
2151{
2152 struct lys_ext_instance *instance;
2153
2154 if (backup_type != NODE) {
2155 instance = yang_ext_instance((actual) ? actual : module, backup_type);
PavolVicane6fa67b2017-02-01 11:06:57 +01002156 if (!instance) {
2157 return NULL;
2158 }
PavolVicanc1807262017-01-31 18:00:27 +01002159 switch (actual_type) {
2160 case NAMESPACE_KEYWORD:
2161 instance->substmt = LYEXT_SUBSTMT_NAMESPACE;
2162 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002163 case BELONGS_TO_KEYWORD:
2164 instance->substmt = LYEXT_SUBSTMT_BELONGSTO;
2165 break;
2166 case PREFIX_KEYWORD:
2167 instance->substmt = LYEXT_SUBSTMT_PREFIX;
2168 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002169 case REVISION_DATE_KEYWORD:
2170 instance->substmt = LYEXT_SUBSTMT_REVISIONDATE;
2171 break;
2172 case DESCRIPTION_KEYWORD:
2173 instance->substmt = LYEXT_SUBSTMT_DESCRIPTION;
2174 break;
2175 case REFERENCE_KEYWORD:
2176 instance->substmt = LYEXT_SUBSTMT_REFERENCE;
2177 break;
PavolVican171717d2017-02-01 14:49:55 +01002178 case CONTACT_KEYWORD:
2179 instance->substmt = LYEXT_SUBSTMT_CONTACT;
2180 break;
2181 case ORGANIZATION_KEYWORD:
2182 instance->substmt = LYEXT_SUBSTMT_ORGANIZATION;
2183 break;
PavolVicanc1807262017-01-31 18:00:27 +01002184 default:
2185 LOGINT;
2186 return NULL;
2187 }
2188 } else {
PavolVicane6fa67b2017-02-01 11:06:57 +01002189 instance = yang_ext_instance((actual) ? actual : module, actual_type);
2190 if (!instance) {
2191 return NULL;
2192 }
PavolVicanc1807262017-01-31 18:00:27 +01002193 instance->substmt = LYEXT_SUBSTMT_SELF;
2194 }
2195 instance->flags |= LYEXT_OPT_YANG;
2196 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2197 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
2198 return instance;
2199}
2200
Pavol Vicanf4717e62016-03-16 11:30:01 +01002201int
Pavol Vican0adf01d2016-03-22 12:29:33 +01002202yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value)
Pavol Vicanf4717e62016-03-16 11:30:01 +01002203{
2204 char *prefix;
2205 char *identif;
2206 const char *ns = NULL;
2207 int i;
2208
Pavol Vicanf4717e62016-03-16 11:30:01 +01002209 /* check to the same pointer */
2210 if (data_node != actual) {
2211 return EXIT_SUCCESS;
2212 }
2213
Pavol Vicana302aa62016-03-17 10:45:35 +01002214 prefix = strdup(value);
2215 if (!prefix) {
2216 LOGMEM;
2217 goto error;
2218 }
2219 /* find prefix anf identificator*/
2220 identif = strchr(prefix, ':');
Pavol Vicanfbd02782016-08-29 11:14:45 +02002221 if (!identif) {
2222 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, prefix);
2223 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The extension must have prefix.");
2224 goto error;
2225 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002226 *identif = '\0';
2227 identif++;
2228
Pavol Vicanf4717e62016-03-16 11:30:01 +01002229 for(i = 0; i < module->imp_size; ++i) {
2230 if (!strcmp(module->imp[i].prefix, prefix)) {
2231 ns = module->imp[i].module->ns;
2232 break;
2233 }
2234 }
Pavol Vican1ff1b7b2016-04-07 09:51:49 +02002235 if (!ns && !strcmp(module->prefix, prefix)) {
2236 ns = (module->type) ? ((struct lys_submodule *)module)->belongsto->ns : module->ns;
2237 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002238 free(prefix);
Pavol Vicanf4717e62016-03-16 11:30:01 +01002239 return EXIT_SUCCESS;
Pavol Vicana302aa62016-03-17 10:45:35 +01002240
2241error:
2242 free(prefix);
2243 return EXIT_FAILURE;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002244}
2245
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002246int
Pavol Vican1dac40c2016-09-28 11:39:26 +02002247store_flags(struct lys_node *node, uint8_t flags, int config_opt)
Pavol Vican4fb66c92016-03-17 10:32:27 +01002248{
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002249 struct lys_node *elem;
2250
Pavol Vican1dac40c2016-09-28 11:39:26 +02002251 node->flags |= (config_opt == CONFIG_IGNORE) ? flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET)): flags;
2252 if (config_opt == CONFIG_INHERIT_ENABLE) {
2253 if (!(node->flags & LYS_CONFIG_MASK)) {
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002254 /* get config flag from parent */
Radek Krejcif71f48f2016-10-25 16:37:24 +02002255 if (node->parent) {
2256 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002257 } else {
2258 /* default config is true */
2259 node->flags |= LYS_CONFIG_W;
2260 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002261 } else {
Pavol Vican1dac40c2016-09-28 11:39:26 +02002262 /* do we even care about config flags? */
2263 for (elem = node; elem && !(elem->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT | LYS_RPC)); elem = elem->parent);
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002264
Pavol Vican1dac40c2016-09-28 11:39:26 +02002265 if (!elem && (node->flags & LYS_CONFIG_W) && node->parent && (node->parent->flags & LYS_CONFIG_R)) {
2266 LOGVAL(LYE_INARG, LY_VLOG_LYS, node, "true", "config");
Michal Vasko51e5c582017-01-19 14:16:39 +01002267 LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "State nodes cannot have configuration nodes as children.");
Pavol Vican1dac40c2016-09-28 11:39:26 +02002268 return EXIT_FAILURE;
2269 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002270 }
2271 }
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002272
2273 return EXIT_SUCCESS;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002274}
Pavol Vican8e7110b2016-03-22 17:00:26 +01002275
Pavol Vicanec598812016-11-30 14:13:38 +01002276int
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002277store_config_flag(struct lys_node *node, int config_opt)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002278{
Pavol Vicanec598812016-11-30 14:13:38 +01002279 int ret = config_opt;
Pavol Vican1938d882016-04-10 13:36:31 +02002280
Pavol Vicanec598812016-11-30 14:13:38 +01002281 switch (node->nodetype) {
2282 case LYS_CONTAINER:
2283 case LYS_LEAF:
2284 case LYS_LEAFLIST:
2285 case LYS_LIST:
2286 case LYS_CHOICE:
2287 case LYS_ANYDATA:
2288 case LYS_ANYXML:
2289 if (config_opt == CONFIG_IGNORE) {
2290 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
2291 } else if (config_opt == CONFIG_INHERIT_ENABLE) {
2292 if (!(node->flags & LYS_CONFIG_MASK)) {
2293 /* get config flag from parent */
2294 if (node->parent) {
2295 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2296 } else {
2297 /* default config is true */
2298 node->flags |= LYS_CONFIG_W;
2299 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002300 }
2301 }
Pavol Vicanec598812016-11-30 14:13:38 +01002302 break;
2303 case LYS_CASE:
2304 if (config_opt == CONFIG_INHERIT_ENABLE) {
2305 if (!(node->flags & LYS_CONFIG_MASK)) {
2306 /* get config flag from parent */
2307 if (node->parent) {
2308 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2309 } else {
2310 /* default config is true */
2311 node->flags |= LYS_CONFIG_W;
2312 }
2313 }
2314 }
2315 break;
2316 case LYS_RPC:
2317 case LYS_ACTION:
2318 case LYS_NOTIF:
2319 ret = CONFIG_IGNORE;
2320 break;
2321 default:
2322 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002323 }
Pavol Vicanec598812016-11-30 14:13:38 +01002324
Pavol Vican1938d882016-04-10 13:36:31 +02002325 return ret;
2326}
2327
2328int
Pavol Vican9d50a772016-10-14 22:23:36 +02002329yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2330 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002331{
Pavol Vican974377b2016-03-23 00:38:53 +01002332 unsigned int size;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002333 YY_BUFFER_STATE bp;
2334 yyscan_t scanner = NULL;
Pavol Vican082afd02016-10-25 12:39:15 +02002335 int ret = EXIT_SUCCESS, remove_import = 1;
2336 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002337 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002338
Pavol Vican8e7110b2016-03-22 17:00:26 +01002339 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002340 yylex_init(&scanner);
2341 bp = yy_scan_buffer((char *)data, size, scanner);
2342 yy_switch_to_buffer(bp, scanner);
PavolVican196694c2017-01-27 10:33:09 +01002343 param.module = module;
2344 param.submodule = submodule;
2345 param.unres = unres;
2346 param.node = node;
2347 param.remove_import = &remove_import;
2348 if (yyparse(scanner, &param)) {
Pavol Vican082afd02016-10-25 12:39:15 +02002349 if (remove_import) {
2350 trg = (submodule) ? (struct lys_module *)submodule : module;
2351 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2352 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2353 trg->inc_size = 0;
2354 trg->imp_size = 0;
2355 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002356 ret = EXIT_FAILURE;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002357 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002358 yy_delete_buffer(bp, scanner);
2359 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002360 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002361}
2362
2363struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002364yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002365{
2366
Radek Krejci6ff885d2017-01-03 14:06:22 +01002367 struct lys_module *module = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002368 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002369 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002370
2371 unres = calloc(1, sizeof *unres);
2372 if (!unres) {
2373 LOGMEM;
2374 goto error;
2375 }
2376
2377 module = calloc(1, sizeof *module);
2378 if (!module) {
2379 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002380 goto error;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002381 }
2382
2383 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002384 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002385 module->type = 0;
2386 module->implemented = (implement ? 1 : 0);
2387
Pavol Vican9d50a772016-10-14 22:23:36 +02002388 if (yang_parse_mem(module, NULL, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002389 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002390 goto error;
2391 }
2392
2393 if (yang_check_sub_module(module, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002394 goto error;
2395 }
2396
2397 if (module && unres->count && resolve_unres_schema(module, unres)) {
2398 goto error;
2399 }
2400
2401 if (revision) {
2402 /* check revision of the parsed model */
2403 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2404 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2405 module->name, module->rev[0].date, revision);
2406 goto error;
2407 }
2408 }
2409
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002410 /* check correctness of includes */
2411 if (lyp_check_include_missing(module)) {
2412 goto error;
2413 }
2414
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002415 if (lyp_ctx_add_module(&module)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002416 goto error;
2417 }
2418
Radek Krejci27fe55e2016-09-13 17:13:35 +02002419 if (module->deviation_size && !module->implemented) {
2420 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2421 /* deviations always causes target to be made implemented,
2422 * but augents and leafrefs not, so we have to apply them now */
2423 if (lys_set_implemented(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002424 goto error;
2425 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002426 }
2427
Pavol Vican8e7110b2016-03-22 17:00:26 +01002428 unres_schema_free(NULL, &unres);
2429 LOGVRB("Module \"%s\" successfully parsed.", module->name);
2430 return module;
2431
2432error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002433 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002434 unres_schema_free(module, &unres);
2435 if (!module || !module->name) {
2436 free(module);
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002437 if (ly_vecode != LYVE_SUBMODULE) {
2438 LOGERR(ly_errno, "Module parsing failed.");
2439 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002440 return NULL;
2441 }
2442
2443 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002444
2445 lys_sub_module_remove_devs_augs(module);
2446 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002447 return NULL;
2448}
2449
2450struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002451yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002452{
2453 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002454 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002455
2456 submodule = calloc(1, sizeof *submodule);
2457 if (!submodule) {
2458 LOGMEM;
2459 goto error;
2460 }
2461
2462 submodule->ctx = module->ctx;
2463 submodule->type = 1;
2464 submodule->belongsto = module;
2465
Pavol Vican9d50a772016-10-14 22:23:36 +02002466 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002467 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002468 goto error;
2469 }
2470
2471 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002472 goto error;
2473 }
2474
Pavol Vican8e7110b2016-03-22 17:00:26 +01002475 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002476 return submodule;
2477
2478error:
2479 /* cleanup */
2480 unres_schema_free((struct lys_module *)submodule, &unres);
2481
2482 if (!submodule || !submodule->name) {
2483 free(submodule);
2484 LOGERR(ly_errno, "Submodule parsing failed.");
2485 return NULL;
2486 }
2487
2488 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2489
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002490 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2491 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002492 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002493 return NULL;
2494}
Pavol Vican8760bb72016-04-07 09:44:01 +02002495
2496static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002497read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2498{
2499 int k = 0, j;
2500
2501 while (in_index < size) {
2502 if (input[in_index] == ' ') {
2503 k++;
2504 } else if (input[in_index] == '\t') {
2505 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2506 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002507 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2508 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2509 k += 8;
2510 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002511 } else {
2512 break;
2513 }
2514 ++in_index;
2515 if (k >= indent) {
2516 for (j = k - indent; j > 0; --j) {
2517 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002518 if (j > 1) {
2519 ++(*out_index);
2520 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002521 }
2522 break;
2523 }
2524 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002525 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002526}
2527
2528char *
PavolVican1bc22062017-01-19 15:09:04 +01002529yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002530 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002531
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002532 while (i < size) {
2533 switch (input[i]) {
2534 case '\n':
2535 out_index -= space;
2536 output[out_index] = '\n';
2537 space = 0;
2538 i = read_indent(input, indent, size, i + 1, &out_index, output);
2539 break;
2540 case ' ':
2541 case '\t':
2542 output[out_index] = input[i];
2543 ++space;
2544 break;
2545 case '\\':
2546 if (input[i + 1] == 'n') {
2547 out_index -= space;
2548 output[out_index] = '\n';
2549 space = 0;
2550 i = read_indent(input, indent, size, i + 2, &out_index, output);
2551 } else if (input[i + 1] == 't') {
2552 output[out_index] = '\t';
2553 ++i;
2554 ++space;
2555 } else if (input[i + 1] == '\\') {
2556 output[out_index] = '\\';
2557 ++i;
2558 } else if ((i + 1) != size && input[i + 1] == '"') {
2559 output[out_index] = '"';
2560 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002561 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002562 /* backslash must not be followed by any other character */
2563 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2564 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002565 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002566 break;
2567 default:
2568 output[out_index] = input[i];
2569 space = 0;
2570 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002571 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002572 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002573 ++out_index;
2574 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002575 output[out_index] = '\0';
2576 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002577 output = realloc(output, out_index + 1);
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002578 if (!output) {
2579 LOGMEM;
Pavol Vican3f598892016-09-28 15:41:07 +02002580 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002581 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002582 }
Pavol Vican3f598892016-09-28 15:41:07 +02002583 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002584}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002585
2586/* free function */
2587
Pavol Vican7313fc02016-11-14 01:10:31 +01002588static void yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
2589{
2590 struct yang_type *stype = (struct yang_type *)type->der;
2591 int i;
2592
2593 if (!stype) {
2594 return ;
2595 }
PavolVicane87cb932016-12-30 15:36:18 +01002596 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2597 lydict_remove(ctx, stype->name);
2598 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2599 for (i = 0; i < type->info.ident.count; ++i) {
2600 free(type->info.ident.ref[i]);
2601 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002602 }
PavolVicane87cb932016-12-30 15:36:18 +01002603 if (stype->base == LY_TYPE_UNION) {
2604 for (i = 0; i < type->info.uni.count; ++i) {
2605 yang_type_free(ctx, &type->info.uni.types[i]);
2606 }
2607 free(type->info.uni.types);
2608 type->base = LY_TYPE_DER;
2609 } else {
2610 type->base = stype->base;
2611 }
2612 free(stype);
2613 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002614 }
2615 lys_type_free(ctx, type);
Pavol Vican36aff862016-11-26 17:07:05 +01002616 type->base = LY_TYPE_DER;
Pavol Vican7313fc02016-11-14 01:10:31 +01002617}
2618
2619static void
2620yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint8_t start, uint8_t size)
2621{
2622 uint8_t i;
2623
2624 assert(ctx);
2625 if (!tpdf) {
2626 return;
2627 }
2628
2629 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002630 lydict_remove(ctx, tpdf[i].name);
2631 lydict_remove(ctx, tpdf[i].dsc);
2632 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002633
Pavol Vicancee10802016-11-22 15:48:35 +01002634 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002635
Pavol Vicancee10802016-11-22 15:48:35 +01002636 lydict_remove(ctx, tpdf[i].units);
2637 lydict_remove(ctx, tpdf[i].dflt);
Pavol Vican7313fc02016-11-14 01:10:31 +01002638 }
2639}
2640
Pavol Vican1cc4e192016-10-24 16:38:31 +02002641static void
2642yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2643{
2644 uint8_t i;
2645
2646 for (i = start; i < size; ++i){
2647 free((char *)imp[i].module);
2648 lydict_remove(ctx, imp[i].prefix);
2649 lydict_remove(ctx, imp[i].dsc);
2650 lydict_remove(ctx, imp[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002651 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002652 }
2653}
2654
Pavol Vicanec423c92016-10-24 21:33:43 +02002655static void
2656yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2657{
2658 uint8_t i;
2659
2660 for (i = start; i < size; ++i){
2661 free((char *)inc[i].submodule);
2662 lydict_remove(ctx, inc[i].dsc);
2663 lydict_remove(ctx, inc[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002664 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02002665 }
2666}
2667
Pavol Vican36e27272016-11-22 15:47:28 +01002668static void
2669yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2670{
2671 uint32_t i;
2672 uint8_t j;
2673
2674 /* free base name */
2675 for (i = start; i < size; ++i) {
2676 for (j = 0; j < ident[i].base_size; ++j) {
2677 free(ident[i].base[j]);
2678 }
2679 }
2680}
2681
Pavol Vican05810b62016-11-23 14:07:22 +01002682static void
2683yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2684{
2685 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2686 free(grp->tpdf);
2687}
2688
2689static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002690yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2691{
2692 uint8_t i;
2693
2694 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2695 free(cont->tpdf);
2696 lydict_remove(ctx, cont->presence);
2697
Pavol Vicanfda8c802016-12-03 02:00:42 +01002698 for (i = 0; i < cont->must_size; ++i) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002699 lys_restr_free(ctx, &cont->must[i]);
2700 }
2701 free(cont->must);
2702
2703 lys_when_free(ctx, cont->when);
2704}
2705
2706static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002707yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2708{
2709 uint8_t i;
2710
2711 for (i = 0; i < leaf->must_size; i++) {
2712 lys_restr_free(ctx, &leaf->must[i]);
2713 }
2714 free(leaf->must);
2715
2716 lys_when_free(ctx, leaf->when);
2717
2718 yang_type_free(ctx, &leaf->type);
2719 lydict_remove(ctx, leaf->units);
2720 lydict_remove(ctx, leaf->dflt);
2721}
2722
2723static void
Pavol Vican36aff862016-11-26 17:07:05 +01002724yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2725{
2726 uint8_t i;
2727
2728 for (i = 0; i < leaflist->must_size; i++) {
2729 lys_restr_free(ctx, &leaflist->must[i]);
2730 }
2731 free(leaflist->must);
2732
2733 for (i = 0; i < leaflist->dflt_size; i++) {
2734 lydict_remove(ctx, leaflist->dflt[i]);
2735 }
2736 free(leaflist->dflt);
2737
2738 lys_when_free(ctx, leaflist->when);
2739
2740 yang_type_free(ctx, &leaflist->type);
2741 lydict_remove(ctx, leaflist->units);
2742}
2743
2744static void
Pavol Vicand8136a42016-11-27 13:28:04 +01002745yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
2746{
2747 uint8_t i;
2748
2749 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
2750 free(list->tpdf);
2751
2752 for (i = 0; i < list->must_size; ++i) {
2753 lys_restr_free(ctx, &list->must[i]);
2754 }
2755 free(list->must);
2756
2757 lys_when_free(ctx, list->when);
2758
2759 for (i = 0; i < list->unique_size; ++i) {
2760 free(list->unique[i].expr);
2761 }
2762 free(list->unique);
2763
2764 free(list->keys);
2765}
2766
2767static void
Pavol Vican36ace102016-11-28 11:46:59 +01002768yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
2769{
2770 free(choice->dflt);
2771 lys_when_free(ctx, choice->when);
2772}
2773
2774static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002775yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
2776{
2777 uint8_t i;
2778
2779 for (i = 0; i < anydata->must_size; ++i) {
2780 lys_restr_free(ctx, &anydata->must[i]);
2781 }
2782 free(anydata->must);
2783
2784 lys_when_free(ctx, anydata->when);
2785}
2786
2787static void
Pavol Vican78729392016-11-28 17:18:22 +01002788yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
2789{
2790 uint8_t i;
2791
2792 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
2793 free(inout->tpdf);
2794
2795 for (i = 0; i < inout->must_size; ++i) {
2796 lys_restr_free(ctx, &inout->must[i]);
2797 }
2798 free(inout->must);
2799}
2800
2801static void
Pavol Vican29bf8802016-11-28 20:44:57 +01002802yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
2803{
2804 uint8_t i;
2805
2806 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
2807 free(notif->tpdf);
2808
2809 for (i = 0; i < notif->must_size; ++i) {
2810 lys_restr_free(ctx, &notif->must[i]);
2811 }
2812 free(notif->must);
2813}
2814
2815static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002816yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
2817{
2818 int i, j;
2819
2820 for (i = 0; i < uses->refine_size; i++) {
2821 lydict_remove(ctx, uses->refine[i].target_name);
2822 lydict_remove(ctx, uses->refine[i].dsc);
2823 lydict_remove(ctx, uses->refine[i].ref);
2824
2825 for (j = 0; j < uses->refine[i].must_size; j++) {
2826 lys_restr_free(ctx, &uses->refine[i].must[j]);
2827 }
2828 free(uses->refine[i].must);
2829
2830 for (j = 0; j < uses->refine[i].dflt_size; j++) {
2831 lydict_remove(ctx, uses->refine[i].dflt[j]);
2832 }
2833 free(uses->refine[i].dflt);
2834
2835 if (uses->refine[i].target_type & LYS_CONTAINER) {
2836 lydict_remove(ctx, uses->refine[i].mod.presence);
2837 }
2838 }
2839 free(uses->refine);
2840
2841 lys_when_free(ctx, uses->when);
2842}
2843
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002844static void
Pavol Vican05810b62016-11-23 14:07:22 +01002845yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
2846{
2847 struct lys_node *tmp, *child, *sibling;
2848
2849 if (!node) {
2850 return;
2851 }
2852 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01002853
2854 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002855 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01002856 sibling = tmp->next;
2857 /* common part */
2858 lydict_remove(ctx, tmp->name);
2859 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
PavolVican8c33b152017-01-27 12:45:34 +01002860 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002861 lydict_remove(ctx, tmp->dsc);
2862 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01002863 }
2864
2865 switch (tmp->nodetype) {
2866 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01002867 case LYS_RPC:
2868 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01002869 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
2870 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002871 case LYS_CONTAINER:
2872 yang_free_container(ctx, (struct lys_node_container *)tmp);
2873 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01002874 case LYS_LEAF:
2875 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
2876 break;
Pavol Vican36aff862016-11-26 17:07:05 +01002877 case LYS_LEAFLIST:
2878 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
2879 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01002880 case LYS_LIST:
2881 yang_free_list(ctx, (struct lys_node_list *)tmp);
2882 break;
Pavol Vican36ace102016-11-28 11:46:59 +01002883 case LYS_CHOICE:
2884 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
2885 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01002886 case LYS_CASE:
2887 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when);
2888 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002889 case LYS_ANYXML:
2890 case LYS_ANYDATA:
2891 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
2892 break;
Pavol Vican78729392016-11-28 17:18:22 +01002893 case LYS_INPUT:
2894 case LYS_OUTPUT:
2895 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
2896 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01002897 case LYS_NOTIF:
2898 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
2899 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002900 case LYS_USES:
2901 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
2902 break;
Pavol Vican05810b62016-11-23 14:07:22 +01002903 default:
2904 break;
2905 }
2906
2907 yang_free_nodes(ctx, child);
2908 free(tmp);
2909 tmp = sibling;
2910 }
2911}
2912
Pavol Vican3ad50f82016-12-04 15:00:36 +01002913static void
2914yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
2915{
2916 lydict_remove(ctx, aug->target_name);
2917 lydict_remove(ctx, aug->dsc);
2918 lydict_remove(ctx, aug->ref);
2919
PavolVican8c33b152017-01-27 12:45:34 +01002920 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size);
Pavol Vican3ad50f82016-12-04 15:00:36 +01002921 lys_when_free(ctx, aug->when);
2922 yang_free_nodes(ctx, aug->child);
2923}
2924
PavolVican75af21d2016-12-29 20:04:07 +01002925static void
2926yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
2927{
2928 uint i, j;
2929
2930 for (i = index; i < dev->deviate_size; ++i) {
2931 lydict_remove(ctx, dev->deviate[i].units);
2932
2933 if (dev->deviate[i].type) {
2934 yang_type_free(ctx, dev->deviate[i].type);
2935 }
2936
2937 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
2938 lydict_remove(ctx, dev->deviate[i].dflt[j]);
2939 }
2940 free(dev->deviate[i].dflt);
2941
2942 for (j = 0; j < dev->deviate[i].must_size; ++j) {
2943 lys_restr_free(ctx, &dev->deviate[i].must[j]);
2944 }
2945 free(dev->deviate[i].must);
2946
2947 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
2948 free(dev->deviate[i].unique[j].expr);
2949 }
2950 free(dev->deviate[i].unique);
2951 }
2952}
2953
Pavol Vican7313fc02016-11-14 01:10:31 +01002954/* free common item from module and submodule */
2955static void
Pavol Vican05810b62016-11-23 14:07:22 +01002956free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01002957{
PavolVican75af21d2016-12-29 20:04:07 +01002958 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002959 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
2960 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01002961 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01002962 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01002963 for (i = 0; i < module->augment_size; ++i) {
2964 yang_free_augment(module->ctx, &module->augment[i]);
2965 }
2966 module->augment_size = 0;
2967 for (i = 0; i < module->deviation_size; ++i) {
2968 yang_free_deviate(module->ctx, &module->deviation[i], 0);
2969 free(module->deviation[i].deviate);
2970 }
2971 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01002972}
2973
Pavol Vican1cc4e192016-10-24 16:38:31 +02002974/* check function*/
2975
2976int
PavolVicanc1807262017-01-31 18:00:27 +01002977yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
2978 void *parent, struct unres_schema *unres)
2979{
2980 struct unres_ext *info;
2981 uint i;
2982
2983 for (i = 0; i < size; ++i) {
2984 info = malloc(sizeof *info);
2985 info->data.yang = (*ext)[i]->parent;
2986 info->datatype = LYS_IN_YANG;
2987 info->parent = parent;
2988 info->mod = module;
2989 info->parent_type = (*ext)[i]->parent_type;
2990 info->substmt = (*ext)[i]->substmt;
2991 info->substmt_index = (*ext)[i]->substmt_index;
2992 info->ext_index = i;
2993 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
2994 return EXIT_FAILURE;
2995 }
2996 }
2997
2998 return EXIT_SUCCESS;
2999}
3000
3001int
Pavol Vicanec423c92016-10-24 21:33:43 +02003002yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003003{
3004 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003005 struct lys_include *inc;
3006 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003007 size_t size;
3008 char *s;
3009
3010 imp = module->imp;
3011 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003012 inc = module->inc;
3013 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003014
3015 if (imp_size) {
3016 size = (imp_size * sizeof *module->imp) + sizeof(void*);
3017 module->imp_size = 0;
3018 module->imp = calloc(1, size);
3019 if (!module->imp) {
3020 LOGMEM;
3021 goto error;
3022 }
3023 /* set stop block for possible realloc */
3024 module->imp[imp_size].module = (void*)0x1;
Pavol Vicanec423c92016-10-24 21:33:43 +02003025 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003026
Pavol Vicanec423c92016-10-24 21:33:43 +02003027 if (inc_size) {
3028 size = (inc_size * sizeof *module->inc) + sizeof(void*);
3029 module->inc_size = 0;
3030 module->inc = calloc(1, size);
3031 if (!module->inc) {
3032 LOGMEM;
3033 goto error;
3034 }
3035 /* set stop block for possible realloc */
3036 module->inc[inc_size].submodule = (void*)0x1;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003037 }
3038
3039 for (i = 0; i < imp_size; ++i) {
3040 s = (char *) imp[i].module;
3041 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003042 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003043 ++i;
3044 goto error;
3045 }
3046 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003047 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003048 s = (char *) inc[j].submodule;
3049 inc[j].submodule = NULL;
3050 if (yang_fill_include(module, s, &inc[j], unres)) {
3051 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003052 goto error;
3053 }
3054 }
3055 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003056 free(imp);
3057
3058 return EXIT_SUCCESS;
3059
3060error:
3061 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003062 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003063 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003064 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003065 return EXIT_FAILURE;
3066}
Pavol Vican7313fc02016-11-14 01:10:31 +01003067
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003068static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003069yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003070{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003071 struct lys_iffeature *iffeature;
3072 uint8_t *ptr_size, size, i;
3073 char *s;
3074 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003075
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003076 switch (type) {
3077 case FEATURE_KEYWORD:
3078 iffeature = ((struct lys_feature *)parent)->iffeature;
3079 size = ((struct lys_feature *)parent)->iffeature_size;
3080 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3081 parent_is_feature = 1;
3082 break;
3083 case IDENTITY_KEYWORD:
3084 iffeature = ((struct lys_ident *)parent)->iffeature;
3085 size = ((struct lys_ident *)parent)->iffeature_size;
3086 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3087 break;
3088 case ENUM_KEYWORD:
3089 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3090 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3091 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3092 break;
3093 case BIT_KEYWORD:
3094 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3095 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3096 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3097 break;
3098 case REFINE_KEYWORD:
3099 iffeature = ((struct lys_refine *)ptr)->iffeature;
3100 size = ((struct lys_refine *)ptr)->iffeature_size;
3101 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3102 break;
3103 default:
3104 iffeature = ((struct lys_node *)parent)->iffeature;
3105 size = ((struct lys_node *)parent)->iffeature_size;
3106 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3107 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003108 }
3109
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003110 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003111 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003112 s = (char *)iffeature[i].features;
3113 iffeature[i].features = NULL;
3114 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3115 *ptr_size = size;
3116 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003117 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003118 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003119 }
3120
3121 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003122}
3123
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003124static int
3125yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3126{
3127 uint size, i;
3128 int rc;
3129 struct lys_ident **ref;
3130 const char *value;
3131 char *expr;
3132
3133 ref = type->info.ident.ref;
3134 size = type->info.ident.count;
3135 type->info.ident.count = 0;
3136 type->info.ident.ref = NULL;
3137 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3138
3139 for (i = 0; i < size; ++i) {
3140 expr = (char *)ref[i];
3141 /* store in the JSON format */
3142 value = transform_schema2json(module, expr);
3143 free(expr);
3144
3145 if (!value) {
3146 goto error;
3147 }
3148 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3149 lydict_remove(module->ctx, value);
3150
3151 if (rc == -1) {
3152 goto error;
3153 }
3154 }
3155 free(ref);
3156
3157 return EXIT_SUCCESS;
3158error:
3159 for (i = i+1; i < size; ++i) {
3160 free(ref[i]);
3161 }
3162 free(ref);
3163 return EXIT_FAILURE;
3164}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003165
Pavol Vican7313fc02016-11-14 01:10:31 +01003166int
3167yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3168{
3169 struct lys_tpdf *tpdf;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003170 uint8_t j, i, tpdf_size, *ptr_tpdf_size;
3171 struct yang_type *stype;
Pavol Vican7313fc02016-11-14 01:10:31 +01003172
3173 if (!parent) {
3174 tpdf = module->tpdf;
3175 ptr_tpdf_size = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003176 } else {
3177 switch (parent->nodetype) {
3178 case LYS_GROUPING:
3179 tpdf = ((struct lys_node_grp *)parent)->tpdf;
3180 ptr_tpdf_size = &((struct lys_node_grp *)parent)->tpdf_size;
3181 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003182 case LYS_CONTAINER:
3183 tpdf = ((struct lys_node_container *)parent)->tpdf;
3184 ptr_tpdf_size = &((struct lys_node_container *)parent)->tpdf_size;
3185 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003186 case LYS_LIST:
3187 tpdf = ((struct lys_node_list *)parent)->tpdf;
3188 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3189 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003190 case LYS_RPC:
3191 case LYS_ACTION:
3192 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3193 ptr_tpdf_size = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3194 break;
Pavol Vican78729392016-11-28 17:18:22 +01003195 case LYS_INPUT:
3196 case LYS_OUTPUT:
3197 tpdf = ((struct lys_node_inout *)parent)->tpdf;
3198 ptr_tpdf_size = &((struct lys_node_inout *)parent)->tpdf_size;
3199 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003200 case LYS_NOTIF:
3201 tpdf = ((struct lys_node_notif *)parent)->tpdf;
3202 ptr_tpdf_size = &((struct lys_node_notif *)parent)->tpdf_size;
3203 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003204 default:
3205 LOGINT;
3206 return EXIT_FAILURE;
3207 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003208 }
3209
3210 tpdf_size = *ptr_tpdf_size;
3211 *ptr_tpdf_size = 0;
3212
3213 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003214 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3215 goto error;
3216 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003217 tpdf[i].type.parent = &tpdf[i];
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003218
3219 stype = (struct yang_type *)tpdf[i].type.der;
3220 if (stype->base == LY_TYPE_ENUM) {
3221 for (j = 0; j < tpdf[i].type.info.enums.count; ++j) {
3222 if (yang_check_iffeatures(module, &tpdf[i].type.info.enums.enm[j], &tpdf[i], ENUM_KEYWORD, unres)) {
3223 goto error;
3224 }
3225 }
3226 } else if (stype->base == LY_TYPE_BITS) {
3227 for (j = 0; j < tpdf[i].type.info.bits.count; ++j) {
3228 if (yang_check_iffeatures(module, &tpdf[i].type.info.bits.bit[j], &tpdf[i], BIT_KEYWORD, unres)) {
3229 goto error;
3230 }
3231 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003232 } else if (stype->base == LY_TYPE_IDENT) {
3233 if (yang_check_identityref(module, &tpdf[i].type, unres)) {
3234 goto error;
3235 }
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003236 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003237
Pavol Vican7313fc02016-11-14 01:10:31 +01003238 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003239 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003240 }
3241
PavolVicane87cb932016-12-30 15:36:18 +01003242 (*ptr_tpdf_size)++;
Pavol Vican7313fc02016-11-14 01:10:31 +01003243 /* check default value*/
Pavol Vicanfda8c802016-12-03 02:00:42 +01003244 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DFLT, (struct lys_node *)(&tpdf[i].dflt)) == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +01003245 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003246 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003247 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003248 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003249
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003250 return EXIT_SUCCESS;
3251
3252error:
3253 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3254 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003255}
3256
3257static int
Pavol Vican36e27272016-11-22 15:47:28 +01003258yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3259{
3260 uint32_t i, size, base_size;
3261 uint8_t j;
3262
3263 size = module->ident_size;
3264 module->ident_size = 0;
3265 for (i = 0; i < size; ++i) {
3266 base_size = module->ident[i].base_size;
3267 module->ident[i].base_size = 0;
3268 for (j = 0; j < base_size; ++j) {
3269 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3270 ++j;
3271 module->ident_size = size;
3272 goto error;
3273 }
3274 }
3275 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003276 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3277 goto error;
3278 }
Pavol Vican36e27272016-11-22 15:47:28 +01003279 }
3280
3281 return EXIT_SUCCESS;
3282
3283error:
3284 for (; j< module->ident[i].base_size; ++j) {
3285 free(module->ident[i].base[j]);
3286 }
3287 yang_free_ident_base(module->ident, i + 1, size);
3288 return EXIT_FAILURE;
3289}
3290
3291static int
PavolVicane87cb932016-12-30 15:36:18 +01003292yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
3293 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003294{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003295 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003296 goto error;
3297 }
3298
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003299 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003300 goto error;
3301 }
3302
PavolVicane87cb932016-12-30 15:36:18 +01003303 if (yang_check_nodes(module, (struct lys_node *)cont, *child, config_opt, unres)) {
3304 *child = NULL;
3305 goto error;
3306 }
3307 *child = NULL;
3308
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003309 /* check XPath dependencies */
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003310 if ((cont->when || cont->must_size) && (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003311 goto error;
3312 }
3313
3314 return EXIT_SUCCESS;
3315error:
3316 return EXIT_FAILURE;
3317}
3318
3319static int
Pavol Vicana69aff22016-11-24 18:23:50 +01003320yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, struct unres_schema *unres)
3321{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003322 int i;
3323 struct yang_type *stype;
Pavol Vicana69aff22016-11-24 18:23:50 +01003324
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003325 stype = (struct yang_type *)leaf->type.der;
3326 if (stype->base == LY_TYPE_ENUM) {
3327 for (i = 0; i < leaf->type.info.enums.count; ++i) {
3328 if (yang_check_iffeatures(module, &leaf->type.info.enums.enm[i], leaf, ENUM_KEYWORD, unres)) {
3329 yang_type_free(module->ctx, &leaf->type);
3330 goto error;
3331 }
3332 }
3333 } else if (stype->base == LY_TYPE_BITS) {
3334 for (i = 0; i < leaf->type.info.bits.count; ++i) {
3335 if (yang_check_iffeatures(module, &leaf->type.info.bits.bit[i], leaf, BIT_KEYWORD, unres)) {
3336 yang_type_free(module->ctx, &leaf->type);
3337 goto error;
3338 }
3339 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003340 } else if (stype->base == LY_TYPE_IDENT) {
3341 if (yang_check_identityref(module, &leaf->type, unres)) {
PavolVicana08d3652016-12-29 21:07:47 +01003342 yang_type_free(module->ctx, &leaf->type);
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003343 goto error;
3344 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003345 }
3346
PavolVicana08d3652016-12-29 21:07:47 +01003347 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3348 yang_type_free(module->ctx, &leaf->type);
3349 goto error;
3350 }
3351
Pavol Vicanfda8c802016-12-03 02:00:42 +01003352 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003353 yang_type_free(module->ctx, &leaf->type);
3354 goto error;
3355 }
3356
Pavol Vicanfda8c802016-12-03 02:00:42 +01003357 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003358 goto error;
3359 }
3360
Pavol Vicana69aff22016-11-24 18:23:50 +01003361 /* check XPath dependencies */
3362 if ((leaf->when || leaf->must_size) && (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1)) {
3363 goto error;
3364 }
3365
3366 return EXIT_SUCCESS;
3367error:
3368 return EXIT_FAILURE;
3369}
3370
3371static int
Pavol Vican36aff862016-11-26 17:07:05 +01003372yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, struct unres_schema *unres)
3373{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003374 int i, j;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003375 struct yang_type *stype;
Pavol Vican36aff862016-11-26 17:07:05 +01003376
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003377 stype = (struct yang_type *)leaflist->type.der;
3378 if (stype->base == LY_TYPE_ENUM) {
3379 for (i = 0; i < leaflist->type.info.enums.count; ++i) {
3380 if (yang_check_iffeatures(module, &leaflist->type.info.enums.enm[i], leaflist, ENUM_KEYWORD, unres)) {
3381 yang_type_free(module->ctx, &leaflist->type);
3382 goto error;
3383 }
3384 }
3385 } else if (stype->base == LY_TYPE_BITS) {
3386 for (i = 0; i < leaflist->type.info.bits.count; ++i) {
3387 if (yang_check_iffeatures(module, &leaflist->type.info.bits.bit[i], leaflist, BIT_KEYWORD, unres)) {
3388 yang_type_free(module->ctx, &leaflist->type);
3389 goto error;
3390 }
3391 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003392 } else if (stype->base == LY_TYPE_IDENT) {
3393 if (yang_check_identityref(module, &leaflist->type, unres)) {
PavolVicana08d3652016-12-29 21:07:47 +01003394 yang_type_free(module->ctx, &leaflist->type);
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003395 goto error;
3396 }
Pavol Vican36aff862016-11-26 17:07:05 +01003397 }
3398
PavolVicana08d3652016-12-29 21:07:47 +01003399 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3400 yang_type_free(module->ctx, &leaflist->type);
3401 goto error;
3402 }
3403
Pavol Vicanfda8c802016-12-03 02:00:42 +01003404 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003405 yang_type_free(module->ctx, &leaflist->type);
3406 goto error;
3407 }
3408
Pavol Vican36aff862016-11-26 17:07:05 +01003409 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003410 /* check for duplicity in case of configuration data,
3411 * in case of status data duplicities are allowed */
3412 if (leaflist->flags & LYS_CONFIG_W) {
3413 for (j = i +1; j < leaflist->dflt_size; ++j) {
3414 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003415 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3416 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003417 goto error;
3418 }
3419 }
3420 }
3421 /* check default value (if not defined, there still could be some restrictions
3422 * that need to be checked against a default value from a derived type) */
Pavol Vican36aff862016-11-26 17:07:05 +01003423 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaflist->dflt[i])) == -1) {
3424 goto error;
3425 }
3426 }
3427
Pavol Vican36aff862016-11-26 17:07:05 +01003428 /* check XPath dependencies */
3429 if ((leaflist->when || leaflist->must_size) && (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1)) {
3430 goto error;
3431 }
3432
3433 return EXIT_SUCCESS;
3434error:
3435 return EXIT_FAILURE;
3436}
3437
3438static int
PavolVicane87cb932016-12-30 15:36:18 +01003439yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
3440 int config_opt, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003441{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003442 struct lys_node *node;
3443
Pavol Vicand8136a42016-11-27 13:28:04 +01003444 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3445 goto error;
3446 }
3447
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003448 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3449 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003450 }
3451
Pavol Vicanfda8c802016-12-03 02:00:42 +01003452 if (list->flags & LYS_CONFIG_R) {
3453 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3454 * ignore oredering MASK - 0x7F
3455 */
3456 list->flags &= 0x7F;
3457 }
3458 /* check - if list is configuration, key statement is mandatory
3459 * (but only if we are not in a grouping or augment, then the check is deferred) */
3460 for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT)); node = node->parent);
3461 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3462 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3463 goto error;
3464 }
3465
PavolVicane87cb932016-12-30 15:36:18 +01003466 if (yang_check_nodes(module, (struct lys_node *)list, *child, config_opt, unres)) {
3467 *child = NULL;
3468 goto error;
3469 }
3470 *child = NULL;
3471
Pavol Vicand8136a42016-11-27 13:28:04 +01003472 if (list->keys && yang_read_key(module, list, unres)) {
3473 goto error;
3474 }
3475
3476 if (yang_read_unique(module, list, unres)) {
3477 goto error;
3478 }
3479
3480 /* check XPath dependencies */
3481 if ((list->when || list->must_size) && (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1)) {
3482 goto error;
3483 }
3484
3485 return EXIT_SUCCESS;
3486error:
3487 return EXIT_FAILURE;
3488}
3489
3490static int
PavolVicane87cb932016-12-30 15:36:18 +01003491yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
3492 int config_opt, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003493{
3494 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003495
PavolVicana08d3652016-12-29 21:07:47 +01003496 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3497 free(choice->dflt);
3498 choice->dflt = NULL;
3499 goto error;
3500 }
3501
PavolVicane87cb932016-12-30 15:36:18 +01003502 if (yang_check_nodes(module, (struct lys_node *)choice, *child, config_opt, unres)) {
3503 *child = NULL;
3504 free(choice->dflt);
3505 choice->dflt = NULL;
3506 goto error;
3507 }
3508 *child = NULL;
3509
Pavol Vican36ace102016-11-28 11:46:59 +01003510 if (choice->dflt) {
3511 value = (char *)choice->dflt;
3512 choice->dflt = NULL;
3513 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3514 free(value);
3515 goto error;
3516 }
3517 free(value);
3518 }
3519
Pavol Vican36ace102016-11-28 11:46:59 +01003520 /* check XPath dependencies */
3521 if ((choice->when) && (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1)) {
3522 goto error;
3523 }
3524
3525 return EXIT_SUCCESS;
3526error:
3527 return EXIT_FAILURE;
3528}
3529
3530static int
PavolVicane87cb932016-12-30 15:36:18 +01003531yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
3532 int config_opt, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003533{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003534 struct lys_node *node;
3535
3536 if (rpc->nodetype == LYS_ACTION) {
3537 for (node = rpc->parent; node; node = lys_parent(node)) {
3538 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003539 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003540 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003541 goto error;
3542 }
3543 }
3544 }
3545 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3546 goto error;
3547 }
3548
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003549 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3550 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003551 }
3552
PavolVicane87cb932016-12-30 15:36:18 +01003553 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, config_opt, unres)) {
3554 *child = NULL;
3555 goto error;
3556 }
3557 *child = NULL;
3558
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003559 return EXIT_SUCCESS;
3560error:
3561 return EXIT_FAILURE;
3562}
3563
3564static int
PavolVicane87cb932016-12-30 15:36:18 +01003565yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
3566 int config_opt, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01003567{
Pavol Vican29bf8802016-11-28 20:44:57 +01003568 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3569 goto error;
3570 }
3571
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003572 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3573 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003574 }
3575
PavolVicane87cb932016-12-30 15:36:18 +01003576 if (yang_check_nodes(module, (struct lys_node *)notif, *child, config_opt, unres)) {
3577 *child = NULL;
3578 goto error;
3579 }
3580 *child = NULL;
3581
Pavol Vican29bf8802016-11-28 20:44:57 +01003582 /* check XPath dependencies */
3583 if ((notif->must_size) && (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1)) {
3584 goto error;
3585 }
3586
3587 return EXIT_SUCCESS;
3588error:
3589 return EXIT_FAILURE;
3590}
3591
3592static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003593yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int config_opt, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003594{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003595 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003596
Pavol Vican3ad50f82016-12-04 15:00:36 +01003597 child = augment->child;
3598 augment->child = NULL;
3599
PavolVicana08d3652016-12-29 21:07:47 +01003600 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
3601 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003602 goto error;
3603 }
3604
PavolVicana08d3652016-12-29 21:07:47 +01003605 if (yang_check_nodes(module, (struct lys_node *)augment, child, config_opt, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01003606 goto error;
3607 }
3608
3609 /* check XPath dependencies */
3610 if (augment->when && (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1)) {
3611 goto error;
3612 }
3613
3614 return EXIT_SUCCESS;
3615error:
3616 return EXIT_FAILURE;
3617}
3618
3619static int
3620yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int config_opt, struct unres_schema *unres)
3621{
3622 uint i, size;
3623
3624 size = uses->augment_size;
3625 uses->augment_size = 0;
3626
3627 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003628 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003629 }
3630
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003631 for (i = 0; i < uses->refine_size; ++i) {
3632 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
3633 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003634 }
3635 }
3636
Pavol Vican3ad50f82016-12-04 15:00:36 +01003637 for (i = 0; i < size; ++i) {
3638 uses->augment_size++;
3639 if (yang_check_augment(module, &uses->augment[i], config_opt, unres)) {
3640 goto error;
3641 }
3642 }
3643
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003644 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
3645 goto error;
3646 }
3647
3648 /* check XPath dependencies */
3649 if (uses->when && (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1)) {
3650 goto error;
3651 }
3652
3653 return EXIT_SUCCESS;
3654error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003655 for (i = uses->augment_size; i < size; ++i) {
3656 yang_free_augment(module->ctx, &uses->augment[i]);
3657 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003658 return EXIT_FAILURE;
3659}
3660
3661static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003662yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
3663 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003664{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003665 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01003666
3667 while (node) {
3668 sibling = node->next;
3669 child = node->child;
3670 node->next = NULL;
3671 node->child = NULL;
3672 node->prev = node;
PavolVican8c33b152017-01-27 12:45:34 +01003673
Pavol Vican24ba7f62016-11-28 12:15:20 +01003674 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
3675 lys_node_unlink(node);
3676 node->next = sibling;
Pavol Vican05810b62016-11-23 14:07:22 +01003677 sibling = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003678 goto error;
3679 }
Pavol Vicanec598812016-11-30 14:13:38 +01003680 config_opt = store_config_flag(node, config_opt);
PavolVican70ce7452017-02-01 15:39:39 +01003681 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
3682 goto error;
3683 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01003684
Pavol Vican05810b62016-11-23 14:07:22 +01003685 switch (node->nodetype) {
3686 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003687 if (yang_check_typedef(module, node, unres)) {
3688 goto error;
3689 }
3690 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003691 goto error;
3692 }
PavolVicane87cb932016-12-30 15:36:18 +01003693 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3694 child = NULL;
3695 goto error;
3696 }
Pavol Vican05810b62016-11-23 14:07:22 +01003697 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003698 case LYS_CONTAINER:
PavolVicane87cb932016-12-30 15:36:18 +01003699 if (yang_check_container(module, (struct lys_node_container *)node, &child, config_opt, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003700 goto error;
3701 }
3702 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003703 case LYS_LEAF:
3704 if (yang_check_leaf(module, (struct lys_node_leaf *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003705 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01003706 goto error;
3707 }
3708 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003709 case LYS_LEAFLIST:
3710 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003711 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01003712 goto error;
3713 }
3714 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003715 case LYS_LIST:
PavolVicane87cb932016-12-30 15:36:18 +01003716 if (yang_check_list(module, (struct lys_node_list *)node, &child, config_opt, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01003717 goto error;
3718 }
3719 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003720 case LYS_CHOICE:
PavolVicane87cb932016-12-30 15:36:18 +01003721 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, config_opt, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01003722 goto error;
3723 }
3724 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003725 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003726 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01003727 goto error;
3728 }
PavolVicane87cb932016-12-30 15:36:18 +01003729 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3730 child = NULL;
3731 goto error;
3732 }
Pavol Vicana420bac2016-11-28 14:51:54 +01003733 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003734 case LYS_ANYDATA:
3735 case LYS_ANYXML:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003736 if (yang_check_iffeatures(module, NULL, node, CHOICE_KEYWORD, unres)) {
3737 goto error;
3738 }
PavolVicane87cb932016-12-30 15:36:18 +01003739 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3740 child = NULL;
3741 goto error;
3742 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003743 /* check XPath dependencies */
3744 if ((((struct lys_node_anydata *)node)->when) && (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003745 goto error;
3746 }
3747 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003748 case LYS_RPC:
3749 case LYS_ACTION:
PavolVicane87cb932016-12-30 15:36:18 +01003750 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, config_opt, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003751 goto error;
3752 }
3753 break;
Pavol Vican78729392016-11-28 17:18:22 +01003754 case LYS_INPUT:
3755 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01003756 if (yang_check_typedef(module, node, unres)) {
3757 goto error;
3758 }
3759 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3760 child = NULL;
3761 goto error;
3762 }
Pavol Vican78729392016-11-28 17:18:22 +01003763 /* check XPath dependencies */
3764 if (((struct lys_node_inout *)node)->must_size &&
3765 (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1)) {
3766 goto error;
3767 }
Pavol Vican78729392016-11-28 17:18:22 +01003768 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003769 case LYS_NOTIF:
PavolVicane87cb932016-12-30 15:36:18 +01003770 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, config_opt, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01003771 goto error;
3772 }
3773 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003774 case LYS_USES:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003775 if (yang_check_uses(module, (struct lys_node_uses *)node, config_opt, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003776 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003777 goto error;
3778 }
3779 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003780 default:
3781 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01003782 goto error;
3783 }
Pavol Vican05810b62016-11-23 14:07:22 +01003784 node = sibling;
3785 }
3786
3787 return EXIT_SUCCESS;
3788error:
3789 yang_free_nodes(module->ctx, sibling);
3790 yang_free_nodes(module->ctx, child);
3791 return EXIT_FAILURE;
3792}
3793
3794static int
PavolVican75af21d2016-12-29 20:04:07 +01003795yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
3796 struct lys_node *dev_target, struct ly_set *dflt_check)
3797{
3798 struct lys_node_leaflist *llist;
3799 struct lys_type *type;
3800 struct lys_tpdf *tmp_parent;
3801 int i, j;
3802
3803 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
3804 goto error;
3805 }
3806 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
3807 goto error;
3808 }
3809 if (deviate->dflt_size) {
3810 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
3811 goto error;
3812 }
3813 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
3814 /* consolidate the final list in the target after removing items from it */
3815 llist = (struct lys_node_leaflist *)dev_target;
3816 for (i = j = 0; j < llist->dflt_size; j++) {
3817 llist->dflt[i] = llist->dflt[j];
3818 if (llist->dflt[i]) {
3819 i++;
3820 }
3821 }
3822 llist->dflt_size = i + 1;
3823 }
3824 }
3825
3826 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
3827 goto error;
3828 }
3829
3830 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
3831 goto error;
3832 }
3833
3834 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
3835 goto error;
3836 }
3837
3838 if ((deviate->flags & LYS_CONFIG_MASK)) {
3839 /* add and replace are the same in this case */
3840 /* remove current config value of the target ... */
3841 dev_target->flags &= ~LYS_CONFIG_MASK;
3842
3843 /* ... and replace it with the value specified in deviation */
3844 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
3845 }
3846
3847 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
3848 goto error;
3849 }
3850
3851 if (deviate->type) {
3852 /* check target node type */
3853 if (dev_target->nodetype == LYS_LEAF) {
3854 type = &((struct lys_node_leaf *)dev_target)->type;
3855 } else if (dev_target->nodetype == LYS_LEAFLIST) {
3856 type = &((struct lys_node_leaflist *)dev_target)->type;
3857 } else {
3858 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
3859 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
3860 goto error;
3861 }
3862 /* remove type and initialize it */
3863 tmp_parent = type->parent;
3864 lys_type_free(module->ctx, type);
3865 memcpy(type, deviate->type, sizeof *deviate->type);
3866 free(deviate->type);
3867 deviate->type = type;
3868 deviate->type->parent = tmp_parent;
3869 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
3870 goto error;
3871 }
3872 }
3873
3874 return EXIT_SUCCESS;
3875error:
3876 if (deviate->type) {
3877 yang_type_free(module->ctx, deviate->type);
3878 deviate->type = NULL;
3879 }
3880 return EXIT_FAILURE;
3881}
3882
3883static int
3884yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
3885{
3886 int rc;
3887 uint i;
3888 struct lys_node *dev_target = NULL, *parent;
3889 struct ly_set *dflt_check = ly_set_new();
3890 unsigned int u;
3891 const char *value, *target_name;
3892 struct lys_node_leaflist *llist;
3893 struct lys_node_leaf *leaf;
3894 struct unres_schema tmp_unres;
3895 struct lys_module *mod;
3896
3897 /* resolve target node */
3898 rc = resolve_augment_schema_nodeid(dev->target_name, NULL, module, 1, (const struct lys_node **)&dev_target);
3899 if (rc || !dev_target) {
3900 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
3901 goto error;
3902 }
3903 if (dev_target->module == lys_main_module(module)) {
3904 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
3905 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
3906 goto error;
3907 }
3908
3909 if (!dflt_check) {
3910 LOGMEM;
3911 goto error;
3912 }
3913
3914 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
3915 /* you cannot remove a key leaf */
3916 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
3917 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
3918 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
3919 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
3920 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
3921 return EXIT_FAILURE;
3922 }
3923 }
3924 }
3925 /* unlink and store the original node */
3926 lys_node_unlink(dev_target);
3927 dev->orig_node = dev_target;
3928 } else {
3929 /* store a shallow copy of the original node */
3930 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01003931 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01003932 /* just to be safe */
3933 if (tmp_unres.count) {
3934 LOGINT;
3935 goto error;
3936 }
3937 }
3938
3939 for (i = 0; i < dev->deviate_size; ++i) {
3940 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
3941 yang_free_deviate(module->ctx, dev, i + 1);
3942 dev->deviate_size = i+1;
3943 goto error; // missing free unresolve type in deviate
3944 }
3945 }
3946 /* now check whether default value, if any, matches the type */
3947 for (u = 0; u < dflt_check->number; ++u) {
3948 value = NULL;
3949 rc = EXIT_SUCCESS;
3950 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
3951 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
3952 target_name = leaf->name;
3953 value = leaf->dflt;
3954 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
3955 } else { /* LYS_LEAFLIST */
3956 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
3957 target_name = llist->name;
3958 for (i = 0; i < llist->dflt_size; i++) {
3959 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
3960 (struct lys_node *)(&llist->dflt[i]));
3961 if (rc == -1) {
3962 value = llist->dflt[i];
3963 break;
3964 }
3965 }
3966 }
3967 if (rc == -1) {
3968 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
3969 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
3970 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
3971 target_name);
3972 goto error;
3973 }
3974 }
3975 ly_set_free(dflt_check);
3976
3977 /* mark all the affected modules as deviated and implemented*/
3978 for(parent = dev_target; parent; parent = lys_parent(parent)) {
3979 mod = lys_node_module(parent);
3980 if (module != mod) {
3981 mod->deviated = 1;
3982 lys_set_implemented(mod);
3983 }
3984}
3985
3986 return EXIT_SUCCESS;
3987error:
3988 ly_set_free(dflt_check);
3989 return EXIT_FAILURE;
3990}
3991
3992static int
Pavol Vican7313fc02016-11-14 01:10:31 +01003993yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
3994{
PavolVican75af21d2016-12-29 20:04:07 +01003995 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01003996
3997 aug_size = module->augment_size;
3998 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01003999 dev_size = module->deviation_size;
4000 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004001
PavolVicanc1807262017-01-31 18:00:27 +01004002 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4003 goto error;
4004 }
4005
PavolVican171717d2017-02-01 14:49:55 +01004006 /* check extension in revision */
4007 for (i = 0; i < module->rev_size; ++i) {
4008 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4009 goto error;
4010 }
4011 }
4012
Pavol Vican7313fc02016-11-14 01:10:31 +01004013 if (yang_check_typedef(module, NULL, unres)) {
4014 goto error;
4015 }
4016
Pavol Vican7a7916f2016-11-21 23:38:30 +01004017 /* check features */
4018 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004019 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4020 goto error;
4021 }
4022 /* check for circular dependencies */
4023 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4024 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004025 }
4026 }
Pavol Vican36e27272016-11-22 15:47:28 +01004027 erase_identities = 0;
4028 if (yang_check_identities(module, unres)) {
4029 goto error;
4030 }
Pavol Vican05810b62016-11-23 14:07:22 +01004031 erase_nodes = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004032 if (yang_check_nodes(module, NULL, node, CONFIG_INHERIT_ENABLE, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004033 goto error;
4034 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004035
PavolVican75af21d2016-12-29 20:04:07 +01004036 /* check deviation */
4037 for (i = 0; i < dev_size; ++i) {
4038 module->deviation_size++;
4039 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4040 goto error;
4041 }
4042 }
4043
Pavol Vican3ad50f82016-12-04 15:00:36 +01004044 /* check augments */
4045 for (i = 0; i < aug_size; ++i) {
4046 module->augment_size++;
4047 if (yang_check_augment(module, &module->augment[i], CONFIG_INHERIT_ENABLE, unres)) {
4048 goto error;
4049 }
4050 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4051 goto error;
4052 }
4053 }
4054
Pavol Vican7313fc02016-11-14 01:10:31 +01004055 return EXIT_SUCCESS;
4056error:
Pavol Vican36e27272016-11-22 15:47:28 +01004057 if (erase_identities) {
4058 yang_free_ident_base(module->ident, 0, module->ident_size);
4059 }
Pavol Vican05810b62016-11-23 14:07:22 +01004060 if (erase_nodes) {
4061 yang_free_nodes(module->ctx, node);
4062 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004063 for (i = module->augment_size; i < aug_size; ++i) {
4064 yang_free_augment(module->ctx, &module->augment[i]);
4065 }
PavolVican75af21d2016-12-29 20:04:07 +01004066 for (i = module->deviation_size; i < dev_size; ++i) {
4067 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4068 free(module->deviation[i].deviate);
4069 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004070 return EXIT_FAILURE;
4071}