blob: 18b1dea8ebc733068c12d4c5e8b9e5acc867a613 [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;
Pavol Vican73e7c992016-02-24 12:18:05 +01001165 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001166 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +01001167 goto error;
1168 }
1169
1170 if (*length) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001171 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001172 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001173 }
1174 *length = calloc(1, sizeof **length);
1175 if (!*length) {
1176 LOGMEM;
1177 goto error;
1178 }
1179 (*length)->expr = lydict_insert_zc(module->ctx, value);
1180 return *length;
1181
1182error:
1183 free(value);
1184 return NULL;
1185
1186}
Pavol Vican1c203db2016-02-24 14:05:23 +01001187
Pavol Vican6eecf302016-08-10 11:09:05 +02001188int
1189yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001190{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001191 char *buf;
1192 size_t len;
1193
Michal Vasko0aee5c12016-06-17 14:27:26 +02001194 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001195 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001196 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001197 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001198
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001199 len = strlen(value);
1200 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Pavol Vican6eecf302016-08-10 11:09:05 +02001201
1202 if (!buf) {
1203 LOGMEM;
1204 free(value);
1205 return EXIT_FAILURE;
1206 }
1207
1208 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001209 strcpy(&buf[1], value);
1210 free(value);
1211
Pavol Vican6eecf302016-08-10 11:09:05 +02001212 pattern->expr = lydict_insert_zc(module->ctx, buf);
1213 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001214}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001215
1216void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001217yang_read_range(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001218{
Pavol Vican6b072512016-04-04 10:50:21 +02001219 if (typ->base != 0 && typ->base != LY_TYPE_DEC64) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001220 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001221 goto error;
1222 }
Pavol Vican6b072512016-04-04 10:50:21 +02001223 typ->base = LY_TYPE_DEC64;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001224 if (typ->type->info.dec64.range) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001225 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001226 goto error;
1227 }
1228 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1229 if (!typ->type->info.dec64.range) {
1230 LOGMEM;
1231 goto error;
1232 }
1233 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1234 return typ->type->info.dec64.range;
1235
1236error:
1237 free(value);
1238 return NULL;
1239}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001240
1241int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001242yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001243{
Pavol Vican6b072512016-04-04 10:50:21 +02001244 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1245 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001246 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001247 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001248 goto error;
1249 }
1250 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001251 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001252 goto error;
1253 }
1254 /* range check */
1255 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001256 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001257 goto error;
1258 }
1259 typ->type->info.dec64.dig = value;
1260 return EXIT_SUCCESS;
1261
1262error:
1263 return EXIT_FAILURE;
1264}
Pavol Vican79a763d2016-02-25 15:41:27 +01001265
Pavol Vican874715f2016-10-25 14:52:08 +02001266int
1267yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001268{
Pavol Vican874715f2016-10-25 14:52:08 +02001269 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001270
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001271 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001272 if (!value[0]) {
1273 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1274 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1275 free(value);
1276 goto error;
1277 }
1278
Pavol Vican79a763d2016-02-25 15:41:27 +01001279 enm->name = lydict_insert_zc(module->ctx, value);
1280
1281 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1282 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001283 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001284 goto error;
1285 }
1286
Pavol Vican874715f2016-10-25 14:52:08 +02001287 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001288 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001289 for (i = 0; i < j; i++) {
1290 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[j].name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001291 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001292 goto error;
1293 }
1294 }
1295
Pavol Vican874715f2016-10-25 14:52:08 +02001296 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001297
1298error:
Pavol Vican874715f2016-10-25 14:52:08 +02001299 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001300}
1301
1302int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001303yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001304{
1305 int i, j;
1306
1307 if (!assign) {
1308 /* assign value automatically */
1309 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001310 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001311 goto error;
1312 }
1313 enm->value = *value;
1314 enm->flags |= LYS_AUTOASSIGNED;
1315 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001316 } else if (typ->type->info.enums.enm == enm) {
1317 /* change value, which is assigned automatically, if first enum has value. */
1318 *value = typ->type->info.enums.enm[0].value;
1319 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001320 }
1321
1322 /* check that the value is unique */
1323 j = typ->type->info.enums.count-1;
1324 for (i = 0; i < j; i++) {
1325 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001326 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001327 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1328 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001329 goto error;
1330 }
1331 }
1332
1333 return EXIT_SUCCESS;
1334
1335error:
1336 return EXIT_FAILURE;
1337}
Pavol Vican9887c682016-02-29 11:32:01 +01001338
Pavol Vican59e8dee2016-10-25 15:29:38 +02001339int
1340yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001341{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001342 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001343
PavolVicane87cb932016-12-30 15:36:18 +01001344 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001345 bit->name = lydict_insert_zc(module->ctx, value);
1346 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001347 free(value);
1348 goto error;
1349 }
Pavol Vican9887c682016-02-29 11:32:01 +01001350
Pavol Vican59e8dee2016-10-25 15:29:38 +02001351 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001352 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001353 for (i = 0; i < j; i++) {
Pavol Vican9887c682016-02-29 11:32:01 +01001354 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001355 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001356 goto error;
1357 }
1358 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001359 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001360
1361error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001362 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001363}
1364
1365int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001366yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001367{
1368 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001369
1370 if (!assign) {
1371 /* assign value automatically */
1372 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001373 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001374 goto error;
1375 }
1376 bit->pos = (uint32_t)*value;
1377 bit->flags |= LYS_AUTOASSIGNED;
1378 (*value)++;
1379 }
1380
1381 j = typ->type->info.bits.count - 1;
1382 /* check that the value is unique */
1383 for (i = 0; i < j; i++) {
1384 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001385 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 +01001386 goto error;
1387 }
1388 }
1389
Pavol Vican9887c682016-02-29 11:32:01 +01001390 return EXIT_SUCCESS;
1391
1392error:
1393 return EXIT_FAILURE;
1394}
Pavol Vican0df02b02016-03-01 10:28:50 +01001395
Pavol Vican3ad50f82016-12-04 15:00:36 +01001396int
1397yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001398{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001399 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001400 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001401 free(value);
1402 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001403 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001404 }
1405 aug->parent = parent;
1406 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001407 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001408}
Pavol Vican220e5a12016-03-03 14:19:43 +01001409
Pavol Vican4c90c642016-03-03 15:06:47 +01001410int
PavolVican75af21d2016-12-29 20:04:07 +01001411yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001412{
PavolVican75af21d2016-12-29 20:04:07 +01001413 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001414 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
Pavol Vican4c90c642016-03-03 15:06:47 +01001415 return EXIT_FAILURE;
Pavol Vican220e5a12016-03-03 14:19:43 +01001416 }
PavolVican75af21d2016-12-29 20:04:07 +01001417 dev->deviate = calloc(1, sizeof *dev->deviate);
1418 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1419 dev->deviate_size = 1;
Pavol Vican4c90c642016-03-03 15:06:47 +01001420 return EXIT_SUCCESS;
Pavol Vican220e5a12016-03-03 14:19:43 +01001421}
1422
1423void *
PavolVican75af21d2016-12-29 20:04:07 +01001424yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001425{
PavolVican75af21d2016-12-29 20:04:07 +01001426 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001427
PavolVican75af21d2016-12-29 20:04:07 +01001428 if (dev->deviate && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001429 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1430 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001431 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001432 }
PavolVican75af21d2016-12-29 20:04:07 +01001433 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1434 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
1435 if (!deviate) {
1436 LOGMEM;
1437 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001438 }
PavolVican75af21d2016-12-29 20:04:07 +01001439 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1440 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001441 }
PavolVican75af21d2016-12-29 20:04:07 +01001442 dev->deviate[dev->deviate_size].mod = mod;
1443 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001444}
1445
1446int
PavolVican75af21d2016-12-29 20:04:07 +01001447yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001448{
1449 const char **stritem;
1450
Pavol Vican85f12022016-03-05 16:30:35 +01001451 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001452 if (dev_target->nodetype == LYS_LEAFLIST) {
1453 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1454 } else if (dev_target->nodetype == LYS_LEAF) {
1455 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001456 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001457 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1458 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001459 goto error;
1460 }
1461
PavolVican75af21d2016-12-29 20:04:07 +01001462 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001463 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001464 if (!ly_strequal(*stritem, deviate->units, 1)) {
1465 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001466 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001467 goto error;
1468 }
1469 /* remove current units value of the target */
1470 lydict_remove(ctx, *stritem);
Pavol Vican4766aca2016-03-07 12:42:36 +01001471 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001472 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001473 /* check that there is no current value */
1474 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001475 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1476 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001477 goto error;
1478 }
1479 } else { /* replace */
1480 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001481 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1482 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001483 goto error;
1484 }
1485 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001486 /* remove current units value of the target ... */
1487 lydict_remove(ctx, *stritem);
1488
1489 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001490 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001491 }
1492
Pavol Vican85f12022016-03-05 16:30:35 +01001493 return EXIT_SUCCESS;
1494
1495error:
1496 return EXIT_FAILURE;
1497}
1498
1499int
PavolVican75af21d2016-12-29 20:04:07 +01001500yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001501{
Pavol Vican85f12022016-03-05 16:30:35 +01001502 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001503 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001504
1505 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001506 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001507 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1508 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001509 goto error;
1510 }
1511
PavolVican75af21d2016-12-29 20:04:07 +01001512 list = (struct lys_node_list *)dev_target;
1513 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001514 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001515 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
1516 if (!unique) {
Pavol Vican85f12022016-03-05 16:30:35 +01001517 LOGMEM;
1518 goto error;
1519 }
PavolVican75af21d2016-12-29 20:04:07 +01001520 list->unique = unique;
1521 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001522 }
1523
1524 return EXIT_SUCCESS;
1525
1526error:
1527 return EXIT_FAILURE;
1528}
1529
1530int
PavolVican75af21d2016-12-29 20:04:07 +01001531yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1532 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001533{
1534 struct lys_node *node;
1535 struct lys_node_choice *choice;
1536 struct lys_node_leaf *leaf;
1537 struct lys_node_leaflist *llist;
1538 int rc, i;
1539 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001540
Pavol Vican38321d02016-08-16 14:56:02 +02001541 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001542 if (dev_target->nodetype == LYS_CHOICE) {
1543 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001544 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1545 if (rc || !node) {
1546 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1547 goto error;
1548 }
PavolVican75af21d2016-12-29 20:04:07 +01001549 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001550 if (!choice->dflt || (choice->dflt != node)) {
1551 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1552 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1553 goto error;
1554 }
1555 } else { /* add or replace */
1556 choice->dflt = node;
1557 if (!choice->dflt) {
1558 /* default branch not found */
1559 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1560 goto error;
1561 }
1562 }
PavolVican75af21d2016-12-29 20:04:07 +01001563 } else if (dev_target->nodetype == LYS_LEAF) {
1564 leaf = (struct lys_node_leaf *)dev_target;
1565 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001566 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1567 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1568 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1569 goto error;
1570 }
1571 /* remove value */
1572 lydict_remove(ctx, leaf->dflt);
1573 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001574 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001575 } else { /* add (already checked) and replace */
1576 /* remove value */
1577 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001578 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001579
1580 /* set new value */
1581 leaf->dflt = lydict_insert(ctx, value, u);
1582
1583 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001584 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001585 }
1586 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001587 llist = (struct lys_node_leaflist *)dev_target;
1588 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001589 /* find and remove the value in target list */
1590 for (i = 0; i < llist->dflt_size; i++) {
1591 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1592 /* match, remove the value */
1593 lydict_remove(llist->module->ctx, llist->dflt[i]);
1594 llist->dflt[i] = NULL;
1595 break;
1596 }
1597 }
1598 if (i == llist->dflt_size) {
1599 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1600 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1601 goto error;
1602 }
1603 } else {
1604 /* add or replace, anyway we place items into the deviate's list
1605 which propagates to the target */
1606 /* we just want to check that the value isn't already in the list */
1607 for (i = 0; i < llist->dflt_size; i++) {
1608 if (ly_strequal(llist->dflt[i], value, 1)) {
1609 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1610 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1611 goto error;
1612 }
1613 }
1614 /* store it in target node */
1615 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1616
1617 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001618 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001619 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001620 }
1621 }
1622
1623 return EXIT_SUCCESS;
1624error:
1625 return EXIT_FAILURE;
1626}
1627
Pavol Vican38321d02016-08-16 14:56:02 +02001628int
PavolVican75af21d2016-12-29 20:04:07 +01001629yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1630 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001631{
PavolVican75af21d2016-12-29 20:04:07 +01001632 int i;
1633 struct lys_node_leaflist *llist;
1634 const char **dflt;
1635
1636 /* check target node type */
1637 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1638 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1639 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1640 goto error;
1641 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1642 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1643 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1644 goto error;
1645 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1646 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1647 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001648 goto error;
1649 }
1650
PavolVican75af21d2016-12-29 20:04:07 +01001651 if (deviate->mod == LY_DEVIATE_ADD) {
1652 /* check that there is no current value */
1653 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1654 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1655 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1656 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1657 goto error;
1658 }
Pavol Vican85f12022016-03-05 16:30:35 +01001659
PavolVican75af21d2016-12-29 20:04:07 +01001660 /* check collision with mandatory/min-elements */
1661 if ((dev_target->flags & LYS_MAND_TRUE) ||
1662 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1663 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1664 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1665 "Adding the \"default\" statement is forbidden on %s statement.",
1666 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1667 goto error;
1668 }
1669 } else if (deviate->mod == LY_DEVIATE_RPL) {
1670 /* check that there was a value before */
1671 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1672 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1673 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1674 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1675 goto error;
1676 }
1677 }
Pavol Vican85f12022016-03-05 16:30:35 +01001678
PavolVican75af21d2016-12-29 20:04:07 +01001679 if (dev_target->nodetype == LYS_LEAFLIST) {
1680 /* reallocate default list in the target */
1681 llist = (struct lys_node_leaflist *)dev_target;
1682 if (deviate->mod == LY_DEVIATE_ADD) {
1683 /* reallocate (enlarge) the unique array of the target */
1684 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
1685 if (!dflt) {
1686 LOGMEM;
1687 goto error;
1688 }
1689 llist->dflt = dflt;
1690 } else if (deviate->mod == LY_DEVIATE_RPL) {
1691 /* reallocate (replace) the unique array of the target */
1692 for (i = 0; i < llist->dflt_size; i++) {
1693 lydict_remove(llist->module->ctx, llist->dflt[i]);
1694 }
1695 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
1696 if (!dflt) {
1697 LOGMEM;
1698 goto error;
1699 }
1700 llist->dflt = dflt;
1701 llist->dflt_size = 0;
1702 }
1703 }
1704
1705 for (i = 0; i < deviate->dflt_size; ++i) {
1706 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1707 goto error;
1708 }
1709 }
Pavol Vican85f12022016-03-05 16:30:35 +01001710
1711 return EXIT_SUCCESS;
1712
1713error:
1714 return EXIT_FAILURE;
1715}
1716
1717int
PavolVican75af21d2016-12-29 20:04:07 +01001718yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001719{
Radek Krejcie00d2312016-08-12 15:27:49 +02001720 struct lys_node *parent;
1721
Pavol Vican85f12022016-03-05 16:30:35 +01001722 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001723 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001724 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1725 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001726 goto error;
1727 }
1728
PavolVican75af21d2016-12-29 20:04:07 +01001729 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001730 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001731 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001732 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1733 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001734 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001735 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001736 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001737 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1738 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1739 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1740 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001741 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001742 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1743 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1744 goto error;
1745 }
Pavol Vican85f12022016-03-05 16:30:35 +01001746 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001747 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001748 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001749 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1750 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001751 goto error;
1752 }
Pavol Vican85f12022016-03-05 16:30:35 +01001753 }
1754
Pavol Vican85f12022016-03-05 16:30:35 +01001755 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001756 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001757
1758 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001759 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001760
Radek Krejcie00d2312016-08-12 15:27:49 +02001761 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001762 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001763 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1764 parent = parent->parent) {
1765 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1766 /* stop also on presence containers */
1767 break;
1768 }
1769 }
1770 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1771 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1772 if (lyp_check_mandatory_choice(parent)) {
1773 goto error;
1774 }
1775 }
1776
Pavol Vican85f12022016-03-05 16:30:35 +01001777 return EXIT_SUCCESS;
1778
1779error:
1780 return EXIT_FAILURE;
1781}
1782
1783int
PavolVican75af21d2016-12-29 20:04:07 +01001784yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001785{
Pavol Vican09adcc32016-08-25 10:51:36 +02001786 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001787
1788 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001789 if (dev_target->nodetype == LYS_LEAFLIST) {
1790 max = &((struct lys_node_leaflist *)dev_target)->max;
1791 min = &((struct lys_node_leaflist *)dev_target)->min;
1792 } else if (dev_target->nodetype == LYS_LIST) {
1793 max = &((struct lys_node_list *)dev_target)->max;
1794 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001795 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001796 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1797 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 +01001798 goto error;
1799 }
1800
PavolVican75af21d2016-12-29 20:04:07 +01001801 ui32val = (type) ? max : min;
1802 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001803 /* check that there is no current value */
1804 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001805 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1806 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001807 goto error;
1808 }
PavolVican75af21d2016-12-29 20:04:07 +01001809 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001810 /* unfortunately, there is no way to check reliably that there
1811 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001812 }
1813
1814 /* add (already checked) and replace */
1815 /* set new value specified in deviation */
1816 *ui32val = value;
1817
Pavol Vican09adcc32016-08-25 10:51:36 +02001818 /* check min-elements is smaller than max-elements */
1819 if (*max && *min > *max) {
1820 if (type) {
1821 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1822 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1823 } else {
1824 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1825 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1826 }
1827 goto error;
1828 }
1829
Pavol Vican85f12022016-03-05 16:30:35 +01001830 return EXIT_SUCCESS;
1831
1832error:
1833 return EXIT_FAILURE;
1834}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001835
1836int
PavolVican75af21d2016-12-29 20:04:07 +01001837yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1838 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001839{
PavolVican75af21d2016-12-29 20:04:07 +01001840 int i, j, erase_must = 1;
1841 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001842 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001843
PavolVican75af21d2016-12-29 20:04:07 +01001844 /* check target node type */
1845 switch (dev_target->nodetype) {
1846 case LYS_LEAF:
1847 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1848 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001849 break;
PavolVican75af21d2016-12-29 20:04:07 +01001850 case LYS_CONTAINER:
1851 trg_must = &((struct lys_node_container *)dev_target)->must;
1852 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1853 break;
1854 case LYS_LEAFLIST:
1855 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1856 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1857 break;
1858 case LYS_LIST:
1859 trg_must = &((struct lys_node_list *)dev_target)->must;
1860 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1861 break;
1862 case LYS_ANYXML:
1863 case LYS_ANYDATA:
1864 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1865 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1866 break;
1867 default:
1868 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1869 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1870 goto error;
1871 }
1872
1873 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001874 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001875
1876 if (deviate->mod == LY_DEVIATE_ADD) {
1877 /* reallocate the must array of the target */
1878 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
1879 if (!must) {
1880 LOGMEM;
1881 goto error;
1882 }
1883 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001884 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001885 free(deviate->must);
1886 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001887 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001888 erase_must = 0;
1889 } else if (deviate->mod == LY_DEVIATE_DEL) {
1890 /* find must to delete, we are ok with just matching conditions */
1891 for (j = 0; j < deviate->must_size; ++j) {
1892 for (i = 0; i < *trg_must_size; i++) {
1893 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1894 /* we have a match, free the must structure ... */
1895 lys_restr_free(module->ctx, &((*trg_must)[i]));
1896 /* ... and maintain the array */
1897 (*trg_must_size)--;
1898 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001899 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001900 }
1901 if (!(*trg_must_size)) {
1902 free(*trg_must);
1903 *trg_must = NULL;
1904 } else {
PavolVican214408f2017-02-03 11:54:05 +01001905 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001906 }
1907
1908 i = -1; /* set match flag */
1909 break;
1910 }
1911 }
1912 if (i != -1) {
1913 /* no match found */
1914 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1915 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1916 goto error;
1917 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001918 }
1919 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001920
PavolVican75af21d2016-12-29 20:04:07 +01001921 /* check XPath dependencies */
1922 if (*trg_must_size && unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001923 goto error;
1924 }
1925
PavolVican75af21d2016-12-29 20:04:07 +01001926 return EXIT_SUCCESS;
1927error:
1928 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1929 for (i = 0; i < deviate->must_size; ++i) {
1930 lys_restr_free(module->ctx, &deviate->must[i]);
1931 }
1932 free(deviate->must);
1933 }
1934 return EXIT_FAILURE;
1935}
1936
1937int
1938yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1939 struct lys_node_list *list, int index, char * value)
1940{
1941 int i, j;
1942
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001943 /* find unique structures to delete */
1944 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001945 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001946 continue;
1947 }
1948
PavolVican75af21d2016-12-29 20:04:07 +01001949 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1950 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001951 break;
1952 }
1953 }
1954
PavolVican75af21d2016-12-29 20:04:07 +01001955 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001956 /* we have a match, free the unique structure ... */
1957 for (j = 0; j < list->unique[i].expr_size; j++) {
1958 lydict_remove(module->ctx, list->unique[i].expr[j]);
1959 }
1960 free(list->unique[i].expr);
1961 /* ... and maintain the array */
1962 list->unique_size--;
1963 if (i != list->unique_size) {
1964 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1965 list->unique[i].expr = list->unique[list->unique_size].expr;
1966 }
1967
1968 if (!list->unique_size) {
1969 free(list->unique);
1970 list->unique = NULL;
1971 } else {
1972 list->unique[list->unique_size].expr_size = 0;
1973 list->unique[list->unique_size].expr = NULL;
1974 }
1975
1976 i = -1; /* set match flag */
1977 break;
1978 }
1979 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001980
1981 if (i != -1) {
1982 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001983 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1984 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001985 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001986 }
1987
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001988 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001989}
Pavol Vican021488a2016-01-25 23:56:12 +01001990
PavolVican75af21d2016-12-29 20:04:07 +01001991int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01001992{
PavolVican75af21d2016-12-29 20:04:07 +01001993 struct lys_node_list *list;
1994 char *str;
1995 uint i;
1996 struct lys_unique *last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01001997
PavolVican75af21d2016-12-29 20:04:07 +01001998 if (yang_read_deviate_unique(deviate, dev_target)) {
1999 goto error;
2000 }
2001 list = (struct lys_node_list *)dev_target;
2002 last_unique = &list->unique[list->unique_size];
2003 for (i = 0; i < deviate->unique_size; ++i) {
2004 str = (char *) deviate->unique[i].expr;
2005 if (deviate->mod == LY_DEVIATE_ADD) {
2006 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2007 free(str);
2008 goto error;
2009 }
2010 list->unique_size++;
2011 } else if (deviate->mod == LY_DEVIATE_DEL) {
2012 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2013 free(str);
2014 goto error;
2015 }
2016 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2017 free(str);
2018 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002019 }
2020 }
PavolVican75af21d2016-12-29 20:04:07 +01002021 free(str);
2022 }
2023 if (deviate->mod == LY_DEVIATE_ADD) {
2024 free(deviate->unique);
2025 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002026 }
Pavol Vican38321d02016-08-16 14:56:02 +02002027
Pavol Vican38321d02016-08-16 14:56:02 +02002028
PavolVican75af21d2016-12-29 20:04:07 +01002029 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002030error:
PavolVican75af21d2016-12-29 20:04:07 +01002031 if (deviate->mod == LY_DEVIATE_ADD) {
2032 for (i = i + 1; i < deviate->unique_size; ++i) {
2033 free(deviate->unique[i].expr);
2034 }
2035 free(deviate->unique);
2036 deviate->unique = last_unique;
2037
2038 }
Pavol Vican021488a2016-01-25 23:56:12 +01002039 return EXIT_FAILURE;
2040}
2041
Pavol Vicanec423c92016-10-24 21:33:43 +02002042static int
2043yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2044 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002045{
Pavol Vican55870412016-03-10 12:36:21 +01002046 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002047 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002048 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002049
Pavol Vicanec423c92016-10-24 21:33:43 +02002050 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002051 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002052 if (!rc) {
2053 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002054 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002055 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2056 &trg->inc[trg->inc_size], unres)) {
2057 ret = -1;
2058 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002059 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002060 } else if (rc == -1) {
PavolVican7d0b5ab2017-02-01 13:06:53 +01002061 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002062 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002063 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002064
Pavol Vicanec423c92016-10-24 21:33:43 +02002065 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002066 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002067}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002068
PavolVicanc1807262017-01-31 18:00:27 +01002069struct lys_ext_instance *
2070yang_ext_instance(void *node, enum yytokentype type)
2071{
2072 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2073 LYEXT_PAR parent_type;
2074 uint8_t *size;
2075
2076 switch (type) {
2077 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002078 case SUBMODULE_KEYWORD:
2079 case BELONGS_TO_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002080 ext = &((struct lys_module *)node)->ext;
2081 size = &((struct lys_module *)node)->ext_size;
2082 parent_type = LYEXT_PAR_MODULE;
2083 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002084 case IMPORT_KEYWORD:
2085 ext = &((struct lys_import *)node)->ext;
2086 size = &((struct lys_import *)node)->ext_size;
2087 parent_type = LYEXT_PAR_IMPORT;
2088 break;
2089 case INCLUDE_KEYWORD:
2090 ext = &((struct lys_include *)node)->ext;
2091 size = &((struct lys_include *)node)->ext_size;
2092 parent_type = LYEXT_PAR_INCLUDE;
2093 break;
PavolVican171717d2017-02-01 14:49:55 +01002094 case REVISION_KEYWORD:
2095 ext = &((struct lys_revision *)node)->ext;
2096 size = &((struct lys_revision *)node)->ext_size;
2097 parent_type = LYEXT_PAR_REVISION;
2098 break;
PavolVican70ce7452017-02-01 15:39:39 +01002099 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002100 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002101 case LEAF_KEYWORD:
2102 case LEAF_LIST_KEYWORD:
2103 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002104 case CHOICE_KEYWORD:
2105 case CASE_KEYWORD:
2106 case ANYXML_KEYWORD:
2107 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002108 case USES_KEYWORD:
2109 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002110 case ACTION_KEYWORD:
2111 case RPC_KEYWORD:
2112 case INPUT_KEYWORD:
2113 case OUTPUT_KEYWORD:
2114 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002115 ext = &((struct lys_node *)node)->ext;
2116 size = &((struct lys_node *)node)->ext_size;
2117 parent_type = LYEXT_PAR_NODE;
2118 break;
PavolVican19dc6152017-02-06 12:04:15 +01002119 case ARGUMENT_KEYWORD:
2120 case EXTENSION_KEYWORD:
2121 ext = &((struct lys_ext *)node)->ext;
2122 size = &((struct lys_ext *)node)->ext_size;
2123 parent_type = LYEXT_PAR_EXT;
2124 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002125 case FEATURE_KEYWORD:
2126 ext = &((struct lys_feature *)node)->ext;
2127 size = &((struct lys_feature *)node)->ext_size;
2128 parent_type = LYEXT_PAR_FEATURE;
2129 break;
PavolVican8fa31242017-02-07 11:04:26 +01002130 case IDENTITY_KEYWORD:
2131 ext = &((struct lys_ident *)node)->ext;
2132 size = &((struct lys_ident *)node)->ext_size;
2133 parent_type = LYEXT_PAR_IDENT;
2134 break;
2135 case IF_FEATURE_KEYWORD:
2136 ext = &((struct lys_iffeature *)node)->ext;
2137 size = &((struct lys_iffeature *)node)->ext_size;
2138 parent_type = LYEXT_PAR_IFFEATURE;
2139 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002140 case TYPEDEF_KEYWORD:
2141 ext = &((struct lys_tpdf *)node)->ext;
2142 size = &((struct lys_tpdf *)node)->ext_size;
2143 parent_type = LYEXT_PAR_TPDF;
2144 break;
PavolVican056fcd12017-02-07 15:36:53 +01002145 case TYPE_KEYWORD:
2146 ext = &((struct yang_type *)node)->type->ext;
2147 size = &((struct yang_type *)node)->type->ext_size;
2148 parent_type = LYEXT_PAR_TYPE;
2149 break;
2150 case LENGTH_KEYWORD:
2151 case PATTERN_KEYWORD:
2152 case RANGE_KEYWORD:
2153 ext = &((struct lys_restr *)node)->ext;
2154 size = &((struct lys_restr *)node)->ext_size;
2155 parent_type = LYEXT_PAR_RESTR;
2156 break;
2157 case ENUM_KEYWORD:
2158 ext = &((struct lys_type_enum *)node)->ext;
2159 size = &((struct lys_type_enum *)node)->ext_size;
2160 parent_type = LYEXT_PAR_TYPE_ENUM;
2161 break;
2162 case BIT_KEYWORD:
2163 ext = &((struct lys_type_bit *)node)->ext;
2164 size = &((struct lys_type_bit *)node)->ext_size;
2165 parent_type = LYEXT_PAR_TYPE_BIT;
2166 break;
PavolVicanc1807262017-01-31 18:00:27 +01002167 default:
2168 LOGINT;
2169 return NULL;
2170 }
2171
2172 instance = calloc(1, sizeof *instance);
2173 if (!instance) {
2174 goto error;
2175 }
2176 instance->parent_type = parent_type;
2177 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2178 if (!tmp) {
2179 goto error;
2180 }
2181 tmp[*size] = instance;
2182 *ext = tmp;
2183 (*size)++;
2184 return instance;
2185
2186error:
2187 LOGMEM;
2188 free(instance);
2189 return NULL;
2190}
2191
2192void *
2193yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
2194 enum yytokentype actual_type, enum yytokentype backup_type)
2195{
2196 struct lys_ext_instance *instance;
2197
2198 if (backup_type != NODE) {
2199 instance = yang_ext_instance((actual) ? actual : module, backup_type);
PavolVicane6fa67b2017-02-01 11:06:57 +01002200 if (!instance) {
2201 return NULL;
2202 }
PavolVicanc1807262017-01-31 18:00:27 +01002203 switch (actual_type) {
2204 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002205 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002206 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002207 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002208 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002209 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002210 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002211 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002212 break;
2213 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002214 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002215 break;
2216 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002217 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002218 break;
PavolVican171717d2017-02-01 14:49:55 +01002219 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002220 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002221 break;
2222 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002223 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002224 break;
PavolVican19dc6152017-02-06 12:04:15 +01002225 case YIN_ELEMENT_KEYWORD:
2226 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
2227 break;
2228 case STATUS_KEYWORD:
2229 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
2230 break;
PavolVican8fa31242017-02-07 11:04:26 +01002231 case BASE_KEYWORD:
2232 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002233 if (backup_type == IDENTITY_KEYWORD) {
2234 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
2235 } else {
2236 /* base in type */
2237 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2238 }
PavolVican8fa31242017-02-07 11:04:26 +01002239 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002240 case DEFAULT_KEYWORD:
2241 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
2242 break;
2243 case UNITS_KEYWORD:
2244 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
2245 break;
PavolVican056fcd12017-02-07 15:36:53 +01002246 case REQUIRE_INSTANCE_KEYWORD:
2247 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
2248 break;
2249 case PATH_KEYWORD:
2250 instance->insubstmt = LYEXT_SUBSTMT_PATH;
2251 break;
2252 case ERROR_MESSAGE_KEYWORD:
2253 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
2254 break;
2255 case ERROR_APP_TAG_KEYWORD:
2256 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
2257 break;
2258 case MODIFIER_KEYWORD:
2259 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
2260 break;
2261 case FRACTION_DIGITS_KEYWORD:
2262 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
2263 break;
2264 case VALUE_KEYWORD:
2265 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
2266 break;
2267 case POSITION_KEYWORD:
2268 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
2269 break;
PavolVicanc1807262017-01-31 18:00:27 +01002270 default:
2271 LOGINT;
2272 return NULL;
2273 }
2274 } else {
PavolVicane6fa67b2017-02-01 11:06:57 +01002275 instance = yang_ext_instance((actual) ? actual : module, actual_type);
2276 if (!instance) {
2277 return NULL;
2278 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002279 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002280 switch (actual_type) {
2281 case ARGUMENT_KEYWORD:
2282 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
2283 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002284 case BELONGS_TO_KEYWORD:
2285 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
2286 break;
PavolVican19dc6152017-02-06 12:04:15 +01002287 default:
2288 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2289 break;
2290 }
PavolVicanc1807262017-01-31 18:00:27 +01002291 }
2292 instance->flags |= LYEXT_OPT_YANG;
2293 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2294 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
2295 return instance;
2296}
2297
Pavol Vicanf4717e62016-03-16 11:30:01 +01002298int
Pavol Vican0adf01d2016-03-22 12:29:33 +01002299yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value)
Pavol Vicanf4717e62016-03-16 11:30:01 +01002300{
2301 char *prefix;
2302 char *identif;
2303 const char *ns = NULL;
2304 int i;
2305
Pavol Vicanf4717e62016-03-16 11:30:01 +01002306 /* check to the same pointer */
2307 if (data_node != actual) {
2308 return EXIT_SUCCESS;
2309 }
2310
Pavol Vicana302aa62016-03-17 10:45:35 +01002311 prefix = strdup(value);
2312 if (!prefix) {
2313 LOGMEM;
2314 goto error;
2315 }
2316 /* find prefix anf identificator*/
2317 identif = strchr(prefix, ':');
Pavol Vicanfbd02782016-08-29 11:14:45 +02002318 if (!identif) {
2319 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, prefix);
2320 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The extension must have prefix.");
2321 goto error;
2322 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002323 *identif = '\0';
2324 identif++;
2325
Pavol Vicanf4717e62016-03-16 11:30:01 +01002326 for(i = 0; i < module->imp_size; ++i) {
2327 if (!strcmp(module->imp[i].prefix, prefix)) {
2328 ns = module->imp[i].module->ns;
2329 break;
2330 }
2331 }
Pavol Vican1ff1b7b2016-04-07 09:51:49 +02002332 if (!ns && !strcmp(module->prefix, prefix)) {
2333 ns = (module->type) ? ((struct lys_submodule *)module)->belongsto->ns : module->ns;
2334 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002335 free(prefix);
Pavol Vicanf4717e62016-03-16 11:30:01 +01002336 return EXIT_SUCCESS;
Pavol Vicana302aa62016-03-17 10:45:35 +01002337
2338error:
2339 free(prefix);
2340 return EXIT_FAILURE;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002341}
2342
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002343int
Pavol Vican1dac40c2016-09-28 11:39:26 +02002344store_flags(struct lys_node *node, uint8_t flags, int config_opt)
Pavol Vican4fb66c92016-03-17 10:32:27 +01002345{
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002346 struct lys_node *elem;
2347
Pavol Vican1dac40c2016-09-28 11:39:26 +02002348 node->flags |= (config_opt == CONFIG_IGNORE) ? flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET)): flags;
2349 if (config_opt == CONFIG_INHERIT_ENABLE) {
2350 if (!(node->flags & LYS_CONFIG_MASK)) {
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002351 /* get config flag from parent */
Radek Krejcif71f48f2016-10-25 16:37:24 +02002352 if (node->parent) {
2353 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002354 } else {
2355 /* default config is true */
2356 node->flags |= LYS_CONFIG_W;
2357 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002358 } else {
Pavol Vican1dac40c2016-09-28 11:39:26 +02002359 /* do we even care about config flags? */
2360 for (elem = node; elem && !(elem->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT | LYS_RPC)); elem = elem->parent);
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002361
Pavol Vican1dac40c2016-09-28 11:39:26 +02002362 if (!elem && (node->flags & LYS_CONFIG_W) && node->parent && (node->parent->flags & LYS_CONFIG_R)) {
2363 LOGVAL(LYE_INARG, LY_VLOG_LYS, node, "true", "config");
Michal Vasko51e5c582017-01-19 14:16:39 +01002364 LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "State nodes cannot have configuration nodes as children.");
Pavol Vican1dac40c2016-09-28 11:39:26 +02002365 return EXIT_FAILURE;
2366 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002367 }
2368 }
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002369
2370 return EXIT_SUCCESS;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002371}
Pavol Vican8e7110b2016-03-22 17:00:26 +01002372
Pavol Vicanec598812016-11-30 14:13:38 +01002373int
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002374store_config_flag(struct lys_node *node, int config_opt)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002375{
Pavol Vicanec598812016-11-30 14:13:38 +01002376 int ret = config_opt;
Pavol Vican1938d882016-04-10 13:36:31 +02002377
Pavol Vicanec598812016-11-30 14:13:38 +01002378 switch (node->nodetype) {
2379 case LYS_CONTAINER:
2380 case LYS_LEAF:
2381 case LYS_LEAFLIST:
2382 case LYS_LIST:
2383 case LYS_CHOICE:
2384 case LYS_ANYDATA:
2385 case LYS_ANYXML:
2386 if (config_opt == CONFIG_IGNORE) {
2387 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
2388 } else if (config_opt == CONFIG_INHERIT_ENABLE) {
2389 if (!(node->flags & LYS_CONFIG_MASK)) {
2390 /* get config flag from parent */
2391 if (node->parent) {
2392 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2393 } else {
2394 /* default config is true */
2395 node->flags |= LYS_CONFIG_W;
2396 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002397 }
2398 }
Pavol Vicanec598812016-11-30 14:13:38 +01002399 break;
2400 case LYS_CASE:
2401 if (config_opt == CONFIG_INHERIT_ENABLE) {
2402 if (!(node->flags & LYS_CONFIG_MASK)) {
2403 /* get config flag from parent */
2404 if (node->parent) {
2405 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2406 } else {
2407 /* default config is true */
2408 node->flags |= LYS_CONFIG_W;
2409 }
2410 }
2411 }
2412 break;
2413 case LYS_RPC:
2414 case LYS_ACTION:
2415 case LYS_NOTIF:
2416 ret = CONFIG_IGNORE;
2417 break;
2418 default:
2419 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002420 }
Pavol Vicanec598812016-11-30 14:13:38 +01002421
Pavol Vican1938d882016-04-10 13:36:31 +02002422 return ret;
2423}
2424
2425int
Pavol Vican9d50a772016-10-14 22:23:36 +02002426yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2427 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002428{
Pavol Vican974377b2016-03-23 00:38:53 +01002429 unsigned int size;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002430 YY_BUFFER_STATE bp;
2431 yyscan_t scanner = NULL;
Pavol Vican082afd02016-10-25 12:39:15 +02002432 int ret = EXIT_SUCCESS, remove_import = 1;
2433 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002434 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002435
Pavol Vican8e7110b2016-03-22 17:00:26 +01002436 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002437 yylex_init(&scanner);
2438 bp = yy_scan_buffer((char *)data, size, scanner);
2439 yy_switch_to_buffer(bp, scanner);
PavolVican196694c2017-01-27 10:33:09 +01002440 param.module = module;
2441 param.submodule = submodule;
2442 param.unres = unres;
2443 param.node = node;
2444 param.remove_import = &remove_import;
2445 if (yyparse(scanner, &param)) {
Pavol Vican082afd02016-10-25 12:39:15 +02002446 if (remove_import) {
2447 trg = (submodule) ? (struct lys_module *)submodule : module;
2448 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2449 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2450 trg->inc_size = 0;
2451 trg->imp_size = 0;
2452 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002453 ret = EXIT_FAILURE;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002454 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002455 yy_delete_buffer(bp, scanner);
2456 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002457 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002458}
2459
2460struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002461yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002462{
2463
Radek Krejci6ff885d2017-01-03 14:06:22 +01002464 struct lys_module *module = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002465 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002466 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002467
2468 unres = calloc(1, sizeof *unres);
2469 if (!unres) {
2470 LOGMEM;
2471 goto error;
2472 }
2473
2474 module = calloc(1, sizeof *module);
2475 if (!module) {
2476 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002477 goto error;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002478 }
2479
2480 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002481 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002482 module->type = 0;
2483 module->implemented = (implement ? 1 : 0);
2484
Pavol Vican9d50a772016-10-14 22:23:36 +02002485 if (yang_parse_mem(module, NULL, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002486 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002487 goto error;
2488 }
2489
2490 if (yang_check_sub_module(module, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002491 goto error;
2492 }
2493
2494 if (module && unres->count && resolve_unres_schema(module, unres)) {
2495 goto error;
2496 }
2497
2498 if (revision) {
2499 /* check revision of the parsed model */
2500 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2501 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2502 module->name, module->rev[0].date, revision);
2503 goto error;
2504 }
2505 }
2506
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002507 /* check correctness of includes */
2508 if (lyp_check_include_missing(module)) {
2509 goto error;
2510 }
2511
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002512 if (lyp_ctx_add_module(&module)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002513 goto error;
2514 }
2515
Radek Krejci27fe55e2016-09-13 17:13:35 +02002516 if (module->deviation_size && !module->implemented) {
2517 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2518 /* deviations always causes target to be made implemented,
2519 * but augents and leafrefs not, so we have to apply them now */
2520 if (lys_set_implemented(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002521 goto error;
2522 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002523 }
2524
Pavol Vican8e7110b2016-03-22 17:00:26 +01002525 unres_schema_free(NULL, &unres);
2526 LOGVRB("Module \"%s\" successfully parsed.", module->name);
2527 return module;
2528
2529error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002530 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002531 unres_schema_free(module, &unres);
2532 if (!module || !module->name) {
2533 free(module);
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002534 if (ly_vecode != LYVE_SUBMODULE) {
2535 LOGERR(ly_errno, "Module parsing failed.");
2536 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002537 return NULL;
2538 }
2539
2540 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002541
2542 lys_sub_module_remove_devs_augs(module);
2543 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002544 return NULL;
2545}
2546
2547struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002548yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002549{
2550 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002551 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002552
2553 submodule = calloc(1, sizeof *submodule);
2554 if (!submodule) {
2555 LOGMEM;
2556 goto error;
2557 }
2558
2559 submodule->ctx = module->ctx;
2560 submodule->type = 1;
2561 submodule->belongsto = module;
2562
Pavol Vican9d50a772016-10-14 22:23:36 +02002563 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002564 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002565 goto error;
2566 }
2567
2568 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002569 goto error;
2570 }
2571
Pavol Vican8e7110b2016-03-22 17:00:26 +01002572 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002573 return submodule;
2574
2575error:
2576 /* cleanup */
2577 unres_schema_free((struct lys_module *)submodule, &unres);
2578
2579 if (!submodule || !submodule->name) {
2580 free(submodule);
2581 LOGERR(ly_errno, "Submodule parsing failed.");
2582 return NULL;
2583 }
2584
2585 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2586
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002587 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2588 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002589 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002590 return NULL;
2591}
Pavol Vican8760bb72016-04-07 09:44:01 +02002592
2593static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002594read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2595{
2596 int k = 0, j;
2597
2598 while (in_index < size) {
2599 if (input[in_index] == ' ') {
2600 k++;
2601 } else if (input[in_index] == '\t') {
2602 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2603 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002604 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2605 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2606 k += 8;
2607 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002608 } else {
2609 break;
2610 }
2611 ++in_index;
2612 if (k >= indent) {
2613 for (j = k - indent; j > 0; --j) {
2614 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002615 if (j > 1) {
2616 ++(*out_index);
2617 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002618 }
2619 break;
2620 }
2621 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002622 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002623}
2624
2625char *
PavolVican1bc22062017-01-19 15:09:04 +01002626yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002627 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002628
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002629 while (i < size) {
2630 switch (input[i]) {
2631 case '\n':
2632 out_index -= space;
2633 output[out_index] = '\n';
2634 space = 0;
2635 i = read_indent(input, indent, size, i + 1, &out_index, output);
2636 break;
2637 case ' ':
2638 case '\t':
2639 output[out_index] = input[i];
2640 ++space;
2641 break;
2642 case '\\':
2643 if (input[i + 1] == 'n') {
2644 out_index -= space;
2645 output[out_index] = '\n';
2646 space = 0;
2647 i = read_indent(input, indent, size, i + 2, &out_index, output);
2648 } else if (input[i + 1] == 't') {
2649 output[out_index] = '\t';
2650 ++i;
2651 ++space;
2652 } else if (input[i + 1] == '\\') {
2653 output[out_index] = '\\';
2654 ++i;
2655 } else if ((i + 1) != size && input[i + 1] == '"') {
2656 output[out_index] = '"';
2657 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002658 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002659 /* backslash must not be followed by any other character */
2660 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2661 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002662 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002663 break;
2664 default:
2665 output[out_index] = input[i];
2666 space = 0;
2667 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002668 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002669 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002670 ++out_index;
2671 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002672 output[out_index] = '\0';
2673 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002674 output = realloc(output, out_index + 1);
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002675 if (!output) {
2676 LOGMEM;
Pavol Vican3f598892016-09-28 15:41:07 +02002677 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002678 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002679 }
Pavol Vican3f598892016-09-28 15:41:07 +02002680 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002681}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002682
2683/* free function */
2684
Pavol Vican7313fc02016-11-14 01:10:31 +01002685static void yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
2686{
2687 struct yang_type *stype = (struct yang_type *)type->der;
2688 int i;
2689
2690 if (!stype) {
2691 return ;
2692 }
PavolVicane87cb932016-12-30 15:36:18 +01002693 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2694 lydict_remove(ctx, stype->name);
2695 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2696 for (i = 0; i < type->info.ident.count; ++i) {
2697 free(type->info.ident.ref[i]);
2698 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002699 }
PavolVicane87cb932016-12-30 15:36:18 +01002700 if (stype->base == LY_TYPE_UNION) {
2701 for (i = 0; i < type->info.uni.count; ++i) {
2702 yang_type_free(ctx, &type->info.uni.types[i]);
2703 }
2704 free(type->info.uni.types);
2705 type->base = LY_TYPE_DER;
2706 } else {
2707 type->base = stype->base;
2708 }
2709 free(stype);
2710 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002711 }
2712 lys_type_free(ctx, type);
Pavol Vican36aff862016-11-26 17:07:05 +01002713 type->base = LY_TYPE_DER;
Pavol Vican7313fc02016-11-14 01:10:31 +01002714}
2715
2716static void
2717yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint8_t start, uint8_t size)
2718{
2719 uint8_t i;
2720
2721 assert(ctx);
2722 if (!tpdf) {
2723 return;
2724 }
2725
2726 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002727 lydict_remove(ctx, tpdf[i].name);
2728 lydict_remove(ctx, tpdf[i].dsc);
2729 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002730
Pavol Vicancee10802016-11-22 15:48:35 +01002731 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002732
Pavol Vicancee10802016-11-22 15:48:35 +01002733 lydict_remove(ctx, tpdf[i].units);
2734 lydict_remove(ctx, tpdf[i].dflt);
Pavol Vican7313fc02016-11-14 01:10:31 +01002735 }
2736}
2737
Pavol Vican1cc4e192016-10-24 16:38:31 +02002738static void
2739yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2740{
2741 uint8_t i;
2742
2743 for (i = start; i < size; ++i){
2744 free((char *)imp[i].module);
2745 lydict_remove(ctx, imp[i].prefix);
2746 lydict_remove(ctx, imp[i].dsc);
2747 lydict_remove(ctx, imp[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002748 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002749 }
2750}
2751
Pavol Vicanec423c92016-10-24 21:33:43 +02002752static void
2753yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2754{
2755 uint8_t i;
2756
2757 for (i = start; i < size; ++i){
2758 free((char *)inc[i].submodule);
2759 lydict_remove(ctx, inc[i].dsc);
2760 lydict_remove(ctx, inc[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002761 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02002762 }
2763}
2764
Pavol Vican36e27272016-11-22 15:47:28 +01002765static void
2766yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2767{
2768 uint32_t i;
2769 uint8_t j;
2770
2771 /* free base name */
2772 for (i = start; i < size; ++i) {
2773 for (j = 0; j < ident[i].base_size; ++j) {
2774 free(ident[i].base[j]);
2775 }
2776 }
2777}
2778
Pavol Vican05810b62016-11-23 14:07:22 +01002779static void
2780yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2781{
2782 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2783 free(grp->tpdf);
2784}
2785
2786static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002787yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2788{
2789 uint8_t i;
2790
2791 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2792 free(cont->tpdf);
2793 lydict_remove(ctx, cont->presence);
2794
Pavol Vicanfda8c802016-12-03 02:00:42 +01002795 for (i = 0; i < cont->must_size; ++i) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002796 lys_restr_free(ctx, &cont->must[i]);
2797 }
2798 free(cont->must);
2799
2800 lys_when_free(ctx, cont->when);
2801}
2802
2803static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002804yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2805{
2806 uint8_t i;
2807
2808 for (i = 0; i < leaf->must_size; i++) {
2809 lys_restr_free(ctx, &leaf->must[i]);
2810 }
2811 free(leaf->must);
2812
2813 lys_when_free(ctx, leaf->when);
2814
2815 yang_type_free(ctx, &leaf->type);
2816 lydict_remove(ctx, leaf->units);
2817 lydict_remove(ctx, leaf->dflt);
2818}
2819
2820static void
Pavol Vican36aff862016-11-26 17:07:05 +01002821yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2822{
2823 uint8_t i;
2824
2825 for (i = 0; i < leaflist->must_size; i++) {
2826 lys_restr_free(ctx, &leaflist->must[i]);
2827 }
2828 free(leaflist->must);
2829
2830 for (i = 0; i < leaflist->dflt_size; i++) {
2831 lydict_remove(ctx, leaflist->dflt[i]);
2832 }
2833 free(leaflist->dflt);
2834
2835 lys_when_free(ctx, leaflist->when);
2836
2837 yang_type_free(ctx, &leaflist->type);
2838 lydict_remove(ctx, leaflist->units);
2839}
2840
2841static void
Pavol Vicand8136a42016-11-27 13:28:04 +01002842yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
2843{
2844 uint8_t i;
2845
2846 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
2847 free(list->tpdf);
2848
2849 for (i = 0; i < list->must_size; ++i) {
2850 lys_restr_free(ctx, &list->must[i]);
2851 }
2852 free(list->must);
2853
2854 lys_when_free(ctx, list->when);
2855
2856 for (i = 0; i < list->unique_size; ++i) {
2857 free(list->unique[i].expr);
2858 }
2859 free(list->unique);
2860
2861 free(list->keys);
2862}
2863
2864static void
Pavol Vican36ace102016-11-28 11:46:59 +01002865yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
2866{
2867 free(choice->dflt);
2868 lys_when_free(ctx, choice->when);
2869}
2870
2871static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002872yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
2873{
2874 uint8_t i;
2875
2876 for (i = 0; i < anydata->must_size; ++i) {
2877 lys_restr_free(ctx, &anydata->must[i]);
2878 }
2879 free(anydata->must);
2880
2881 lys_when_free(ctx, anydata->when);
2882}
2883
2884static void
Pavol Vican78729392016-11-28 17:18:22 +01002885yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
2886{
2887 uint8_t i;
2888
2889 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
2890 free(inout->tpdf);
2891
2892 for (i = 0; i < inout->must_size; ++i) {
2893 lys_restr_free(ctx, &inout->must[i]);
2894 }
2895 free(inout->must);
2896}
2897
2898static void
Pavol Vican29bf8802016-11-28 20:44:57 +01002899yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
2900{
2901 uint8_t i;
2902
2903 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
2904 free(notif->tpdf);
2905
2906 for (i = 0; i < notif->must_size; ++i) {
2907 lys_restr_free(ctx, &notif->must[i]);
2908 }
2909 free(notif->must);
2910}
2911
2912static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002913yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
2914{
2915 int i, j;
2916
2917 for (i = 0; i < uses->refine_size; i++) {
2918 lydict_remove(ctx, uses->refine[i].target_name);
2919 lydict_remove(ctx, uses->refine[i].dsc);
2920 lydict_remove(ctx, uses->refine[i].ref);
2921
2922 for (j = 0; j < uses->refine[i].must_size; j++) {
2923 lys_restr_free(ctx, &uses->refine[i].must[j]);
2924 }
2925 free(uses->refine[i].must);
2926
2927 for (j = 0; j < uses->refine[i].dflt_size; j++) {
2928 lydict_remove(ctx, uses->refine[i].dflt[j]);
2929 }
2930 free(uses->refine[i].dflt);
2931
2932 if (uses->refine[i].target_type & LYS_CONTAINER) {
2933 lydict_remove(ctx, uses->refine[i].mod.presence);
2934 }
2935 }
2936 free(uses->refine);
2937
2938 lys_when_free(ctx, uses->when);
2939}
2940
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002941static void
Pavol Vican05810b62016-11-23 14:07:22 +01002942yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
2943{
2944 struct lys_node *tmp, *child, *sibling;
2945
2946 if (!node) {
2947 return;
2948 }
2949 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01002950
2951 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002952 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01002953 sibling = tmp->next;
2954 /* common part */
2955 lydict_remove(ctx, tmp->name);
2956 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
PavolVican8c33b152017-01-27 12:45:34 +01002957 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002958 lydict_remove(ctx, tmp->dsc);
2959 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01002960 }
2961
2962 switch (tmp->nodetype) {
2963 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01002964 case LYS_RPC:
2965 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01002966 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
2967 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002968 case LYS_CONTAINER:
2969 yang_free_container(ctx, (struct lys_node_container *)tmp);
2970 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01002971 case LYS_LEAF:
2972 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
2973 break;
Pavol Vican36aff862016-11-26 17:07:05 +01002974 case LYS_LEAFLIST:
2975 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
2976 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01002977 case LYS_LIST:
2978 yang_free_list(ctx, (struct lys_node_list *)tmp);
2979 break;
Pavol Vican36ace102016-11-28 11:46:59 +01002980 case LYS_CHOICE:
2981 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
2982 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01002983 case LYS_CASE:
2984 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when);
2985 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002986 case LYS_ANYXML:
2987 case LYS_ANYDATA:
2988 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
2989 break;
Pavol Vican78729392016-11-28 17:18:22 +01002990 case LYS_INPUT:
2991 case LYS_OUTPUT:
2992 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
2993 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01002994 case LYS_NOTIF:
2995 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
2996 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002997 case LYS_USES:
2998 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
2999 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003000 default:
3001 break;
3002 }
3003
3004 yang_free_nodes(ctx, child);
3005 free(tmp);
3006 tmp = sibling;
3007 }
3008}
3009
Pavol Vican3ad50f82016-12-04 15:00:36 +01003010static void
3011yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3012{
3013 lydict_remove(ctx, aug->target_name);
3014 lydict_remove(ctx, aug->dsc);
3015 lydict_remove(ctx, aug->ref);
3016
PavolVican8c33b152017-01-27 12:45:34 +01003017 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003018 lys_when_free(ctx, aug->when);
3019 yang_free_nodes(ctx, aug->child);
3020}
3021
PavolVican75af21d2016-12-29 20:04:07 +01003022static void
3023yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3024{
3025 uint i, j;
3026
3027 for (i = index; i < dev->deviate_size; ++i) {
3028 lydict_remove(ctx, dev->deviate[i].units);
3029
3030 if (dev->deviate[i].type) {
3031 yang_type_free(ctx, dev->deviate[i].type);
3032 }
3033
3034 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3035 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3036 }
3037 free(dev->deviate[i].dflt);
3038
3039 for (j = 0; j < dev->deviate[i].must_size; ++j) {
3040 lys_restr_free(ctx, &dev->deviate[i].must[j]);
3041 }
3042 free(dev->deviate[i].must);
3043
3044 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3045 free(dev->deviate[i].unique[j].expr);
3046 }
3047 free(dev->deviate[i].unique);
3048 }
3049}
3050
Pavol Vican7313fc02016-11-14 01:10:31 +01003051/* free common item from module and submodule */
3052static void
Pavol Vican05810b62016-11-23 14:07:22 +01003053free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003054{
PavolVican75af21d2016-12-29 20:04:07 +01003055 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003056 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3057 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003058 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003059 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003060 for (i = 0; i < module->augment_size; ++i) {
3061 yang_free_augment(module->ctx, &module->augment[i]);
3062 }
3063 module->augment_size = 0;
3064 for (i = 0; i < module->deviation_size; ++i) {
3065 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3066 free(module->deviation[i].deviate);
3067 }
3068 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003069}
3070
Pavol Vican1cc4e192016-10-24 16:38:31 +02003071/* check function*/
3072
3073int
PavolVicanc1807262017-01-31 18:00:27 +01003074yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3075 void *parent, struct unres_schema *unres)
3076{
3077 struct unres_ext *info;
3078 uint i;
3079
3080 for (i = 0; i < size; ++i) {
3081 info = malloc(sizeof *info);
3082 info->data.yang = (*ext)[i]->parent;
3083 info->datatype = LYS_IN_YANG;
3084 info->parent = parent;
3085 info->mod = module;
3086 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003087 info->substmt = (*ext)[i]->insubstmt;
3088 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003089 info->ext_index = i;
3090 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3091 return EXIT_FAILURE;
3092 }
3093 }
3094
3095 return EXIT_SUCCESS;
3096}
3097
3098int
Pavol Vicanec423c92016-10-24 21:33:43 +02003099yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003100{
3101 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003102 struct lys_include *inc;
3103 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003104 size_t size;
3105 char *s;
3106
3107 imp = module->imp;
3108 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003109 inc = module->inc;
3110 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003111
3112 if (imp_size) {
3113 size = (imp_size * sizeof *module->imp) + sizeof(void*);
3114 module->imp_size = 0;
3115 module->imp = calloc(1, size);
3116 if (!module->imp) {
3117 LOGMEM;
3118 goto error;
3119 }
3120 /* set stop block for possible realloc */
3121 module->imp[imp_size].module = (void*)0x1;
Pavol Vicanec423c92016-10-24 21:33:43 +02003122 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003123
Pavol Vicanec423c92016-10-24 21:33:43 +02003124 if (inc_size) {
3125 size = (inc_size * sizeof *module->inc) + sizeof(void*);
3126 module->inc_size = 0;
3127 module->inc = calloc(1, size);
3128 if (!module->inc) {
3129 LOGMEM;
3130 goto error;
3131 }
3132 /* set stop block for possible realloc */
3133 module->inc[inc_size].submodule = (void*)0x1;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003134 }
3135
3136 for (i = 0; i < imp_size; ++i) {
3137 s = (char *) imp[i].module;
3138 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003139 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003140 ++i;
3141 goto error;
3142 }
3143 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003144 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003145 s = (char *) inc[j].submodule;
3146 inc[j].submodule = NULL;
3147 if (yang_fill_include(module, s, &inc[j], unres)) {
3148 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003149 goto error;
3150 }
3151 }
3152 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003153 free(imp);
3154
3155 return EXIT_SUCCESS;
3156
3157error:
3158 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003159 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003160 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003161 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003162 return EXIT_FAILURE;
3163}
Pavol Vican7313fc02016-11-14 01:10:31 +01003164
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003165static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003166yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003167{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003168 struct lys_iffeature *iffeature;
3169 uint8_t *ptr_size, size, i;
3170 char *s;
3171 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003172
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003173 switch (type) {
3174 case FEATURE_KEYWORD:
3175 iffeature = ((struct lys_feature *)parent)->iffeature;
3176 size = ((struct lys_feature *)parent)->iffeature_size;
3177 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3178 parent_is_feature = 1;
3179 break;
3180 case IDENTITY_KEYWORD:
3181 iffeature = ((struct lys_ident *)parent)->iffeature;
3182 size = ((struct lys_ident *)parent)->iffeature_size;
3183 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3184 break;
3185 case ENUM_KEYWORD:
3186 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3187 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3188 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3189 break;
3190 case BIT_KEYWORD:
3191 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3192 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3193 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3194 break;
3195 case REFINE_KEYWORD:
3196 iffeature = ((struct lys_refine *)ptr)->iffeature;
3197 size = ((struct lys_refine *)ptr)->iffeature_size;
3198 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3199 break;
3200 default:
3201 iffeature = ((struct lys_node *)parent)->iffeature;
3202 size = ((struct lys_node *)parent)->iffeature_size;
3203 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3204 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003205 }
3206
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003207 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003208 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003209 s = (char *)iffeature[i].features;
3210 iffeature[i].features = NULL;
3211 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3212 *ptr_size = size;
3213 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003214 }
PavolVican8fa31242017-02-07 11:04:26 +01003215 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3216 *ptr_size = size;
3217 return EXIT_FAILURE;
3218 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003219 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003220 }
3221
3222 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003223}
3224
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003225static int
3226yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3227{
3228 uint size, i;
3229 int rc;
3230 struct lys_ident **ref;
3231 const char *value;
3232 char *expr;
3233
3234 ref = type->info.ident.ref;
3235 size = type->info.ident.count;
3236 type->info.ident.count = 0;
3237 type->info.ident.ref = NULL;
3238 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3239
3240 for (i = 0; i < size; ++i) {
3241 expr = (char *)ref[i];
3242 /* store in the JSON format */
3243 value = transform_schema2json(module, expr);
3244 free(expr);
3245
3246 if (!value) {
3247 goto error;
3248 }
3249 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3250 lydict_remove(module->ctx, value);
3251
3252 if (rc == -1) {
3253 goto error;
3254 }
3255 }
3256 free(ref);
3257
3258 return EXIT_SUCCESS;
3259error:
3260 for (i = i+1; i < size; ++i) {
3261 free(ref[i]);
3262 }
3263 free(ref);
3264 return EXIT_FAILURE;
3265}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003266
Pavol Vican7313fc02016-11-14 01:10:31 +01003267int
PavolVican056fcd12017-02-07 15:36:53 +01003268yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3269 void *parent, struct unres_schema *unres)
3270{
3271 int i;
3272
3273 type->parent = parent;
3274 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3275 return EXIT_FAILURE;
3276 }
3277 switch (stype->base) {
3278 case LY_TYPE_ENUM:
3279 for (i = 0; i < type->info.enums.count; ++i) {
3280 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3281 return EXIT_FAILURE;
3282 }
3283 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3284 &type->info.enums.enm[i], unres)) {
3285 return EXIT_FAILURE;
3286 }
3287 }
3288 break;
3289 case LY_TYPE_BITS:
3290 for (i = 0; i < type->info.bits.count; ++i) {
3291 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3292 return EXIT_FAILURE;
3293 }
3294 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3295 &type->info.bits.bit[i], unres)) {
3296 return EXIT_FAILURE;
3297 }
3298 }
3299 break;
3300 case LY_TYPE_IDENT:
3301 if (yang_check_identityref(module, type, unres)) {
3302 return EXIT_FAILURE;
3303 }
3304 break;
3305 case LY_TYPE_STRING:
3306 if (type->info.str.length && yang_check_ext_instance(module, &type->info.str.length->ext,
3307 type->info.str.length->ext_size, type->info.str.length, unres)) {
3308 return EXIT_FAILURE;
3309 }
3310 for (i = 0; i < type->info.str.pat_count; ++i) {
3311 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3312 &type->info.str.patterns[i], unres)) {
3313 return EXIT_FAILURE;
3314 }
3315 }
3316 break;
3317 case LY_TYPE_DEC64:
3318 if (type->info.dec64.range && yang_check_ext_instance(module, &type->info.dec64.range->ext,
3319 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3320 return EXIT_FAILURE;
3321 }
3322 break;
3323 case LY_TYPE_UNION:
3324 for (i = 0; i < type->info.uni.count; ++i) {
3325 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3326 parent, unres)) {
3327 return EXIT_FAILURE;
3328 }
3329 }
3330 default:
3331 /* nothing checks */
3332 break;
3333 }
3334 return EXIT_SUCCESS;
3335}
3336
3337int
Pavol Vican7313fc02016-11-14 01:10:31 +01003338yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3339{
3340 struct lys_tpdf *tpdf;
PavolVican056fcd12017-02-07 15:36:53 +01003341 uint8_t i, tpdf_size, *ptr_tpdf_size;
Pavol Vican7313fc02016-11-14 01:10:31 +01003342
3343 if (!parent) {
3344 tpdf = module->tpdf;
3345 ptr_tpdf_size = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003346 } else {
3347 switch (parent->nodetype) {
3348 case LYS_GROUPING:
3349 tpdf = ((struct lys_node_grp *)parent)->tpdf;
3350 ptr_tpdf_size = &((struct lys_node_grp *)parent)->tpdf_size;
3351 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003352 case LYS_CONTAINER:
3353 tpdf = ((struct lys_node_container *)parent)->tpdf;
3354 ptr_tpdf_size = &((struct lys_node_container *)parent)->tpdf_size;
3355 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003356 case LYS_LIST:
3357 tpdf = ((struct lys_node_list *)parent)->tpdf;
3358 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3359 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003360 case LYS_RPC:
3361 case LYS_ACTION:
3362 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3363 ptr_tpdf_size = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3364 break;
Pavol Vican78729392016-11-28 17:18:22 +01003365 case LYS_INPUT:
3366 case LYS_OUTPUT:
3367 tpdf = ((struct lys_node_inout *)parent)->tpdf;
3368 ptr_tpdf_size = &((struct lys_node_inout *)parent)->tpdf_size;
3369 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003370 case LYS_NOTIF:
3371 tpdf = ((struct lys_node_notif *)parent)->tpdf;
3372 ptr_tpdf_size = &((struct lys_node_notif *)parent)->tpdf_size;
3373 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003374 default:
3375 LOGINT;
3376 return EXIT_FAILURE;
3377 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003378 }
3379
3380 tpdf_size = *ptr_tpdf_size;
3381 *ptr_tpdf_size = 0;
3382
3383 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003384 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3385 goto error;
3386 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003387
PavolVican056fcd12017-02-07 15:36:53 +01003388 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3389 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003390 }
PavolVicandf9e7972017-02-07 11:41:38 +01003391 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3392 goto error;
3393 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003394 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003395 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003396 }
3397
PavolVicane87cb932016-12-30 15:36:18 +01003398 (*ptr_tpdf_size)++;
Pavol Vican7313fc02016-11-14 01:10:31 +01003399 /* check default value*/
Pavol Vicanfda8c802016-12-03 02:00:42 +01003400 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 +01003401 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003402 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003403 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003404 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003405
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003406 return EXIT_SUCCESS;
3407
3408error:
3409 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3410 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003411}
3412
3413static int
Pavol Vican36e27272016-11-22 15:47:28 +01003414yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3415{
3416 uint32_t i, size, base_size;
3417 uint8_t j;
3418
3419 size = module->ident_size;
3420 module->ident_size = 0;
3421 for (i = 0; i < size; ++i) {
3422 base_size = module->ident[i].base_size;
3423 module->ident[i].base_size = 0;
3424 for (j = 0; j < base_size; ++j) {
3425 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3426 ++j;
3427 module->ident_size = size;
3428 goto error;
3429 }
3430 }
3431 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003432 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3433 goto error;
3434 }
PavolVican8fa31242017-02-07 11:04:26 +01003435 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3436 goto error;
3437 }
Pavol Vican36e27272016-11-22 15:47:28 +01003438 }
3439
PavolVican8fa31242017-02-07 11:04:26 +01003440
Pavol Vican36e27272016-11-22 15:47:28 +01003441 return EXIT_SUCCESS;
3442
3443error:
3444 for (; j< module->ident[i].base_size; ++j) {
3445 free(module->ident[i].base[j]);
3446 }
3447 yang_free_ident_base(module->ident, i + 1, size);
3448 return EXIT_FAILURE;
3449}
3450
3451static int
PavolVicane87cb932016-12-30 15:36:18 +01003452yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
3453 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003454{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003455 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003456 goto error;
3457 }
3458
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003459 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003460 goto error;
3461 }
3462
PavolVicane87cb932016-12-30 15:36:18 +01003463 if (yang_check_nodes(module, (struct lys_node *)cont, *child, config_opt, unres)) {
3464 *child = NULL;
3465 goto error;
3466 }
3467 *child = NULL;
3468
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003469 /* check XPath dependencies */
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003470 if ((cont->when || cont->must_size) && (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003471 goto error;
3472 }
3473
3474 return EXIT_SUCCESS;
3475error:
3476 return EXIT_FAILURE;
3477}
3478
3479static int
Pavol Vicana69aff22016-11-24 18:23:50 +01003480yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, struct unres_schema *unres)
3481{
PavolVican056fcd12017-02-07 15:36:53 +01003482 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003483 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003484 }
PavolVicana08d3652016-12-29 21:07:47 +01003485 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3486 yang_type_free(module->ctx, &leaf->type);
3487 goto error;
3488 }
3489
Pavol Vicanfda8c802016-12-03 02:00:42 +01003490 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003491 yang_type_free(module->ctx, &leaf->type);
3492 goto error;
3493 }
3494
Pavol Vicanfda8c802016-12-03 02:00:42 +01003495 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 +01003496 goto error;
3497 }
3498
Pavol Vicana69aff22016-11-24 18:23:50 +01003499 /* check XPath dependencies */
3500 if ((leaf->when || leaf->must_size) && (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1)) {
3501 goto error;
3502 }
3503
3504 return EXIT_SUCCESS;
3505error:
3506 return EXIT_FAILURE;
3507}
3508
3509static int
Pavol Vican36aff862016-11-26 17:07:05 +01003510yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, struct unres_schema *unres)
3511{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003512 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003513
PavolVican056fcd12017-02-07 15:36:53 +01003514 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003515 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003516 }
PavolVicana08d3652016-12-29 21:07:47 +01003517 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3518 yang_type_free(module->ctx, &leaflist->type);
3519 goto error;
3520 }
3521
Pavol Vicanfda8c802016-12-03 02:00:42 +01003522 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003523 yang_type_free(module->ctx, &leaflist->type);
3524 goto error;
3525 }
3526
Pavol Vican36aff862016-11-26 17:07:05 +01003527 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003528 /* check for duplicity in case of configuration data,
3529 * in case of status data duplicities are allowed */
3530 if (leaflist->flags & LYS_CONFIG_W) {
3531 for (j = i +1; j < leaflist->dflt_size; ++j) {
3532 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003533 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3534 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003535 goto error;
3536 }
3537 }
3538 }
3539 /* check default value (if not defined, there still could be some restrictions
3540 * that need to be checked against a default value from a derived type) */
Pavol Vican36aff862016-11-26 17:07:05 +01003541 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaflist->dflt[i])) == -1) {
3542 goto error;
3543 }
3544 }
3545
Pavol Vican36aff862016-11-26 17:07:05 +01003546 /* check XPath dependencies */
3547 if ((leaflist->when || leaflist->must_size) && (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1)) {
3548 goto error;
3549 }
3550
3551 return EXIT_SUCCESS;
3552error:
3553 return EXIT_FAILURE;
3554}
3555
3556static int
PavolVicane87cb932016-12-30 15:36:18 +01003557yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
3558 int config_opt, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003559{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003560 struct lys_node *node;
3561
Pavol Vicand8136a42016-11-27 13:28:04 +01003562 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3563 goto error;
3564 }
3565
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003566 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3567 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003568 }
3569
Pavol Vicanfda8c802016-12-03 02:00:42 +01003570 if (list->flags & LYS_CONFIG_R) {
3571 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3572 * ignore oredering MASK - 0x7F
3573 */
3574 list->flags &= 0x7F;
3575 }
3576 /* check - if list is configuration, key statement is mandatory
3577 * (but only if we are not in a grouping or augment, then the check is deferred) */
3578 for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT)); node = node->parent);
3579 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3580 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3581 goto error;
3582 }
3583
PavolVicane87cb932016-12-30 15:36:18 +01003584 if (yang_check_nodes(module, (struct lys_node *)list, *child, config_opt, unres)) {
3585 *child = NULL;
3586 goto error;
3587 }
3588 *child = NULL;
3589
Pavol Vicand8136a42016-11-27 13:28:04 +01003590 if (list->keys && yang_read_key(module, list, unres)) {
3591 goto error;
3592 }
3593
3594 if (yang_read_unique(module, list, unres)) {
3595 goto error;
3596 }
3597
3598 /* check XPath dependencies */
3599 if ((list->when || list->must_size) && (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1)) {
3600 goto error;
3601 }
3602
3603 return EXIT_SUCCESS;
3604error:
3605 return EXIT_FAILURE;
3606}
3607
3608static int
PavolVicane87cb932016-12-30 15:36:18 +01003609yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
3610 int config_opt, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003611{
3612 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003613
PavolVicana08d3652016-12-29 21:07:47 +01003614 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3615 free(choice->dflt);
3616 choice->dflt = NULL;
3617 goto error;
3618 }
3619
PavolVicane87cb932016-12-30 15:36:18 +01003620 if (yang_check_nodes(module, (struct lys_node *)choice, *child, config_opt, unres)) {
3621 *child = NULL;
3622 free(choice->dflt);
3623 choice->dflt = NULL;
3624 goto error;
3625 }
3626 *child = NULL;
3627
Pavol Vican36ace102016-11-28 11:46:59 +01003628 if (choice->dflt) {
3629 value = (char *)choice->dflt;
3630 choice->dflt = NULL;
3631 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3632 free(value);
3633 goto error;
3634 }
3635 free(value);
3636 }
3637
Pavol Vican36ace102016-11-28 11:46:59 +01003638 /* check XPath dependencies */
3639 if ((choice->when) && (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1)) {
3640 goto error;
3641 }
3642
3643 return EXIT_SUCCESS;
3644error:
3645 return EXIT_FAILURE;
3646}
3647
3648static int
PavolVicane87cb932016-12-30 15:36:18 +01003649yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
3650 int config_opt, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003651{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003652 struct lys_node *node;
3653
3654 if (rpc->nodetype == LYS_ACTION) {
3655 for (node = rpc->parent; node; node = lys_parent(node)) {
3656 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003657 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003658 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003659 goto error;
3660 }
3661 }
3662 }
3663 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3664 goto error;
3665 }
3666
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003667 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3668 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003669 }
3670
PavolVicane87cb932016-12-30 15:36:18 +01003671 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, config_opt, unres)) {
3672 *child = NULL;
3673 goto error;
3674 }
3675 *child = NULL;
3676
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003677 return EXIT_SUCCESS;
3678error:
3679 return EXIT_FAILURE;
3680}
3681
3682static int
PavolVicane87cb932016-12-30 15:36:18 +01003683yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
3684 int config_opt, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01003685{
Pavol Vican29bf8802016-11-28 20:44:57 +01003686 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3687 goto error;
3688 }
3689
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003690 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3691 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003692 }
3693
PavolVicane87cb932016-12-30 15:36:18 +01003694 if (yang_check_nodes(module, (struct lys_node *)notif, *child, config_opt, unres)) {
3695 *child = NULL;
3696 goto error;
3697 }
3698 *child = NULL;
3699
Pavol Vican29bf8802016-11-28 20:44:57 +01003700 /* check XPath dependencies */
3701 if ((notif->must_size) && (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1)) {
3702 goto error;
3703 }
3704
3705 return EXIT_SUCCESS;
3706error:
3707 return EXIT_FAILURE;
3708}
3709
3710static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003711yang_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 +01003712{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003713 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003714
Pavol Vican3ad50f82016-12-04 15:00:36 +01003715 child = augment->child;
3716 augment->child = NULL;
3717
PavolVicana08d3652016-12-29 21:07:47 +01003718 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
3719 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003720 goto error;
3721 }
3722
PavolVicana08d3652016-12-29 21:07:47 +01003723 if (yang_check_nodes(module, (struct lys_node *)augment, child, config_opt, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01003724 goto error;
3725 }
3726
3727 /* check XPath dependencies */
3728 if (augment->when && (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1)) {
3729 goto error;
3730 }
3731
3732 return EXIT_SUCCESS;
3733error:
3734 return EXIT_FAILURE;
3735}
3736
3737static int
3738yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int config_opt, struct unres_schema *unres)
3739{
3740 uint i, size;
3741
3742 size = uses->augment_size;
3743 uses->augment_size = 0;
3744
3745 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003746 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003747 }
3748
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003749 for (i = 0; i < uses->refine_size; ++i) {
3750 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
3751 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003752 }
3753 }
3754
Pavol Vican3ad50f82016-12-04 15:00:36 +01003755 for (i = 0; i < size; ++i) {
3756 uses->augment_size++;
3757 if (yang_check_augment(module, &uses->augment[i], config_opt, unres)) {
3758 goto error;
3759 }
3760 }
3761
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003762 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
3763 goto error;
3764 }
3765
3766 /* check XPath dependencies */
3767 if (uses->when && (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1)) {
3768 goto error;
3769 }
3770
3771 return EXIT_SUCCESS;
3772error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003773 for (i = uses->augment_size; i < size; ++i) {
3774 yang_free_augment(module->ctx, &uses->augment[i]);
3775 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003776 return EXIT_FAILURE;
3777}
3778
3779static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003780yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
3781 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003782{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003783 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01003784
3785 while (node) {
3786 sibling = node->next;
3787 child = node->child;
3788 node->next = NULL;
3789 node->child = NULL;
3790 node->prev = node;
PavolVican8c33b152017-01-27 12:45:34 +01003791
Pavol Vican24ba7f62016-11-28 12:15:20 +01003792 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
3793 lys_node_unlink(node);
3794 node->next = sibling;
Pavol Vican05810b62016-11-23 14:07:22 +01003795 sibling = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003796 goto error;
3797 }
Pavol Vicanec598812016-11-30 14:13:38 +01003798 config_opt = store_config_flag(node, config_opt);
PavolVican70ce7452017-02-01 15:39:39 +01003799 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
3800 goto error;
3801 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01003802
Pavol Vican05810b62016-11-23 14:07:22 +01003803 switch (node->nodetype) {
3804 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003805 if (yang_check_typedef(module, node, unres)) {
3806 goto error;
3807 }
3808 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003809 goto error;
3810 }
PavolVicane87cb932016-12-30 15:36:18 +01003811 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3812 child = NULL;
3813 goto error;
3814 }
Pavol Vican05810b62016-11-23 14:07:22 +01003815 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003816 case LYS_CONTAINER:
PavolVicane87cb932016-12-30 15:36:18 +01003817 if (yang_check_container(module, (struct lys_node_container *)node, &child, config_opt, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003818 goto error;
3819 }
3820 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003821 case LYS_LEAF:
3822 if (yang_check_leaf(module, (struct lys_node_leaf *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003823 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01003824 goto error;
3825 }
3826 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003827 case LYS_LEAFLIST:
3828 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003829 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01003830 goto error;
3831 }
3832 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003833 case LYS_LIST:
PavolVicane87cb932016-12-30 15:36:18 +01003834 if (yang_check_list(module, (struct lys_node_list *)node, &child, config_opt, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01003835 goto error;
3836 }
3837 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003838 case LYS_CHOICE:
PavolVicane87cb932016-12-30 15:36:18 +01003839 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, config_opt, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01003840 goto error;
3841 }
3842 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003843 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003844 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01003845 goto error;
3846 }
PavolVicane87cb932016-12-30 15:36:18 +01003847 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3848 child = NULL;
3849 goto error;
3850 }
Pavol Vicana420bac2016-11-28 14:51:54 +01003851 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003852 case LYS_ANYDATA:
3853 case LYS_ANYXML:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003854 if (yang_check_iffeatures(module, NULL, node, CHOICE_KEYWORD, unres)) {
3855 goto error;
3856 }
PavolVicane87cb932016-12-30 15:36:18 +01003857 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3858 child = NULL;
3859 goto error;
3860 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003861 /* check XPath dependencies */
3862 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 +01003863 goto error;
3864 }
3865 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003866 case LYS_RPC:
3867 case LYS_ACTION:
PavolVicane87cb932016-12-30 15:36:18 +01003868 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, config_opt, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003869 goto error;
3870 }
3871 break;
Pavol Vican78729392016-11-28 17:18:22 +01003872 case LYS_INPUT:
3873 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01003874 if (yang_check_typedef(module, node, unres)) {
3875 goto error;
3876 }
3877 if (yang_check_nodes(module, node, child, config_opt, unres)) {
3878 child = NULL;
3879 goto error;
3880 }
Pavol Vican78729392016-11-28 17:18:22 +01003881 /* check XPath dependencies */
3882 if (((struct lys_node_inout *)node)->must_size &&
3883 (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1)) {
3884 goto error;
3885 }
Pavol Vican78729392016-11-28 17:18:22 +01003886 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003887 case LYS_NOTIF:
PavolVicane87cb932016-12-30 15:36:18 +01003888 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, config_opt, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01003889 goto error;
3890 }
3891 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003892 case LYS_USES:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003893 if (yang_check_uses(module, (struct lys_node_uses *)node, config_opt, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003894 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003895 goto error;
3896 }
3897 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003898 default:
3899 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01003900 goto error;
3901 }
Pavol Vican05810b62016-11-23 14:07:22 +01003902 node = sibling;
3903 }
3904
3905 return EXIT_SUCCESS;
3906error:
3907 yang_free_nodes(module->ctx, sibling);
3908 yang_free_nodes(module->ctx, child);
3909 return EXIT_FAILURE;
3910}
3911
3912static int
PavolVican75af21d2016-12-29 20:04:07 +01003913yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
3914 struct lys_node *dev_target, struct ly_set *dflt_check)
3915{
3916 struct lys_node_leaflist *llist;
3917 struct lys_type *type;
3918 struct lys_tpdf *tmp_parent;
3919 int i, j;
3920
3921 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
3922 goto error;
3923 }
3924 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
3925 goto error;
3926 }
3927 if (deviate->dflt_size) {
3928 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
3929 goto error;
3930 }
3931 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
3932 /* consolidate the final list in the target after removing items from it */
3933 llist = (struct lys_node_leaflist *)dev_target;
3934 for (i = j = 0; j < llist->dflt_size; j++) {
3935 llist->dflt[i] = llist->dflt[j];
3936 if (llist->dflt[i]) {
3937 i++;
3938 }
3939 }
3940 llist->dflt_size = i + 1;
3941 }
3942 }
3943
3944 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
3945 goto error;
3946 }
3947
3948 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
3949 goto error;
3950 }
3951
3952 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
3953 goto error;
3954 }
3955
3956 if ((deviate->flags & LYS_CONFIG_MASK)) {
3957 /* add and replace are the same in this case */
3958 /* remove current config value of the target ... */
3959 dev_target->flags &= ~LYS_CONFIG_MASK;
3960
3961 /* ... and replace it with the value specified in deviation */
3962 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
3963 }
3964
3965 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
3966 goto error;
3967 }
3968
3969 if (deviate->type) {
3970 /* check target node type */
3971 if (dev_target->nodetype == LYS_LEAF) {
3972 type = &((struct lys_node_leaf *)dev_target)->type;
3973 } else if (dev_target->nodetype == LYS_LEAFLIST) {
3974 type = &((struct lys_node_leaflist *)dev_target)->type;
3975 } else {
3976 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
3977 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
3978 goto error;
3979 }
3980 /* remove type and initialize it */
3981 tmp_parent = type->parent;
3982 lys_type_free(module->ctx, type);
3983 memcpy(type, deviate->type, sizeof *deviate->type);
3984 free(deviate->type);
3985 deviate->type = type;
3986 deviate->type->parent = tmp_parent;
3987 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
3988 goto error;
3989 }
3990 }
3991
3992 return EXIT_SUCCESS;
3993error:
3994 if (deviate->type) {
3995 yang_type_free(module->ctx, deviate->type);
3996 deviate->type = NULL;
3997 }
3998 return EXIT_FAILURE;
3999}
4000
4001static int
4002yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4003{
4004 int rc;
4005 uint i;
4006 struct lys_node *dev_target = NULL, *parent;
4007 struct ly_set *dflt_check = ly_set_new();
4008 unsigned int u;
4009 const char *value, *target_name;
4010 struct lys_node_leaflist *llist;
4011 struct lys_node_leaf *leaf;
4012 struct unres_schema tmp_unres;
4013 struct lys_module *mod;
4014
4015 /* resolve target node */
4016 rc = resolve_augment_schema_nodeid(dev->target_name, NULL, module, 1, (const struct lys_node **)&dev_target);
4017 if (rc || !dev_target) {
4018 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4019 goto error;
4020 }
4021 if (dev_target->module == lys_main_module(module)) {
4022 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4023 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4024 goto error;
4025 }
4026
4027 if (!dflt_check) {
4028 LOGMEM;
4029 goto error;
4030 }
4031
4032 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4033 /* you cannot remove a key leaf */
4034 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4035 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4036 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4037 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4038 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
4039 return EXIT_FAILURE;
4040 }
4041 }
4042 }
4043 /* unlink and store the original node */
4044 lys_node_unlink(dev_target);
4045 dev->orig_node = dev_target;
4046 } else {
4047 /* store a shallow copy of the original node */
4048 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004049 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004050 /* just to be safe */
4051 if (tmp_unres.count) {
4052 LOGINT;
4053 goto error;
4054 }
4055 }
4056
4057 for (i = 0; i < dev->deviate_size; ++i) {
4058 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4059 yang_free_deviate(module->ctx, dev, i + 1);
4060 dev->deviate_size = i+1;
4061 goto error; // missing free unresolve type in deviate
4062 }
4063 }
4064 /* now check whether default value, if any, matches the type */
4065 for (u = 0; u < dflt_check->number; ++u) {
4066 value = NULL;
4067 rc = EXIT_SUCCESS;
4068 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4069 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4070 target_name = leaf->name;
4071 value = leaf->dflt;
4072 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4073 } else { /* LYS_LEAFLIST */
4074 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4075 target_name = llist->name;
4076 for (i = 0; i < llist->dflt_size; i++) {
4077 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4078 (struct lys_node *)(&llist->dflt[i]));
4079 if (rc == -1) {
4080 value = llist->dflt[i];
4081 break;
4082 }
4083 }
4084 }
4085 if (rc == -1) {
4086 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4087 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
4088 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4089 target_name);
4090 goto error;
4091 }
4092 }
4093 ly_set_free(dflt_check);
4094
4095 /* mark all the affected modules as deviated and implemented*/
4096 for(parent = dev_target; parent; parent = lys_parent(parent)) {
4097 mod = lys_node_module(parent);
4098 if (module != mod) {
4099 mod->deviated = 1;
4100 lys_set_implemented(mod);
4101 }
4102}
4103
4104 return EXIT_SUCCESS;
4105error:
4106 ly_set_free(dflt_check);
4107 return EXIT_FAILURE;
4108}
4109
4110static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004111yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4112{
PavolVican75af21d2016-12-29 20:04:07 +01004113 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004114
4115 aug_size = module->augment_size;
4116 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004117 dev_size = module->deviation_size;
4118 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004119
PavolVicanc1807262017-01-31 18:00:27 +01004120 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4121 goto error;
4122 }
4123
PavolVican171717d2017-02-01 14:49:55 +01004124 /* check extension in revision */
4125 for (i = 0; i < module->rev_size; ++i) {
4126 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4127 goto error;
4128 }
4129 }
4130
PavolVican19dc6152017-02-06 12:04:15 +01004131 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004132 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004133 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4134 goto error;
4135 }
4136 }
4137
Pavol Vican7313fc02016-11-14 01:10:31 +01004138 if (yang_check_typedef(module, NULL, unres)) {
4139 goto error;
4140 }
4141
Pavol Vican7a7916f2016-11-21 23:38:30 +01004142 /* check features */
4143 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004144 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4145 goto error;
4146 }
PavolVican5393d3f2017-02-06 23:30:55 +01004147 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4148 goto error;
4149 }
4150
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004151 /* check for circular dependencies */
4152 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4153 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004154 }
4155 }
Pavol Vican36e27272016-11-22 15:47:28 +01004156 erase_identities = 0;
4157 if (yang_check_identities(module, unres)) {
4158 goto error;
4159 }
Pavol Vican05810b62016-11-23 14:07:22 +01004160 erase_nodes = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004161 if (yang_check_nodes(module, NULL, node, CONFIG_INHERIT_ENABLE, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004162 goto error;
4163 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004164
PavolVican75af21d2016-12-29 20:04:07 +01004165 /* check deviation */
4166 for (i = 0; i < dev_size; ++i) {
4167 module->deviation_size++;
4168 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4169 goto error;
4170 }
4171 }
4172
Pavol Vican3ad50f82016-12-04 15:00:36 +01004173 /* check augments */
4174 for (i = 0; i < aug_size; ++i) {
4175 module->augment_size++;
4176 if (yang_check_augment(module, &module->augment[i], CONFIG_INHERIT_ENABLE, unres)) {
4177 goto error;
4178 }
4179 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4180 goto error;
4181 }
4182 }
4183
Pavol Vican7313fc02016-11-14 01:10:31 +01004184 return EXIT_SUCCESS;
4185error:
Pavol Vican36e27272016-11-22 15:47:28 +01004186 if (erase_identities) {
4187 yang_free_ident_base(module->ident, 0, module->ident_size);
4188 }
Pavol Vican05810b62016-11-23 14:07:22 +01004189 if (erase_nodes) {
4190 yang_free_nodes(module->ctx, node);
4191 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004192 for (i = module->augment_size; i < aug_size; ++i) {
4193 yang_free_augment(module->ctx, &module->augment[i]);
4194 }
PavolVican75af21d2016-12-29 20:04:07 +01004195 for (i = module->deviation_size; i < dev_size; ++i) {
4196 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4197 free(module->deviation[i].deviate);
4198 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004199 return EXIT_FAILURE;
4200}