blob: c0432889a686704d5bc6cb0aeb6fbc9144b03823 [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);
Pavol Vican05810b62016-11-23 14:07:22 +010028void lys_iffeature_free(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
Pavol Vican0adf01d2016-03-22 12:29:33 +010031yang_check_string(struct lys_module *module, const char **target, char *what, char *where, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +010032{
Pavol Vicanbf805472016-01-26 14:24:56 +010033 if (*target) {
Pavol Vican0adf01d2016-03-22 12:29:33 +010034 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010035 free(value);
36 return 1;
37 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010038 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010039 return 0;
40 }
41}
42
Michal Vaskofe7e5a72016-05-02 14:49:23 +020043int
Pavol Vican5f0316a2016-04-05 21:21:11 +020044yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010045{
Pavol Vican6eb14e82016-02-03 12:27:13 +010046 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010047
48 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010049 case MODULE_KEYWORD:
50 module->name = lydict_insert_zc(module->ctx, value);
51 break;
52 case NAMESPACE_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010053 ret = yang_check_string(module, &module->ns, "namespace", "module", value);
Pavol Vican2a064652016-02-02 22:54:34 +010054 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010055 case ORGANIZATION_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010056 ret = yang_check_string(module, &module->org, "organization", "module", value);
Pavol Vican1ca072c2016-02-03 13:03:56 +010057 break;
58 case CONTACT_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010059 ret = yang_check_string(module, &module->contact, "contact", "module", value);
Pavol Vican1ca072c2016-02-03 13:03:56 +010060 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020061 default:
62 free(value);
63 LOGINT;
64 ret = EXIT_FAILURE;
65 break;
Pavol Vican2a064652016-02-02 22:54:34 +010066 }
67
Pavol Vican021488a2016-01-25 23:56:12 +010068 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010069}
70
Michal Vaskofe7e5a72016-05-02 14:49:23 +020071int
Pavol Vicand0b64c12016-07-15 09:56:19 +020072yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
73{
74 int ret = EXIT_SUCCESS;
75
76 if (repeat) {
Michal Vasko3767fb22016-07-21 12:10:57 +020077 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
78 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020079 } else {
80 if (!strcmp(value, "1")) {
81 if (submodule) {
82 if (module->version > 1) {
83 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
84 ret = EXIT_FAILURE;
85 }
86 } else {
87 module->version = 1;
88 }
89 } else if (!strcmp(value, "1.1")) {
90 if (submodule) {
91 if (module->version != 2) {
92 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
93 ret = EXIT_FAILURE;
94 }
95 } else {
96 module->version = 2;
97 }
98 } else {
99 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
100 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200101 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200102 }
103 free(value);
104 return ret;
105}
106
107int
Pavol Vicane024ab72016-07-27 14:27:43 +0200108yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100109{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100110 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100111
Pavol Vican1cc4e192016-10-24 16:38:31 +0200112 if (!imp && lyp_check_identifier(value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100113 free(value);
114 return EXIT_FAILURE;
115 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200116
117 if (imp) {
118 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value);
119 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100120 ret = yang_check_string(module, &module->prefix, "prefix", "module", value);
Pavol Vican2a064652016-02-02 22:54:34 +0100121 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100122
Pavol Vicanbf805472016-01-26 14:24:56 +0100123 return ret;
124}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100125
Pavol Vican1cc4e192016-10-24 16:38:31 +0200126static int
127yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new, char *value)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100128{
Pavol Vican0da132e2016-03-21 12:03:03 +0100129 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200130 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100131
Pavol Vican1cc4e192016-10-24 16:38:31 +0200132 if (!imp_old->prefix) {
Pavol Vicane024ab72016-07-27 14:27:43 +0200133 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200134 goto error;
135 } else {
136 if (lyp_check_identifier(imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
137 goto error;
138 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200139 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200140 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100141 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100143 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200144 module->imp_size++;
Pavol Vican0da132e2016-03-21 12:03:03 +0100145 if (rc) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200146 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100147 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100148
Pavol Vican6eb14e82016-02-03 12:27:13 +0100149 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200150
151error:
152 free(value);
153 lydict_remove(module->ctx, imp_old->dsc);
154 lydict_remove(module->ctx, imp_old->ref);
155 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100156}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100157
158int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100159yang_read_description(struct lys_module *module, void *node, char *value, char *where)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100160{
161 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100162 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100163
164 if (!node) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100165 ret = yang_check_string(module, &module->dsc, dsc, "module", value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100166 } else {
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100167 if (!strcmp("revision", where)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100168 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value);
Pavol Vicane024ab72016-07-27 14:27:43 +0200169 } else if (!strcmp("import", where)){
170 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value);
171 } else if (!strcmp("include", where)){
172 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value);
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100173 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100174 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100175 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100176 }
177 return ret;
178}
179
180int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100181yang_read_reference(struct lys_module *module, void *node, char *value, char *where)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100182{
183 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100184 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100185
186 if (!node) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100187 ret = yang_check_string(module, &module->ref, "reference", "module", value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100188 } else {
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100189 if (!strcmp("revision", where)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100190 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value);
Pavol Vicane024ab72016-07-27 14:27:43 +0200191 } else if (!strcmp("import", where)){
192 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value);
193 } else if (!strcmp("include", where)){
194 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value);
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100195 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100196 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100197 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100198 }
199 return ret;
200}
Pavol Vicanbedff692016-02-03 14:29:17 +0100201
Pavol Vican866d9912016-10-25 09:13:30 +0200202void
203yang_read_revision(struct lys_module *module, char *value, struct lys_revision *retval)
Pavol Vicanbedff692016-02-03 14:29:17 +0100204{
Pavol Vicanbedff692016-02-03 14:29:17 +0100205 /* first member of array is last revision */
Pavol Vican866d9912016-10-25 09:13:30 +0200206 if ((module->rev_size - 1) && strcmp(module->rev[0].date, value) < 0) {
Pavol Vicanbedff692016-02-03 14:29:17 +0100207 memcpy(retval->date, module->rev[0].date, LY_REV_SIZE);
208 memcpy(module->rev[0].date, value, LY_REV_SIZE);
209 retval->dsc = module->rev[0].dsc;
210 retval->ref = module->rev[0].ref;
211 retval = module->rev;
212 retval->dsc = NULL;
213 retval->ref = NULL;
214 } else {
215 memcpy(retval->date, value, LY_REV_SIZE);
216 }
Pavol Vicanbedff692016-02-03 14:29:17 +0100217 free(value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100218}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100219
220int
Pavol Vicana1827962016-02-29 15:39:42 +0100221yang_add_elem(struct lys_node_array **node, uint32_t *size)
Pavol Vican1eeb1992016-02-09 11:10:45 +0100222{
Pavol Vican45ccc592016-03-09 18:53:48 +0100223 if (!(*size % LY_ARRAY_SIZE)) {
Pavol Vican1eeb1992016-02-09 11:10:45 +0100224 if (!(*node = ly_realloc(*node, (*size + LY_ARRAY_SIZE) * sizeof **node))) {
225 LOGMEM;
226 return EXIT_FAILURE;
227 } else {
Pavol Vican45ccc592016-03-09 18:53:48 +0100228 memset(*node + *size, 0, LY_ARRAY_SIZE * sizeof **node);
Pavol Vican1eeb1992016-02-09 11:10:45 +0100229 }
230 }
231 (*size)++;
232 return EXIT_SUCCESS;
233}
Pavol Vicane1354e92016-02-09 14:02:09 +0100234
Pavol Vicane1354e92016-02-09 14:02:09 +0100235int
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) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100302 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100303 } else {
Pavol Vicandde090a2016-08-30 15:12:14 +0200304 ret = yang_check_string(module, &save->emsg, "error_message", what, value);
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 }
Pavol Vican531a9132016-03-03 10:10:09 +0100427 if (value) {
428 node->name = lydict_insert_zc(module->ctx, value);
429 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100430 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100431 node->nodetype = nodetype;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100432
433 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100434 child = (parent) ? &parent->child : root;
435 if (*child) {
436 (*child)->prev->next = node;
437 (*child)->prev = node;
438 } else {
439 *child = node;
440 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100441 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100442 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100443}
444
445int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200446yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100447{
448 int ret;
449
450 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100451 case LEAF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100452 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100453 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100454 case TYPEDEF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100455 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value);
Pavol Vican0df02b02016-03-01 10:28:50 +0100456 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200457 default:
458 free(value);
459 LOGINT;
460 ret = EXIT_FAILURE;
461 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100462 }
463 return ret;
464}
465
466int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200467yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100468{
469 int ret;
470
471 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100472 case LEAF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100473 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100474 break;
475 case LEAF_LIST_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100476 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100477 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100478 case TYPEDEF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100479 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value);
Pavol Vican0df02b02016-03-01 10:28:50 +0100480 break;
PavolVican75af21d2016-12-29 20:04:07 +0100481 case ADD_KEYWORD:
482 case REPLACE_KEYWORD:
483 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value);
484 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200485 default:
486 free(value);
487 LOGINT;
488 ret = EXIT_FAILURE;
489 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100490 }
491 return ret;
492}
Pavol Vican5de33492016-02-22 14:03:24 +0100493
494int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100495yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100496{
497 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100498 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100499
500 exp = value = (char *) list->keys;
501 while ((value = strpbrk(value, " \t\n"))) {
502 list->keys_size++;
503 while (isspace(*value)) {
504 value++;
505 }
506 }
507 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100508
509 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100510 list->keys = calloc(list->keys_size, sizeof *list->keys);
511 if (!list->keys) {
512 LOGMEM;
Radek Krejci5c08a992016-11-02 13:30:04 +0100513 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100514 }
Radek Krejci5c08a992016-11-02 13:30:04 +0100515 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
516 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
517 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100518 }
Pavol Vican5de33492016-02-22 14:03:24 +0100519 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100520}
521
522int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100523yang_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 +0100524{
525 int i, j;
526 char *vaux;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200527 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100528
529 /* count the number of unique leafs in the value */
530 vaux = value;
531 while ((vaux = strpbrk(vaux, " \t\n"))) {
532 unique->expr_size++;
533 while (isspace(*vaux)) {
534 vaux++;
535 }
536 }
537 unique->expr_size++;
538 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
539 if (!unique->expr) {
540 LOGMEM;
541 goto error;
542 }
543
544 for (i = 0; i < unique->expr_size; i++) {
545 vaux = strpbrk(value, " \t\n");
546 if (!vaux) {
547 /* the last token, lydict_insert() will count its size on its own */
548 vaux = value;
549 }
550
551 /* store token into unique structure */
552 unique->expr[i] = lydict_insert(module->ctx, value, vaux - value);
553
554 /* check that the expression does not repeat */
555 for (j = 0; j < i; j++) {
556 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100557 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
558 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100559 goto error;
560 }
561 }
562 /* try to resolve leaf */
563 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200564 unique_info = malloc(sizeof *unique_info);
565 unique_info->list = (struct lys_node *)list;
566 unique_info->expr = unique->expr[i];
567 unique_info->trg_type = &unique->trg_type;
568 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200569 goto error;
570 }
Pavol Vican85f12022016-03-05 16:30:35 +0100571 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200572 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100573 goto error;
574 }
575 }
576
577 /* move to next token */
578 value = vaux;
579 while(isspace(*value)) {
580 value++;
581 }
582 }
583
584 return EXIT_SUCCESS;
585
586error:
587 return EXIT_FAILURE;
588}
589
590int
Pavol Vican5de33492016-02-22 14:03:24 +0100591yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
592{
593 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100594 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100595
596 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100597 str = (char *)list->unique[k].expr;
598 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100599 goto error;
600 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100601 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100602 }
603 return EXIT_SUCCESS;
604
605error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100606 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100607 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100608}
609
Pavol Vican07f220f2016-09-02 13:04:37 +0200610int
Pavol Vican81344ac2016-09-02 14:23:06 +0200611yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100612{
Pavol Vican81344ac2016-09-02 14:23:06 +0200613 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
614 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
615 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100616 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200617 if (stype->type->info.lref.path) {
618 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
619 goto error;
620 }
621 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
622 stype->base = LY_TYPE_LEAFREF;
623 return EXIT_SUCCESS;
624
625error:
626 free(value);
627 return EXIT_FAILURE;
628}
629
630int
631yang_read_require_instance(struct yang_type *stype, int req)
632{
633 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
634 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
635 return EXIT_FAILURE;
636 }
637 if (stype->type->info.lref.req) {
638 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
639 return EXIT_FAILURE;
640 }
641 stype->type->info.lref.req = req;
642 stype->base = LY_TYPE_LEAFREF;
643 return EXIT_SUCCESS;
644}
645
646int
Pavol Vican7313fc02016-11-14 01:10:31 +0100647yang_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 +0100648{
Pavol Vican81344ac2016-09-02 14:23:06 +0200649 int i, j, rc, ret = -1;
650 int8_t req;
Pavol Vican73e7c992016-02-24 12:18:05 +0100651 const char *name, *value;
Pavol Vican8bd72e42016-08-29 09:53:05 +0200652 LY_DATA_TYPE base = 0;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200653 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200654 struct lys_type *dertype;
655 struct lys_type_enum *enms_sc = NULL;
656 struct lys_type_bit *bits_sc = NULL;
657 struct lys_type_bit bit_tmp;
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) {
703 if (!((struct lys_node_grp *)siter)->nacm) {
704 LOGINT;
705 goto error;
706 }
707 ((struct lys_node_grp *)siter)->nacm--;
708 } else {
709 LOGINT;
710 goto error;
711 }
712 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200713
714 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100715 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
716 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200717 goto error;
718 }
719
Pavol Vican8bd72e42016-08-29 09:53:05 +0200720 base = typ->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100721 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100722 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100723 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100724 }
725 switch (base) {
726 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100727 if (type->base == LY_TYPE_BINARY) {
728 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100729 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100730 goto error;
731 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100732 type->info.binary.length = type->info.str.length;
733 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
734 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100735 goto error;
736 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100737 } else if (type->base == LY_TYPE_STRING) {
738 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
739 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100740 goto error;
741 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100742 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100743 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100744 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100745 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100746 break;
747 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100748 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100749 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100750 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100751 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100752 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100753 goto error;
754 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100755 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100756 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100757 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100758 goto error;
759 }
Radek Krejci4800f652016-09-08 14:02:52 +0200760
761 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100762 if (type->der->type.der) {
763 type->info.dec64.dig = type->der->type.info.dec64.dig;
764 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200765 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100766 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
767 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200768 goto error;
769 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100770 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
771 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100772 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100773 goto error;
774 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100775 type->info.num.range = type->info.dec64.range;
776 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
777 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100778 goto error;
779 }
780 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100781 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100782 goto error;
783 }
784 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100785 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100786 if (type->base != LY_TYPE_ENUM) {
787 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100788 goto error;
789 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100790 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200791
792 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100793 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200794 /* type is derived directly from buit-in enumeartion type and enum statement is required */
795 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
796 goto error;
797 }
798 } else {
799 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100800 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200801 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
802 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
803 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
804 goto error;
805 }
806
807 /* restricted enumeration type - the name MUST be used in the base type */
808 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100809 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200810 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100811 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200812 break;
813 }
814 }
815 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100816 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200817 goto error;
818 }
819
Pavol Vican7313fc02016-11-14 01:10:31 +0100820 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200821 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100822 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200823 } else {
824 /* check that the assigned value corresponds to the original
825 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100826 if (type->info.enums.enm[i].value != enms_sc[j].value) {
827 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200828 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100829 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
830 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200831 goto error;
832 }
833 }
834 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100835 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100836 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100837 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 if (type->base != LY_TYPE_BITS) {
839 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100840 goto error;
841 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100842 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200843
844 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100845 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200846 /* type is derived directly from buit-in bits type and bit statement is required */
847 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
848 goto error;
849 }
850 } else {
851 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100852 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200853 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
854 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
855 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
856 goto error;
857 }
858
859 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100860 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200861 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100862 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200863 break;
864 }
865 }
866 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100867 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200868 goto error;
869 }
870
871 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100872 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200873 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100874 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200875 } else {
876 /* check that the assigned position corresponds to the original
877 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100878 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
879 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200880 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100881 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
882 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200883 goto error;
884 }
885 }
886 }
Pavol Vican03a59442016-03-21 15:23:45 +0100887 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200888
Pavol Vican7313fc02016-11-14 01:10:31 +0100889 for (i = type->info.bits.count - 1; i > 0; i--) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200890 j = i;
891
892 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100893 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200894 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100895 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
896 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
897 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200898 j--;
899 }
Pavol Vican03a59442016-03-21 15:23:45 +0100900 }
901 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100902 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100903 if (type->base == LY_TYPE_INST) {
904 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200905 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100906 goto error;
907 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100908 if ((req = type->info.lref.req)) {
909 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200910 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100911 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200912 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100913 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200914 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
915 goto error;
916 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200917 /* flag resolving for later use */
918 if (!tpdftype) {
919 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
920 if (siter) {
921 /* just a flag - do not resolve */
922 tpdftype = 1;
923 }
924 }
925
Pavol Vican7313fc02016-11-14 01:10:31 +0100926 if (type->info.lref.path) {
927 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200928 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
929 goto error;
930 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100931 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100932 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100933 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100934 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100935 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100936 goto error;
937 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200938 /* try to resolve leafref path only when this is instantiated
939 * leaf, so it is not:
940 * - typedef's type,
941 * - in grouping definition,
942 * - just instantiated in a grouping definition,
943 * because in those cases the nodes referenced in path might not be present
944 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100945 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100946 goto error;
947 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100948 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100949 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100950 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200951 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200952 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100953 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200954 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100955 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200956 goto error;
957 }
Radek Krejci742be352016-07-17 12:18:54 +0200958
Radek Krejci3a5501d2016-07-18 22:03:34 +0200959 /* add pointer to leafref target, only on leaves (not in typedefs) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100960 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 +0200961 goto error;
Radek Krejci742be352016-07-17 12:18:54 +0200962 }
Pavol Vican191613a2016-02-26 16:21:32 +0100963 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100964 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100965 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100966 goto error;
967 }
968 break;
969 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100970 if (type->base != LY_TYPE_IDENT) {
971 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100972 goto error;
973 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100974 if (type->der->type.der) {
975 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200976 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
977 goto error;
978 }
979 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100980 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200981 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
982 goto error;
983 }
984 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100985 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100986 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100987 if (type->base != LY_TYPE_UNION) {
988 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100989 goto error;
990 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100991 if (!type->info.uni.types) {
992 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100993 /* this is just a derived type with no additional type specified/required */
994 break;
995 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100996 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100997 goto error;
998 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100999 for (i = 0; i < type->info.uni.count; i++) {
1000 type->info.uni.types[i].parent = type->parent;
1001 if (unres_schema_add_node(module, unres, &type->info.uni.types[i],
Michal Vasko5d631402016-07-21 13:15:15 +02001002 tpdftype ? UNRES_TYPE_DER_TPDF : UNRES_TYPE_DER, parent) == -1) {
Pavol Vicana4f045a2016-02-29 15:01:20 +01001003 goto error;
1004 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001005 if (module->version < 2) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001006 if (type->info.uni.types[i].base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001007 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
1008 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01001009 } else if (type->info.uni.types[i].base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001010 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
1011 goto error;
1012 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001013 }
1014 }
1015 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001016
1017 default:
1018 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001019 if (type->base != base) {
1020 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001021 goto error;
1022 }
1023 } else {
1024 LOGINT;
1025 goto error;
1026 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001027 }
1028 return EXIT_SUCCESS;
1029
1030error:
Pavol Vican7313fc02016-11-14 01:10:31 +01001031 if (type->module_name) {
1032 lydict_remove(module->ctx, type->module_name);
1033 type->module_name = NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001034 }
Pavol Vican8bd72e42016-08-29 09:53:05 +02001035 if (base) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001036 type->base = base;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001037 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001038 return ret;
1039}
1040
1041void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001042yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001043{
1044 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001045 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001046
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001047 typ = calloc(1, sizeof *typ);
1048 if (!typ) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001049 LOGMEM;
1050 return NULL;
1051 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001052
1053 typ->flags = LY_YANG_STRUCTURE_FLAG;
1054 switch (type) {
1055 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001056 if (((struct lys_node_leaf *)parent)->type.der) {
1057 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1058 goto error;
1059 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001060 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1061 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1062 typ->type = &((struct lys_node_leaf *)parent)->type;
1063 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001064 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001065 if (((struct lys_node_leaflist *)parent)->type.der) {
1066 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1067 goto error;
1068 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001069 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1070 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1071 typ->type = &((struct lys_node_leaflist *)parent)->type;
1072 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001073 case UNION_KEYWORD:
1074 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1075 typ->type = (struct lys_type *)parent;
1076 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001077 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001078 if (((struct lys_tpdf *)parent)->type.der) {
1079 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1080 goto error;
1081 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001082 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1083 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001084 break;
1085 case REPLACE_KEYWORD:
1086 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001087 dev = (struct lys_deviate *)parent;
1088 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001089 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001090 goto error;
1091 }
PavolVican75af21d2016-12-29 20:04:07 +01001092 dev->type = calloc(1, sizeof *dev->type);
1093 if (!dev->type) {
1094 LOGMEM;
Pavol Vican4766aca2016-03-07 12:42:36 +01001095 goto error;
1096 }
PavolVican75af21d2016-12-29 20:04:07 +01001097 dev->type->der = (struct lys_tpdf *)typ;
1098 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001099 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001100 default:
1101 goto error;
1102 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001103 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001104 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001105 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001106
1107error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001108 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001109 free(typ);
1110 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001111}
1112
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001113void
1114yang_delete_type(struct lys_module *module, struct yang_type *stype)
1115{
1116 int i;
1117
Pavol Vican77a95e52016-08-15 09:49:26 +02001118 if (!stype) {
1119 return;
1120 }
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001121 stype->type->base = stype->base;
1122 stype->type->der = NULL;
1123 lydict_remove(module->ctx, stype->name);
1124 if (stype->base == LY_TYPE_UNION) {
1125 for (i = 0; i < stype->type->info.uni.count; i++) {
1126 if (stype->type->info.uni.types[i].der) {
1127 yang_delete_type(module, (struct yang_type *)stype->type->info.uni.types[i].der);
1128 }
1129 }
1130 }
1131 free(stype);
1132}
1133
Pavol Vican73e7c992016-02-24 12:18:05 +01001134void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001135yang_read_length(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican73e7c992016-02-24 12:18:05 +01001136{
1137 struct lys_restr **length;
1138
Pavol Vican6b072512016-04-04 10:50:21 +02001139 if (typ->base == 0 || typ->base == LY_TYPE_STRING) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001140 length = &typ->type->info.str.length;
Pavol Vican6b072512016-04-04 10:50:21 +02001141 typ->base = LY_TYPE_STRING;
1142 } else if (typ->base == LY_TYPE_BINARY) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001143 length = &typ->type->info.binary.length;
1144 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001145 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +01001146 goto error;
1147 }
1148
1149 if (*length) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001150 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001151 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001152 }
1153 *length = calloc(1, sizeof **length);
1154 if (!*length) {
1155 LOGMEM;
1156 goto error;
1157 }
1158 (*length)->expr = lydict_insert_zc(module->ctx, value);
1159 return *length;
1160
1161error:
1162 free(value);
1163 return NULL;
1164
1165}
Pavol Vican1c203db2016-02-24 14:05:23 +01001166
Pavol Vican6eecf302016-08-10 11:09:05 +02001167int
1168yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001169{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001170 char *buf;
1171 size_t len;
1172
Michal Vasko0aee5c12016-06-17 14:27:26 +02001173 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001174 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001175 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001176 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001177
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001178 len = strlen(value);
1179 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Pavol Vican6eecf302016-08-10 11:09:05 +02001180
1181 if (!buf) {
1182 LOGMEM;
1183 free(value);
1184 return EXIT_FAILURE;
1185 }
1186
1187 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001188 strcpy(&buf[1], value);
1189 free(value);
1190
Pavol Vican6eecf302016-08-10 11:09:05 +02001191 pattern->expr = lydict_insert_zc(module->ctx, buf);
1192 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001193}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001194
1195void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001196yang_read_range(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001197{
Pavol Vican6b072512016-04-04 10:50:21 +02001198 if (typ->base != 0 && typ->base != LY_TYPE_DEC64) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001199 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001200 goto error;
1201 }
Pavol Vican6b072512016-04-04 10:50:21 +02001202 typ->base = LY_TYPE_DEC64;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001203 if (typ->type->info.dec64.range) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001204 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001205 goto error;
1206 }
1207 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1208 if (!typ->type->info.dec64.range) {
1209 LOGMEM;
1210 goto error;
1211 }
1212 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1213 return typ->type->info.dec64.range;
1214
1215error:
1216 free(value);
1217 return NULL;
1218}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001219
1220int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001221yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001222{
Radek Krejci8c3b4b62016-06-17 14:32:12 +02001223 unsigned int i;
1224
Pavol Vican6b072512016-04-04 10:50:21 +02001225 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1226 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001227 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001228 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001229 goto error;
1230 }
1231 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001232 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001233 goto error;
1234 }
1235 /* range check */
1236 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001237 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001238 goto error;
1239 }
1240 typ->type->info.dec64.dig = value;
Radek Krejci8c3b4b62016-06-17 14:32:12 +02001241 typ->type->info.dec64.div = 10;
1242 for (i = 1; i < value; i++) {
1243 typ->type->info.dec64.div *= 10;
1244 }
Pavol Vican07ea68d2016-02-25 12:01:37 +01001245 return EXIT_SUCCESS;
1246
1247error:
1248 return EXIT_FAILURE;
1249}
Pavol Vican79a763d2016-02-25 15:41:27 +01001250
Pavol Vican874715f2016-10-25 14:52:08 +02001251int
1252yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001253{
Pavol Vican874715f2016-10-25 14:52:08 +02001254 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001255
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001256 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001257 if (!value[0]) {
1258 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1259 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1260 free(value);
1261 goto error;
1262 }
1263
Pavol Vican79a763d2016-02-25 15:41:27 +01001264 enm->name = lydict_insert_zc(module->ctx, value);
1265
1266 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1267 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001268 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001269 goto error;
1270 }
1271
Pavol Vican874715f2016-10-25 14:52:08 +02001272 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001273 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001274 for (i = 0; i < j; i++) {
1275 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[j].name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001276 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001277 goto error;
1278 }
1279 }
1280
Pavol Vican874715f2016-10-25 14:52:08 +02001281 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001282
1283error:
Pavol Vican874715f2016-10-25 14:52:08 +02001284 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001285}
1286
1287int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001288yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001289{
1290 int i, j;
1291
1292 if (!assign) {
1293 /* assign value automatically */
1294 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001295 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001296 goto error;
1297 }
1298 enm->value = *value;
1299 enm->flags |= LYS_AUTOASSIGNED;
1300 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001301 } else if (typ->type->info.enums.enm == enm) {
1302 /* change value, which is assigned automatically, if first enum has value. */
1303 *value = typ->type->info.enums.enm[0].value;
1304 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001305 }
1306
1307 /* check that the value is unique */
1308 j = typ->type->info.enums.count-1;
1309 for (i = 0; i < j; i++) {
1310 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001311 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001312 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1313 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001314 goto error;
1315 }
1316 }
1317
1318 return EXIT_SUCCESS;
1319
1320error:
1321 return EXIT_FAILURE;
1322}
Pavol Vican9887c682016-02-29 11:32:01 +01001323
Pavol Vican59e8dee2016-10-25 15:29:38 +02001324int
1325yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001326{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001327 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001328
Pavol Vican59e8dee2016-10-25 15:29:38 +02001329 bit->name = lydict_insert_zc(module->ctx, value);
1330 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001331 free(value);
1332 goto error;
1333 }
Pavol Vican9887c682016-02-29 11:32:01 +01001334
Pavol Vican59e8dee2016-10-25 15:29:38 +02001335 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001336 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001337 for (i = 0; i < j; i++) {
Pavol Vican9887c682016-02-29 11:32:01 +01001338 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001339 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001340 goto error;
1341 }
1342 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001343 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001344
1345error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001346 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001347}
1348
1349int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001350yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001351{
1352 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001353
1354 if (!assign) {
1355 /* assign value automatically */
1356 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001357 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001358 goto error;
1359 }
1360 bit->pos = (uint32_t)*value;
1361 bit->flags |= LYS_AUTOASSIGNED;
1362 (*value)++;
1363 }
1364
1365 j = typ->type->info.bits.count - 1;
1366 /* check that the value is unique */
1367 for (i = 0; i < j; i++) {
1368 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001369 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 +01001370 goto error;
1371 }
1372 }
1373
Pavol Vican9887c682016-02-29 11:32:01 +01001374 return EXIT_SUCCESS;
1375
1376error:
1377 return EXIT_FAILURE;
1378}
Pavol Vican0df02b02016-03-01 10:28:50 +01001379
Pavol Vican3ad50f82016-12-04 15:00:36 +01001380int
1381yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001382{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001383 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001384 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001385 free(value);
1386 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001387 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001388 }
1389 aug->parent = parent;
1390 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001391 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001392}
Pavol Vican220e5a12016-03-03 14:19:43 +01001393
Pavol Vican4c90c642016-03-03 15:06:47 +01001394int
PavolVican75af21d2016-12-29 20:04:07 +01001395yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001396{
PavolVican75af21d2016-12-29 20:04:07 +01001397 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001398 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
Pavol Vican4c90c642016-03-03 15:06:47 +01001399 return EXIT_FAILURE;
1400 }
PavolVican75af21d2016-12-29 20:04:07 +01001401 dev->deviate = calloc(1, sizeof *dev->deviate);
1402 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1403 dev->deviate_size = 1;
Pavol Vican4c90c642016-03-03 15:06:47 +01001404 return EXIT_SUCCESS;
1405}
Pavol Vican85f12022016-03-05 16:30:35 +01001406
PavolVican75af21d2016-12-29 20:04:07 +01001407void *
1408yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican85f12022016-03-05 16:30:35 +01001409{
PavolVican75af21d2016-12-29 20:04:07 +01001410 struct lys_deviate *deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001411
PavolVican75af21d2016-12-29 20:04:07 +01001412 if (dev->deviate && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001413 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1414 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001415 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001416 }
PavolVican75af21d2016-12-29 20:04:07 +01001417 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1418 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
1419 if (!deviate) {
1420 LOGMEM;
1421 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001422 }
PavolVican75af21d2016-12-29 20:04:07 +01001423 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1424 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001425 }
PavolVican75af21d2016-12-29 20:04:07 +01001426 dev->deviate[dev->deviate_size].mod = mod;
1427 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001428}
1429
1430int
PavolVican75af21d2016-12-29 20:04:07 +01001431yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001432{
1433 const char **stritem;
1434
Pavol Vican85f12022016-03-05 16:30:35 +01001435 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001436 if (dev_target->nodetype == LYS_LEAFLIST) {
1437 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1438 } else if (dev_target->nodetype == LYS_LEAF) {
1439 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001440 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001441 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1442 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001443 goto error;
1444 }
1445
PavolVican75af21d2016-12-29 20:04:07 +01001446 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001447 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001448 if (!ly_strequal(*stritem, deviate->units, 1)) {
1449 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001450 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001451 goto error;
1452 }
1453 /* remove current units value of the target */
1454 lydict_remove(ctx, *stritem);
Pavol Vican4766aca2016-03-07 12:42:36 +01001455 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001456 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001457 /* check that there is no current value */
1458 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001459 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1460 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001461 goto error;
1462 }
1463 } else { /* replace */
1464 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001465 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1466 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001467 goto error;
1468 }
1469 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001470 /* remove current units value of the target ... */
1471 lydict_remove(ctx, *stritem);
1472
1473 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001474 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001475 }
1476
Pavol Vican85f12022016-03-05 16:30:35 +01001477 return EXIT_SUCCESS;
1478
1479error:
1480 return EXIT_FAILURE;
1481}
1482
1483int
PavolVican75af21d2016-12-29 20:04:07 +01001484yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001485{
Pavol Vican85f12022016-03-05 16:30:35 +01001486 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001487 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001488
1489 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001490 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001491 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1492 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001493 goto error;
1494 }
1495
PavolVican75af21d2016-12-29 20:04:07 +01001496 list = (struct lys_node_list *)dev_target;
1497 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001498 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001499 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
1500 if (!unique) {
Pavol Vican85f12022016-03-05 16:30:35 +01001501 LOGMEM;
1502 goto error;
1503 }
PavolVican75af21d2016-12-29 20:04:07 +01001504 list->unique = unique;
1505 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001506 }
1507
1508 return EXIT_SUCCESS;
1509
1510error:
1511 return EXIT_FAILURE;
1512}
1513
1514int
PavolVican75af21d2016-12-29 20:04:07 +01001515yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1516 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001517{
1518 struct lys_node *node;
1519 struct lys_node_choice *choice;
1520 struct lys_node_leaf *leaf;
1521 struct lys_node_leaflist *llist;
1522 int rc, i;
1523 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001524
Pavol Vican38321d02016-08-16 14:56:02 +02001525 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001526 if (dev_target->nodetype == LYS_CHOICE) {
1527 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001528 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1529 if (rc || !node) {
1530 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1531 goto error;
1532 }
PavolVican75af21d2016-12-29 20:04:07 +01001533 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001534 if (!choice->dflt || (choice->dflt != node)) {
1535 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1536 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1537 goto error;
1538 }
1539 } else { /* add or replace */
1540 choice->dflt = node;
1541 if (!choice->dflt) {
1542 /* default branch not found */
1543 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1544 goto error;
1545 }
1546 }
PavolVican75af21d2016-12-29 20:04:07 +01001547 } else if (dev_target->nodetype == LYS_LEAF) {
1548 leaf = (struct lys_node_leaf *)dev_target;
1549 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001550 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
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 /* remove value */
1556 lydict_remove(ctx, leaf->dflt);
1557 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001558 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001559 } else { /* add (already checked) and replace */
1560 /* remove value */
1561 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001562 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001563
1564 /* set new value */
1565 leaf->dflt = lydict_insert(ctx, value, u);
1566
1567 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001568 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001569 }
1570 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001571 llist = (struct lys_node_leaflist *)dev_target;
1572 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001573 /* find and remove the value in target list */
1574 for (i = 0; i < llist->dflt_size; i++) {
1575 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1576 /* match, remove the value */
1577 lydict_remove(llist->module->ctx, llist->dflt[i]);
1578 llist->dflt[i] = NULL;
1579 break;
1580 }
1581 }
1582 if (i == llist->dflt_size) {
1583 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1584 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1585 goto error;
1586 }
1587 } else {
1588 /* add or replace, anyway we place items into the deviate's list
1589 which propagates to the target */
1590 /* we just want to check that the value isn't already in the list */
1591 for (i = 0; i < llist->dflt_size; i++) {
1592 if (ly_strequal(llist->dflt[i], value, 1)) {
1593 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1594 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1595 goto error;
1596 }
1597 }
1598 /* store it in target node */
1599 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1600
1601 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001602 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001603 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001604 }
1605 }
1606
1607 return EXIT_SUCCESS;
1608error:
1609 return EXIT_FAILURE;
1610}
1611
Pavol Vican38321d02016-08-16 14:56:02 +02001612int
PavolVican75af21d2016-12-29 20:04:07 +01001613yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1614 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001615{
PavolVican75af21d2016-12-29 20:04:07 +01001616 int i;
1617 struct lys_node_leaflist *llist;
1618 const char **dflt;
1619
1620 /* check target node type */
1621 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1622 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1623 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1624 goto error;
1625 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1626 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1627 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1628 goto error;
1629 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1630 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1631 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001632 goto error;
1633 }
1634
PavolVican75af21d2016-12-29 20:04:07 +01001635 if (deviate->mod == LY_DEVIATE_ADD) {
1636 /* check that there is no current value */
1637 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1638 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1639 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1640 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1641 goto error;
1642 }
Pavol Vican85f12022016-03-05 16:30:35 +01001643
PavolVican75af21d2016-12-29 20:04:07 +01001644 /* check collision with mandatory/min-elements */
1645 if ((dev_target->flags & LYS_MAND_TRUE) ||
1646 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1647 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1648 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1649 "Adding the \"default\" statement is forbidden on %s statement.",
1650 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1651 goto error;
1652 }
1653 } else if (deviate->mod == LY_DEVIATE_RPL) {
1654 /* check that there was a value before */
1655 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1656 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1657 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1658 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1659 goto error;
1660 }
1661 }
Pavol Vican85f12022016-03-05 16:30:35 +01001662
PavolVican75af21d2016-12-29 20:04:07 +01001663 if (dev_target->nodetype == LYS_LEAFLIST) {
1664 /* reallocate default list in the target */
1665 llist = (struct lys_node_leaflist *)dev_target;
1666 if (deviate->mod == LY_DEVIATE_ADD) {
1667 /* reallocate (enlarge) the unique array of the target */
1668 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
1669 if (!dflt) {
1670 LOGMEM;
1671 goto error;
1672 }
1673 llist->dflt = dflt;
1674 } else if (deviate->mod == LY_DEVIATE_RPL) {
1675 /* reallocate (replace) the unique array of the target */
1676 for (i = 0; i < llist->dflt_size; i++) {
1677 lydict_remove(llist->module->ctx, llist->dflt[i]);
1678 }
1679 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
1680 if (!dflt) {
1681 LOGMEM;
1682 goto error;
1683 }
1684 llist->dflt = dflt;
1685 llist->dflt_size = 0;
1686 }
1687 }
1688
1689 for (i = 0; i < deviate->dflt_size; ++i) {
1690 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1691 goto error;
1692 }
1693 }
Pavol Vican85f12022016-03-05 16:30:35 +01001694
1695 return EXIT_SUCCESS;
1696
1697error:
1698 return EXIT_FAILURE;
1699}
1700
1701int
PavolVican75af21d2016-12-29 20:04:07 +01001702yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001703{
Radek Krejcie00d2312016-08-12 15:27:49 +02001704 struct lys_node *parent;
1705
Pavol Vican85f12022016-03-05 16:30:35 +01001706 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001707 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001708 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1709 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001710 goto error;
1711 }
1712
PavolVican75af21d2016-12-29 20:04:07 +01001713 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001714 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001715 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001716 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1717 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001718 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001719 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001720 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001721 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1722 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1723 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1724 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001725 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001726 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1727 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1728 goto error;
1729 }
Pavol Vican85f12022016-03-05 16:30:35 +01001730 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001731 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001732 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001733 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1734 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001735 goto error;
1736 }
Pavol Vican85f12022016-03-05 16:30:35 +01001737 }
1738
Pavol Vican85f12022016-03-05 16:30:35 +01001739 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001740 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001741
1742 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001743 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001744
Radek Krejcie00d2312016-08-12 15:27:49 +02001745 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001746 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001747 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1748 parent = parent->parent) {
1749 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1750 /* stop also on presence containers */
1751 break;
1752 }
1753 }
1754 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1755 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1756 if (lyp_check_mandatory_choice(parent)) {
1757 goto error;
1758 }
1759 }
1760
Pavol Vican85f12022016-03-05 16:30:35 +01001761 return EXIT_SUCCESS;
1762
1763error:
1764 return EXIT_FAILURE;
1765}
1766
1767int
PavolVican75af21d2016-12-29 20:04:07 +01001768yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001769{
Pavol Vican09adcc32016-08-25 10:51:36 +02001770 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001771
1772 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001773 if (dev_target->nodetype == LYS_LEAFLIST) {
1774 max = &((struct lys_node_leaflist *)dev_target)->max;
1775 min = &((struct lys_node_leaflist *)dev_target)->min;
1776 } else if (dev_target->nodetype == LYS_LIST) {
1777 max = &((struct lys_node_list *)dev_target)->max;
1778 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001779 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001780 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1781 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 +01001782 goto error;
1783 }
1784
PavolVican75af21d2016-12-29 20:04:07 +01001785 ui32val = (type) ? max : min;
1786 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001787 /* check that there is no current value */
1788 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001789 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1790 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001791 goto error;
1792 }
PavolVican75af21d2016-12-29 20:04:07 +01001793 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001794 /* unfortunately, there is no way to check reliably that there
1795 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001796 }
1797
1798 /* add (already checked) and replace */
1799 /* set new value specified in deviation */
1800 *ui32val = value;
1801
Pavol Vican09adcc32016-08-25 10:51:36 +02001802 /* check min-elements is smaller than max-elements */
1803 if (*max && *min > *max) {
1804 if (type) {
1805 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1806 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1807 } else {
1808 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1809 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1810 }
1811 goto error;
1812 }
1813
Pavol Vican85f12022016-03-05 16:30:35 +01001814 return EXIT_SUCCESS;
1815
1816error:
1817 return EXIT_FAILURE;
1818}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001819
1820int
PavolVican75af21d2016-12-29 20:04:07 +01001821yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1822 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001823{
PavolVican75af21d2016-12-29 20:04:07 +01001824 int i, j, erase_must = 1;
1825 struct lys_restr **trg_must, *must;
1826 uint8_t *trg_must_size, must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001827
PavolVican75af21d2016-12-29 20:04:07 +01001828 /* check target node type */
1829 switch (dev_target->nodetype) {
1830 case LYS_LEAF:
1831 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1832 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001833 break;
PavolVican75af21d2016-12-29 20:04:07 +01001834 case LYS_CONTAINER:
1835 trg_must = &((struct lys_node_container *)dev_target)->must;
1836 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1837 break;
1838 case LYS_LEAFLIST:
1839 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1840 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1841 break;
1842 case LYS_LIST:
1843 trg_must = &((struct lys_node_list *)dev_target)->must;
1844 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1845 break;
1846 case LYS_ANYXML:
1847 case LYS_ANYDATA:
1848 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1849 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1850 break;
1851 default:
1852 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1853 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1854 goto error;
1855 }
1856
1857 /* flag will be checked again, clear it for now */
1858 dev_target->flags &= ~LYS_VALID_DEP;
1859
1860 if (deviate->mod == LY_DEVIATE_ADD) {
1861 /* reallocate the must array of the target */
1862 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
1863 if (!must) {
1864 LOGMEM;
1865 goto error;
1866 }
1867 *trg_must = must;
1868 must_size = *trg_must_size;
1869 for (i = 0; i < deviate->must_size; ++i) {
1870 (*trg_must)[must_size].expr = deviate->must[i].expr;
1871 (*trg_must)[must_size].dsc = deviate->must[i].dsc;
1872 (*trg_must)[must_size].ref = deviate->must[i].ref;
1873 (*trg_must)[must_size].emsg = deviate->must[i].emsg;
1874 (*trg_must)[must_size].eapptag = deviate->must[i].eapptag;
1875 ++must_size;
1876 }
1877 free(deviate->must);
1878 deviate->must = &must[*trg_must_size];
1879 *trg_must_size = must_size;
1880 erase_must = 0;
1881 } else if (deviate->mod == LY_DEVIATE_DEL) {
1882 /* find must to delete, we are ok with just matching conditions */
1883 for (j = 0; j < deviate->must_size; ++j) {
1884 for (i = 0; i < *trg_must_size; i++) {
1885 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1886 /* we have a match, free the must structure ... */
1887 lys_restr_free(module->ctx, &((*trg_must)[i]));
1888 /* ... and maintain the array */
1889 (*trg_must_size)--;
1890 if (i != *trg_must_size) {
1891 (*trg_must)[i].expr = (*trg_must)[*trg_must_size].expr;
1892 (*trg_must)[i].dsc = (*trg_must)[*trg_must_size].dsc;
1893 (*trg_must)[i].ref = (*trg_must)[*trg_must_size].ref;
1894 (*trg_must)[i].eapptag = (*trg_must)[*trg_must_size].eapptag;
1895 (*trg_must)[i].emsg = (*trg_must)[*trg_must_size].emsg;
1896 }
1897 if (!(*trg_must_size)) {
1898 free(*trg_must);
1899 *trg_must = NULL;
1900 } else {
1901 (*trg_must)[*trg_must_size].expr = NULL;
1902 (*trg_must)[*trg_must_size].dsc = NULL;
1903 (*trg_must)[*trg_must_size].ref = NULL;
1904 (*trg_must)[*trg_must_size].eapptag = NULL;
1905 (*trg_must)[*trg_must_size].emsg = NULL;
1906 }
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 Vicane92421d2016-03-08 10:12:33 +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;
2030error:
2031 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 }
2039 return EXIT_FAILURE;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002040}
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 Vican9b89dda2016-03-09 15:36:55 +01002045{
Pavol Vicanec423c92016-10-24 21:33:43 +02002046 struct lys_submodule *submodule;
2047 struct lys_module *module;
Pavol Vican55870412016-03-10 12:36:21 +01002048 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002049 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002050 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002051
Pavol Vicanec423c92016-10-24 21:33:43 +02002052 str = lydict_insert_zc(trg->ctx, value);
Pavol Vicanfda8c802016-12-03 02:00:42 +01002053 if (trg->type) {
Pavol Vicanec423c92016-10-24 21:33:43 +02002054 submodule = (struct lys_submodule *)trg;
2055 module = ((struct lys_submodule *)trg)->belongsto;
2056 } else {
2057 submodule = NULL;
2058 module = trg;
2059 }
Pavol Vicane024ab72016-07-27 14:27:43 +02002060 rc = lyp_check_include(module, submodule, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002061 if (!rc) {
2062 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002063 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
Radek Krejci4dcd3392016-06-22 10:28:40 +02002064 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002065 } else if (rc == -1) {
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002066 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002067 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002068
Pavol Vicanec423c92016-10-24 21:33:43 +02002069 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002070 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002071}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002072
2073int
Pavol Vican0adf01d2016-03-22 12:29:33 +01002074yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value)
Pavol Vicanf4717e62016-03-16 11:30:01 +01002075{
2076 char *prefix;
2077 char *identif;
2078 const char *ns = NULL;
2079 int i;
2080
Pavol Vicanf4717e62016-03-16 11:30:01 +01002081 /* check to the same pointer */
2082 if (data_node != actual) {
2083 return EXIT_SUCCESS;
2084 }
2085
Pavol Vicana302aa62016-03-17 10:45:35 +01002086 prefix = strdup(value);
2087 if (!prefix) {
2088 LOGMEM;
2089 goto error;
2090 }
2091 /* find prefix anf identificator*/
2092 identif = strchr(prefix, ':');
Pavol Vicanfbd02782016-08-29 11:14:45 +02002093 if (!identif) {
2094 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, prefix);
2095 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The extension must have prefix.");
2096 goto error;
2097 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002098 *identif = '\0';
2099 identif++;
2100
Pavol Vicanf4717e62016-03-16 11:30:01 +01002101 for(i = 0; i < module->imp_size; ++i) {
2102 if (!strcmp(module->imp[i].prefix, prefix)) {
2103 ns = module->imp[i].module->ns;
2104 break;
2105 }
2106 }
Pavol Vican1ff1b7b2016-04-07 09:51:49 +02002107 if (!ns && !strcmp(module->prefix, prefix)) {
2108 ns = (module->type) ? ((struct lys_submodule *)module)->belongsto->ns : module->ns;
2109 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002110 if (ns && !strcmp(ns, LY_NSNACM)) {
2111 if (!strcmp(identif, "default-deny-write")) {
2112 data_node->nacm |= LYS_NACM_DENYW;
2113 } else if (!strcmp(identif, "default-deny-all")) {
2114 data_node->nacm |= LYS_NACM_DENYA;
2115 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01002116 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, identif);
Pavol Vicana302aa62016-03-17 10:45:35 +01002117 goto error;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002118 }
2119 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002120 free(prefix);
Pavol Vicanf4717e62016-03-16 11:30:01 +01002121 return EXIT_SUCCESS;
Pavol Vicana302aa62016-03-17 10:45:35 +01002122
2123error:
2124 free(prefix);
2125 return EXIT_FAILURE;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002126}
2127
2128void
2129nacm_inherit(struct lys_module *module)
2130{
Pavol Vican10ffba52016-04-04 12:21:22 +02002131 struct lys_node *next, *elem, *tmp_node, *tmp_child;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002132
2133 LY_TREE_DFS_BEGIN(module->data, next, elem) {
Pavol Vican10ffba52016-04-04 12:21:22 +02002134 tmp_node = NULL;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002135 if (elem->parent) {
2136 switch (elem->nodetype) {
Pavol Vican10ffba52016-04-04 12:21:22 +02002137 case LYS_GROUPING:
2138 /* extension nacm not inherited*/
2139 break;
2140 case LYS_CHOICE:
2141 case LYS_ANYXML:
Radek Krejcibf2abff2016-08-23 15:51:52 +02002142 case LYS_ANYDATA:
Pavol Vican10ffba52016-04-04 12:21:22 +02002143 case LYS_USES:
2144 if (elem->parent->nodetype != LYS_GROUPING) {
2145 elem->nacm |= elem->parent->nacm;
2146 }
2147 break;
2148 case LYS_CONTAINER:
2149 case LYS_LIST:
2150 case LYS_CASE:
2151 case LYS_NOTIF:
2152 case LYS_RPC:
2153 case LYS_INPUT:
2154 case LYS_OUTPUT:
2155 case LYS_AUGMENT:
2156 elem->nacm |= elem->parent->nacm;
2157 break;
2158 case LYS_LEAF:
2159 case LYS_LEAFLIST:
2160 tmp_node = elem;
2161 tmp_child = elem->child;
2162 elem->child = NULL;
2163 default:
2164 break;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002165 }
2166 }
2167 LY_TREE_DFS_END(module->data, next, elem);
Pavol Vican10ffba52016-04-04 12:21:22 +02002168 if (tmp_node) {
2169 tmp_node->child = tmp_child;
2170 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002171 }
2172}
Pavol Vican4fb66c92016-03-17 10:32:27 +01002173
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002174int
Pavol Vican1dac40c2016-09-28 11:39:26 +02002175store_flags(struct lys_node *node, uint8_t flags, int config_opt)
Pavol Vican4fb66c92016-03-17 10:32:27 +01002176{
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002177 struct lys_node *elem;
2178
Pavol Vican1dac40c2016-09-28 11:39:26 +02002179 node->flags |= (config_opt == CONFIG_IGNORE) ? flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET)): flags;
2180 if (config_opt == CONFIG_INHERIT_ENABLE) {
2181 if (!(node->flags & LYS_CONFIG_MASK)) {
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002182 /* get config flag from parent */
Radek Krejcif71f48f2016-10-25 16:37:24 +02002183 if (node->parent) {
2184 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002185 } else {
2186 /* default config is true */
2187 node->flags |= LYS_CONFIG_W;
2188 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002189 } else {
Pavol Vican1dac40c2016-09-28 11:39:26 +02002190 /* do we even care about config flags? */
2191 for (elem = node; elem && !(elem->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT | LYS_RPC)); elem = elem->parent);
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002192
Pavol Vican1dac40c2016-09-28 11:39:26 +02002193 if (!elem && (node->flags & LYS_CONFIG_W) && node->parent && (node->parent->flags & LYS_CONFIG_R)) {
2194 LOGVAL(LYE_INARG, LY_VLOG_LYS, node, "true", "config");
2195 LOGVAL(LYE_SPEC, LY_VLOG_LYS, node, "State nodes cannot have configuration nodes as children.");
2196 return EXIT_FAILURE;
2197 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002198 }
2199 }
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002200
2201 return EXIT_SUCCESS;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002202}
Pavol Vican8e7110b2016-03-22 17:00:26 +01002203
Pavol Vicanec598812016-11-30 14:13:38 +01002204int
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002205store_config_flag(struct lys_node *node, int config_opt)
2206{
Pavol Vicanec598812016-11-30 14:13:38 +01002207 int ret = config_opt;
2208
2209 switch (node->nodetype) {
2210 case LYS_CONTAINER:
2211 case LYS_LEAF:
2212 case LYS_LEAFLIST:
2213 case LYS_LIST:
2214 case LYS_CHOICE:
2215 case LYS_ANYDATA:
2216 case LYS_ANYXML:
2217 if (config_opt == CONFIG_IGNORE) {
2218 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
2219 } else if (config_opt == CONFIG_INHERIT_ENABLE) {
2220 if (!(node->flags & LYS_CONFIG_MASK)) {
2221 /* get config flag from parent */
2222 if (node->parent) {
2223 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2224 } else {
2225 /* default config is true */
2226 node->flags |= LYS_CONFIG_W;
2227 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002228 }
2229 }
Pavol Vicanec598812016-11-30 14:13:38 +01002230 break;
2231 case LYS_CASE:
2232 if (config_opt == CONFIG_INHERIT_ENABLE) {
2233 if (!(node->flags & LYS_CONFIG_MASK)) {
2234 /* get config flag from parent */
2235 if (node->parent) {
2236 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2237 } else {
2238 /* default config is true */
2239 node->flags |= LYS_CONFIG_W;
2240 }
2241 }
2242 }
2243 break;
2244 case LYS_RPC:
2245 case LYS_ACTION:
2246 case LYS_NOTIF:
2247 ret = CONFIG_IGNORE;
2248 break;
2249 default:
2250 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002251 }
Pavol Vicanec598812016-11-30 14:13:38 +01002252
2253 return ret;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002254}
2255
Pavol Vican9d50a772016-10-14 22:23:36 +02002256int
2257yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2258 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002259{
Pavol Vican9d50a772016-10-14 22:23:36 +02002260 unsigned int size;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002261 YY_BUFFER_STATE bp;
Pavol Vican802af1e2016-03-23 20:42:26 +01002262 yyscan_t scanner = NULL;
Pavol Vican082afd02016-10-25 12:39:15 +02002263 int ret = EXIT_SUCCESS, remove_import = 1;
2264 struct lys_module *trg;
Pavol Vican1938d882016-04-10 13:36:31 +02002265
Pavol Vican9d50a772016-10-14 22:23:36 +02002266 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican1938d882016-04-10 13:36:31 +02002267 yylex_init(&scanner);
2268 bp = yy_scan_buffer((char *)data, size, scanner);
2269 yy_switch_to_buffer(bp, scanner);
Pavol Vican082afd02016-10-25 12:39:15 +02002270 if (yyparse(scanner, NULL, module, submodule, unres, node, &remove_import)) {
2271 if (remove_import) {
2272 trg = (submodule) ? (struct lys_module *)submodule : module;
2273 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2274 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2275 trg->inc_size = 0;
2276 trg->imp_size = 0;
2277 }
Pavol Vican1938d882016-04-10 13:36:31 +02002278 ret = EXIT_FAILURE;
2279 }
2280 yy_delete_buffer(bp, scanner);
2281 yylex_destroy(scanner);
2282 return ret;
2283}
2284
Pavol Vican8e7110b2016-03-22 17:00:26 +01002285struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002286yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002287{
2288
Pavol Vican10ffba52016-04-04 12:21:22 +02002289 struct lys_module *tmp_module, *module = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002290 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002291 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002292
2293 unres = calloc(1, sizeof *unres);
2294 if (!unres) {
2295 LOGMEM;
2296 goto error;
2297 }
2298
2299 module = calloc(1, sizeof *module);
2300 if (!module) {
2301 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002302 goto error;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002303 }
2304
2305 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002306 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002307 module->type = 0;
2308 module->implemented = (implement ? 1 : 0);
2309
Pavol Vican9d50a772016-10-14 22:23:36 +02002310 if (yang_parse_mem(module, NULL, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002311 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002312 goto error;
2313 }
2314
2315 if (yang_check_sub_module(module, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002316 goto error;
2317 }
2318
2319 if (module && unres->count && resolve_unres_schema(module, unres)) {
2320 goto error;
2321 }
2322
2323 if (revision) {
2324 /* check revision of the parsed model */
2325 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2326 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2327 module->name, module->rev[0].date, revision);
2328 goto error;
2329 }
2330 }
2331
Pavol Vican10ffba52016-04-04 12:21:22 +02002332 tmp_module = module;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002333 if (lyp_ctx_add_module(&module)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002334 goto error;
2335 }
2336
Pavol Vican10ffba52016-04-04 12:21:22 +02002337 if (module == tmp_module) {
2338 nacm_inherit(module);
2339 }
2340
Radek Krejci27fe55e2016-09-13 17:13:35 +02002341 if (module->deviation_size && !module->implemented) {
2342 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2343 /* deviations always causes target to be made implemented,
2344 * but augents and leafrefs not, so we have to apply them now */
2345 if (lys_set_implemented(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002346 goto error;
2347 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002348 }
2349
Pavol Vican8e7110b2016-03-22 17:00:26 +01002350 unres_schema_free(NULL, &unres);
2351 LOGVRB("Module \"%s\" successfully parsed.", module->name);
2352 return module;
2353
2354error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002355 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002356 unres_schema_free(module, &unres);
2357 if (!module || !module->name) {
2358 free(module);
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002359 if (ly_vecode != LYVE_SUBMODULE) {
2360 LOGERR(ly_errno, "Module parsing failed.");
2361 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002362 return NULL;
2363 }
2364
2365 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002366
2367 lys_sub_module_remove_devs_augs(module);
2368 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002369 return NULL;
2370}
2371
2372struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002373yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002374{
2375 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002376 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002377
2378 submodule = calloc(1, sizeof *submodule);
2379 if (!submodule) {
2380 LOGMEM;
2381 goto error;
2382 }
2383
2384 submodule->ctx = module->ctx;
2385 submodule->type = 1;
2386 submodule->belongsto = module;
2387
Pavol Vican9d50a772016-10-14 22:23:36 +02002388 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002389 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002390 goto error;
2391 }
2392
2393 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002394 goto error;
2395 }
2396
Pavol Vican8e7110b2016-03-22 17:00:26 +01002397 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002398 return submodule;
2399
2400error:
2401 /* cleanup */
2402 unres_schema_free((struct lys_module *)submodule, &unres);
2403
2404 if (!submodule || !submodule->name) {
2405 free(submodule);
2406 LOGERR(ly_errno, "Submodule parsing failed.");
2407 return NULL;
2408 }
2409
2410 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2411
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002412 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2413 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002414 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002415 return NULL;
2416}
Pavol Vican8760bb72016-04-07 09:44:01 +02002417
2418static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002419read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2420{
2421 int k = 0, j;
2422
2423 while (in_index < size) {
2424 if (input[in_index] == ' ') {
2425 k++;
2426 } else if (input[in_index] == '\t') {
2427 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2428 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002429 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2430 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2431 k += 8;
2432 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002433 } else {
2434 break;
2435 }
2436 ++in_index;
2437 if (k >= indent) {
2438 for (j = k - indent; j > 0; --j) {
2439 output[*out_index] = ' ';
2440 ++(*out_index);
2441 }
2442 break;
2443 }
2444 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002445 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002446}
2447
2448char *
Pavol Vican3f598892016-09-28 15:41:07 +02002449yang_read_string(const char *input, char *output, int size, int offset, int indent, int version) {
2450 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002451
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002452 while (i < size) {
2453 switch (input[i]) {
2454 case '\n':
2455 out_index -= space;
2456 output[out_index] = '\n';
2457 space = 0;
2458 i = read_indent(input, indent, size, i + 1, &out_index, output);
2459 break;
2460 case ' ':
2461 case '\t':
2462 output[out_index] = input[i];
2463 ++space;
2464 break;
2465 case '\\':
2466 if (input[i + 1] == 'n') {
2467 out_index -= space;
2468 output[out_index] = '\n';
2469 space = 0;
2470 i = read_indent(input, indent, size, i + 2, &out_index, output);
2471 } else if (input[i + 1] == 't') {
2472 output[out_index] = '\t';
2473 ++i;
2474 ++space;
2475 } else if (input[i + 1] == '\\') {
2476 output[out_index] = '\\';
2477 ++i;
2478 } else if ((i + 1) != size && input[i + 1] == '"') {
2479 output[out_index] = '"';
2480 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002481 } else {
Pavol Vican677b0132016-08-09 15:44:58 +02002482 if (version < 2) {
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002483 output[out_index] = input[i];
Pavol Vican677b0132016-08-09 15:44:58 +02002484 } else {
2485 /* YANG 1.1 backslash must not be followed by any other character */
2486 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
Pavol Vican3f598892016-09-28 15:41:07 +02002487 return NULL;
Pavol Vican677b0132016-08-09 15:44:58 +02002488 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002489 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002490 break;
2491 default:
2492 output[out_index] = input[i];
2493 space = 0;
2494 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002495 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002496 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002497 ++out_index;
2498 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002499 output[out_index] = '\0';
2500 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002501 output = realloc(output, out_index + 1);
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002502 if (!output) {
2503 LOGMEM;
Pavol Vican3f598892016-09-28 15:41:07 +02002504 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002505 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002506 }
Pavol Vican3f598892016-09-28 15:41:07 +02002507 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002508}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002509
2510/* free function */
2511
Pavol Vican7313fc02016-11-14 01:10:31 +01002512static void yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
2513{
2514 struct yang_type *stype = (struct yang_type *)type->der;
2515 int i;
2516
2517 if (!stype) {
2518 return ;
2519 }
2520 lydict_remove(ctx, stype->name);
2521 type->base = stype->base;
Pavol Vicanb60a1d12016-12-03 01:56:55 +01002522 if (type->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
Pavol Vican7313fc02016-11-14 01:10:31 +01002523 for (i = 0; i < type->info.ident.count; ++i) {
2524 free(type->info.ident.ref[i]);
2525 }
2526 }
2527 lys_type_free(ctx, type);
Pavol Vican36aff862016-11-26 17:07:05 +01002528 type->base = LY_TYPE_DER;
Pavol Vican7313fc02016-11-14 01:10:31 +01002529 free(stype);
2530}
2531
2532static void
2533yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint8_t start, uint8_t size)
2534{
2535 uint8_t i;
2536
2537 assert(ctx);
2538 if (!tpdf) {
2539 return;
2540 }
2541
2542 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002543 lydict_remove(ctx, tpdf[i].name);
2544 lydict_remove(ctx, tpdf[i].dsc);
2545 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002546
Pavol Vicancee10802016-11-22 15:48:35 +01002547 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002548
Pavol Vicancee10802016-11-22 15:48:35 +01002549 lydict_remove(ctx, tpdf[i].units);
2550 lydict_remove(ctx, tpdf[i].dflt);
Pavol Vican7313fc02016-11-14 01:10:31 +01002551 }
2552}
2553
Pavol Vican1cc4e192016-10-24 16:38:31 +02002554static void
2555yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2556{
2557 uint8_t i;
2558
2559 for (i = start; i < size; ++i){
2560 free((char *)imp[i].module);
2561 lydict_remove(ctx, imp[i].prefix);
2562 lydict_remove(ctx, imp[i].dsc);
2563 lydict_remove(ctx, imp[i].ref);
2564 }
2565}
2566
Pavol Vicanec423c92016-10-24 21:33:43 +02002567static void
2568yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2569{
2570 uint8_t i;
2571
2572 for (i = start; i < size; ++i){
2573 free((char *)inc[i].submodule);
2574 lydict_remove(ctx, inc[i].dsc);
2575 lydict_remove(ctx, inc[i].ref);
2576 }
2577}
2578
Pavol Vican36e27272016-11-22 15:47:28 +01002579static void
2580yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2581{
2582 uint32_t i;
2583 uint8_t j;
2584
2585 /* free base name */
2586 for (i = start; i < size; ++i) {
2587 for (j = 0; j < ident[i].base_size; ++j) {
2588 free(ident[i].base[j]);
2589 }
2590 }
2591}
2592
Pavol Vican05810b62016-11-23 14:07:22 +01002593static void
2594yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2595{
2596 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2597 free(grp->tpdf);
2598}
2599
2600static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002601yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2602{
2603 uint8_t i;
2604
2605 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2606 free(cont->tpdf);
2607 lydict_remove(ctx, cont->presence);
2608
Pavol Vicanfda8c802016-12-03 02:00:42 +01002609 for (i = 0; i < cont->must_size; ++i) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002610 lys_restr_free(ctx, &cont->must[i]);
2611 }
2612 free(cont->must);
2613
2614 lys_when_free(ctx, cont->when);
2615}
2616
2617static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002618yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2619{
2620 uint8_t i;
2621
2622 for (i = 0; i < leaf->must_size; i++) {
2623 lys_restr_free(ctx, &leaf->must[i]);
2624 }
2625 free(leaf->must);
2626
2627 lys_when_free(ctx, leaf->when);
2628
2629 yang_type_free(ctx, &leaf->type);
2630 lydict_remove(ctx, leaf->units);
2631 lydict_remove(ctx, leaf->dflt);
2632}
2633
2634static void
Pavol Vican36aff862016-11-26 17:07:05 +01002635yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2636{
2637 uint8_t i;
2638
2639 for (i = 0; i < leaflist->must_size; i++) {
2640 lys_restr_free(ctx, &leaflist->must[i]);
2641 }
2642 free(leaflist->must);
2643
2644 for (i = 0; i < leaflist->dflt_size; i++) {
2645 lydict_remove(ctx, leaflist->dflt[i]);
2646 }
2647 free(leaflist->dflt);
2648
2649 lys_when_free(ctx, leaflist->when);
2650
2651 yang_type_free(ctx, &leaflist->type);
2652 lydict_remove(ctx, leaflist->units);
2653}
2654
2655static void
Pavol Vicand8136a42016-11-27 13:28:04 +01002656yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
2657{
2658 uint8_t i;
2659
2660 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
2661 free(list->tpdf);
2662
2663 for (i = 0; i < list->must_size; ++i) {
2664 lys_restr_free(ctx, &list->must[i]);
2665 }
2666 free(list->must);
2667
2668 lys_when_free(ctx, list->when);
2669
2670 for (i = 0; i < list->unique_size; ++i) {
2671 free(list->unique[i].expr);
2672 }
2673 free(list->unique);
2674
2675 free(list->keys);
2676}
2677
2678static void
Pavol Vican36ace102016-11-28 11:46:59 +01002679yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
2680{
2681 free(choice->dflt);
2682 lys_when_free(ctx, choice->when);
2683}
2684
2685static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002686yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
2687{
2688 uint8_t i;
2689
2690 for (i = 0; i < anydata->must_size; ++i) {
2691 lys_restr_free(ctx, &anydata->must[i]);
2692 }
2693 free(anydata->must);
2694
2695 lys_when_free(ctx, anydata->when);
2696}
2697
2698static void
Pavol Vican78729392016-11-28 17:18:22 +01002699yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
2700{
2701 uint8_t i;
2702
2703 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
2704 free(inout->tpdf);
2705
2706 for (i = 0; i < inout->must_size; ++i) {
2707 lys_restr_free(ctx, &inout->must[i]);
2708 }
2709 free(inout->must);
2710}
2711
2712static void
Pavol Vican29bf8802016-11-28 20:44:57 +01002713yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
2714{
2715 uint8_t i;
2716
2717 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
2718 free(notif->tpdf);
2719
2720 for (i = 0; i < notif->must_size; ++i) {
2721 lys_restr_free(ctx, &notif->must[i]);
2722 }
2723 free(notif->must);
2724}
2725
2726static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002727yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
2728{
2729 int i, j;
2730
2731 for (i = 0; i < uses->refine_size; i++) {
2732 lydict_remove(ctx, uses->refine[i].target_name);
2733 lydict_remove(ctx, uses->refine[i].dsc);
2734 lydict_remove(ctx, uses->refine[i].ref);
2735
2736 for (j = 0; j < uses->refine[i].must_size; j++) {
2737 lys_restr_free(ctx, &uses->refine[i].must[j]);
2738 }
2739 free(uses->refine[i].must);
2740
2741 for (j = 0; j < uses->refine[i].dflt_size; j++) {
2742 lydict_remove(ctx, uses->refine[i].dflt[j]);
2743 }
2744 free(uses->refine[i].dflt);
2745
2746 if (uses->refine[i].target_type & LYS_CONTAINER) {
2747 lydict_remove(ctx, uses->refine[i].mod.presence);
2748 }
2749 }
2750 free(uses->refine);
2751
2752 lys_when_free(ctx, uses->when);
2753}
2754
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002755static void
Pavol Vican05810b62016-11-23 14:07:22 +01002756yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
2757{
2758 struct lys_node *tmp, *child, *sibling;
2759
2760 if (!node) {
2761 return;
2762 }
2763 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01002764
2765 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002766 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01002767 sibling = tmp->next;
2768 /* common part */
2769 lydict_remove(ctx, tmp->name);
2770 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01002771 lys_iffeature_free(tmp->iffeature, tmp->iffeature_size);
2772 lydict_remove(ctx, tmp->dsc);
2773 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01002774 }
2775
2776 switch (tmp->nodetype) {
2777 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01002778 case LYS_RPC:
2779 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01002780 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
2781 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002782 case LYS_CONTAINER:
2783 yang_free_container(ctx, (struct lys_node_container *)tmp);
2784 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01002785 case LYS_LEAF:
2786 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
2787 break;
Pavol Vican36aff862016-11-26 17:07:05 +01002788 case LYS_LEAFLIST:
2789 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
2790 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01002791 case LYS_LIST:
2792 yang_free_list(ctx, (struct lys_node_list *)tmp);
2793 break;
Pavol Vican36ace102016-11-28 11:46:59 +01002794 case LYS_CHOICE:
2795 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
2796 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01002797 case LYS_CASE:
2798 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when);
2799 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01002800 case LYS_ANYXML:
2801 case LYS_ANYDATA:
2802 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
2803 break;
Pavol Vican78729392016-11-28 17:18:22 +01002804 case LYS_INPUT:
2805 case LYS_OUTPUT:
2806 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
2807 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01002808 case LYS_NOTIF:
2809 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
2810 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01002811 case LYS_USES:
2812 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
2813 break;
Pavol Vican05810b62016-11-23 14:07:22 +01002814 default:
2815 break;
2816 }
2817
2818 yang_free_nodes(ctx, child);
2819 free(tmp);
2820 tmp = sibling;
2821 }
2822}
2823
Pavol Vican3ad50f82016-12-04 15:00:36 +01002824static void
2825yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
2826{
2827 lydict_remove(ctx, aug->target_name);
2828 lydict_remove(ctx, aug->dsc);
2829 lydict_remove(ctx, aug->ref);
2830
2831 lys_iffeature_free(aug->iffeature, aug->iffeature_size);
2832 lys_when_free(ctx, aug->when);
2833 yang_free_nodes(ctx, aug->child);
2834}
2835
PavolVican75af21d2016-12-29 20:04:07 +01002836static void
2837yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
2838{
2839 uint i, j;
2840
2841 for (i = index; i < dev->deviate_size; ++i) {
2842 lydict_remove(ctx, dev->deviate[i].units);
2843
2844 if (dev->deviate[i].type) {
2845 yang_type_free(ctx, dev->deviate[i].type);
2846 }
2847
2848 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
2849 lydict_remove(ctx, dev->deviate[i].dflt[j]);
2850 }
2851 free(dev->deviate[i].dflt);
2852
2853 for (j = 0; j < dev->deviate[i].must_size; ++j) {
2854 lys_restr_free(ctx, &dev->deviate[i].must[j]);
2855 }
2856 free(dev->deviate[i].must);
2857
2858 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
2859 free(dev->deviate[i].unique[j].expr);
2860 }
2861 free(dev->deviate[i].unique);
2862 }
2863}
2864
Pavol Vican7313fc02016-11-14 01:10:31 +01002865/* free common item from module and submodule */
2866static void
Pavol Vican05810b62016-11-23 14:07:22 +01002867free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01002868{
PavolVican75af21d2016-12-29 20:04:07 +01002869 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002870 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
2871 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01002872 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01002873 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01002874 for (i = 0; i < module->augment_size; ++i) {
2875 yang_free_augment(module->ctx, &module->augment[i]);
2876 }
2877 module->augment_size = 0;
2878 for (i = 0; i < module->deviation_size; ++i) {
2879 yang_free_deviate(module->ctx, &module->deviation[i], 0);
2880 free(module->deviation[i].deviate);
2881 }
2882 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01002883}
2884
Pavol Vican1cc4e192016-10-24 16:38:31 +02002885/* check function*/
2886
2887int
Pavol Vicanec423c92016-10-24 21:33:43 +02002888yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02002889{
2890 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02002891 struct lys_include *inc;
2892 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02002893 size_t size;
2894 char *s;
2895
2896 imp = module->imp;
2897 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02002898 inc = module->inc;
2899 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02002900
2901 if (imp_size) {
2902 size = (imp_size * sizeof *module->imp) + sizeof(void*);
2903 module->imp_size = 0;
2904 module->imp = calloc(1, size);
2905 if (!module->imp) {
2906 LOGMEM;
2907 goto error;
2908 }
2909 /* set stop block for possible realloc */
2910 module->imp[imp_size].module = (void*)0x1;
Pavol Vicanec423c92016-10-24 21:33:43 +02002911 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02002912
Pavol Vicanec423c92016-10-24 21:33:43 +02002913 if (inc_size) {
2914 size = (inc_size * sizeof *module->inc) + sizeof(void*);
2915 module->inc_size = 0;
2916 module->inc = calloc(1, size);
2917 if (!module->inc) {
2918 LOGMEM;
2919 goto error;
2920 }
2921 /* set stop block for possible realloc */
2922 module->inc[inc_size].submodule = (void*)0x1;
Pavol Vican1cc4e192016-10-24 16:38:31 +02002923 }
2924
2925 for (i = 0; i < imp_size; ++i) {
2926 s = (char *) imp[i].module;
2927 imp[i].module = NULL;
2928 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s)) {
2929 ++i;
2930 goto error;
2931 }
2932 }
Pavol Vicanec423c92016-10-24 21:33:43 +02002933 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01002934 s = (char *) inc[j].submodule;
2935 inc[j].submodule = NULL;
2936 if (yang_fill_include(module, s, &inc[j], unres)) {
2937 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02002938 goto error;
2939 }
2940 }
2941 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002942 free(imp);
2943
2944 return EXIT_SUCCESS;
2945
2946error:
2947 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02002948 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002949 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02002950 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002951 return EXIT_FAILURE;
2952}
Pavol Vican7313fc02016-11-14 01:10:31 +01002953
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01002954static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01002955yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01002956{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01002957 struct lys_iffeature *iffeature;
2958 uint8_t *ptr_size, size, i;
2959 char *s;
2960 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01002961
Pavol Vicandf9a95c2016-12-02 23:34:51 +01002962 switch (type) {
2963 case FEATURE_KEYWORD:
2964 iffeature = ((struct lys_feature *)parent)->iffeature;
2965 size = ((struct lys_feature *)parent)->iffeature_size;
2966 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
2967 parent_is_feature = 1;
2968 break;
2969 case IDENTITY_KEYWORD:
2970 iffeature = ((struct lys_ident *)parent)->iffeature;
2971 size = ((struct lys_ident *)parent)->iffeature_size;
2972 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
2973 break;
2974 case ENUM_KEYWORD:
2975 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
2976 size = ((struct lys_type_enum *)ptr)->iffeature_size;
2977 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
2978 break;
2979 case BIT_KEYWORD:
2980 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
2981 size = ((struct lys_type_bit *)ptr)->iffeature_size;
2982 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
2983 break;
2984 case REFINE_KEYWORD:
2985 iffeature = ((struct lys_refine *)ptr)->iffeature;
2986 size = ((struct lys_refine *)ptr)->iffeature_size;
2987 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
2988 break;
2989 default:
2990 iffeature = ((struct lys_node *)parent)->iffeature;
2991 size = ((struct lys_node *)parent)->iffeature_size;
2992 ptr_size = &((struct lys_node *)parent)->iffeature_size;
2993 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01002994 }
2995
Pavol Vicandf9a95c2016-12-02 23:34:51 +01002996 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01002997 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01002998 s = (char *)iffeature[i].features;
2999 iffeature[i].features = NULL;
3000 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3001 *ptr_size = size;
3002 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003003 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003004 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003005 }
3006
3007 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003008}
3009
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003010static int
3011yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3012{
3013 uint size, i;
3014 int rc;
3015 struct lys_ident **ref;
3016 const char *value;
3017 char *expr;
3018
3019 ref = type->info.ident.ref;
3020 size = type->info.ident.count;
3021 type->info.ident.count = 0;
3022 type->info.ident.ref = NULL;
3023 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3024
3025 for (i = 0; i < size; ++i) {
3026 expr = (char *)ref[i];
3027 /* store in the JSON format */
3028 value = transform_schema2json(module, expr);
3029 free(expr);
3030
3031 if (!value) {
3032 goto error;
3033 }
3034 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3035 lydict_remove(module->ctx, value);
3036
3037 if (rc == -1) {
3038 goto error;
3039 }
3040 }
3041 free(ref);
3042
3043 return EXIT_SUCCESS;
3044error:
3045 for (i = i+1; i < size; ++i) {
3046 free(ref[i]);
3047 }
3048 free(ref);
3049 return EXIT_FAILURE;
3050}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003051
Pavol Vican7313fc02016-11-14 01:10:31 +01003052int
3053yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3054{
3055 struct lys_tpdf *tpdf;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003056 uint8_t j, i, tpdf_size, *ptr_tpdf_size;
3057 struct yang_type *stype;
Pavol Vican7313fc02016-11-14 01:10:31 +01003058
3059 if (!parent) {
3060 tpdf = module->tpdf;
3061 ptr_tpdf_size = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003062 } else {
3063 switch (parent->nodetype) {
3064 case LYS_GROUPING:
3065 tpdf = ((struct lys_node_grp *)parent)->tpdf;
3066 ptr_tpdf_size = &((struct lys_node_grp *)parent)->tpdf_size;
3067 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003068 case LYS_CONTAINER:
3069 tpdf = ((struct lys_node_container *)parent)->tpdf;
3070 ptr_tpdf_size = &((struct lys_node_container *)parent)->tpdf_size;
3071 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003072 case LYS_LIST:
3073 tpdf = ((struct lys_node_list *)parent)->tpdf;
3074 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3075 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003076 case LYS_RPC:
3077 case LYS_ACTION:
3078 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3079 ptr_tpdf_size = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3080 break;
Pavol Vican78729392016-11-28 17:18:22 +01003081 case LYS_INPUT:
3082 case LYS_OUTPUT:
3083 tpdf = ((struct lys_node_inout *)parent)->tpdf;
3084 ptr_tpdf_size = &((struct lys_node_inout *)parent)->tpdf_size;
3085 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003086 case LYS_NOTIF:
3087 tpdf = ((struct lys_node_notif *)parent)->tpdf;
3088 ptr_tpdf_size = &((struct lys_node_notif *)parent)->tpdf_size;
3089 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003090 default:
3091 LOGINT;
3092 return EXIT_FAILURE;
3093 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003094 }
3095
3096 tpdf_size = *ptr_tpdf_size;
3097 *ptr_tpdf_size = 0;
3098
3099 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003100 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3101 goto error;
3102 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003103 tpdf[i].type.parent = &tpdf[i];
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003104
3105 stype = (struct yang_type *)tpdf[i].type.der;
3106 if (stype->base == LY_TYPE_ENUM) {
3107 for (j = 0; j < tpdf[i].type.info.enums.count; ++j) {
3108 if (yang_check_iffeatures(module, &tpdf[i].type.info.enums.enm[j], &tpdf[i], ENUM_KEYWORD, unres)) {
3109 goto error;
3110 }
3111 }
3112 } else if (stype->base == LY_TYPE_BITS) {
3113 for (j = 0; j < tpdf[i].type.info.bits.count; ++j) {
3114 if (yang_check_iffeatures(module, &tpdf[i].type.info.bits.bit[j], &tpdf[i], BIT_KEYWORD, unres)) {
3115 goto error;
3116 }
3117 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003118 } else if (stype->base == LY_TYPE_IDENT) {
3119 if (yang_check_identityref(module, &tpdf[i].type, unres)) {
3120 goto error;
3121 }
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003122 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003123
Pavol Vican7313fc02016-11-14 01:10:31 +01003124 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003125 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003126 }
3127
3128 /* check default value*/
Pavol Vicanfda8c802016-12-03 02:00:42 +01003129 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 +01003130 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003131 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003132 }
3133 (*ptr_tpdf_size)++;
3134 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003135
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003136 return EXIT_SUCCESS;
3137
3138error:
3139 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3140 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003141}
3142
3143static int
Pavol Vican36e27272016-11-22 15:47:28 +01003144yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3145{
3146 uint32_t i, size, base_size;
3147 uint8_t j;
3148
3149 size = module->ident_size;
3150 module->ident_size = 0;
3151 for (i = 0; i < size; ++i) {
3152 base_size = module->ident[i].base_size;
3153 module->ident[i].base_size = 0;
3154 for (j = 0; j < base_size; ++j) {
3155 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3156 ++j;
3157 module->ident_size = size;
3158 goto error;
3159 }
3160 }
3161 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003162 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3163 goto error;
3164 }
Pavol Vican36e27272016-11-22 15:47:28 +01003165 }
3166
3167 return EXIT_SUCCESS;
3168
3169error:
3170 for (; j< module->ident[i].base_size; ++j) {
3171 free(module->ident[i].base[j]);
3172 }
3173 yang_free_ident_base(module->ident, i + 1, size);
3174 return EXIT_FAILURE;
3175}
3176
3177static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003178yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003179{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003180 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003181 goto error;
3182 }
3183
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003184 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003185 goto error;
3186 }
3187
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003188 /* check XPath dependencies */
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003189 if ((cont->when || cont->must_size) && (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003190 goto error;
3191 }
3192
3193 return EXIT_SUCCESS;
3194error:
3195 return EXIT_FAILURE;
3196}
3197
3198static int
Pavol Vicana69aff22016-11-24 18:23:50 +01003199yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, struct unres_schema *unres)
3200{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003201 int i;
3202 struct yang_type *stype;
Pavol Vicana69aff22016-11-24 18:23:50 +01003203
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003204 stype = (struct yang_type *)leaf->type.der;
3205 if (stype->base == LY_TYPE_ENUM) {
3206 for (i = 0; i < leaf->type.info.enums.count; ++i) {
3207 if (yang_check_iffeatures(module, &leaf->type.info.enums.enm[i], leaf, ENUM_KEYWORD, unres)) {
3208 yang_type_free(module->ctx, &leaf->type);
3209 goto error;
3210 }
3211 }
3212 } else if (stype->base == LY_TYPE_BITS) {
3213 for (i = 0; i < leaf->type.info.bits.count; ++i) {
3214 if (yang_check_iffeatures(module, &leaf->type.info.bits.bit[i], leaf, BIT_KEYWORD, unres)) {
3215 yang_type_free(module->ctx, &leaf->type);
3216 goto error;
3217 }
3218 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003219 } else if (stype->base == LY_TYPE_IDENT) {
3220 if (yang_check_identityref(module, &leaf->type, unres)) {
3221 goto error;
3222 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003223 }
3224
Pavol Vicanfda8c802016-12-03 02:00:42 +01003225 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003226 yang_type_free(module->ctx, &leaf->type);
3227 goto error;
3228 }
3229
Pavol Vicanfda8c802016-12-03 02:00:42 +01003230 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 +01003231 goto error;
3232 }
3233
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003234 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3235 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003236 }
3237
3238 /* check XPath dependencies */
3239 if ((leaf->when || leaf->must_size) && (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1)) {
3240 goto error;
3241 }
3242
3243 return EXIT_SUCCESS;
3244error:
3245 return EXIT_FAILURE;
3246}
3247
3248static int
Pavol Vican36aff862016-11-26 17:07:05 +01003249yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, struct unres_schema *unres)
3250{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003251 int i, j;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003252 struct yang_type *stype;
Pavol Vican36aff862016-11-26 17:07:05 +01003253
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003254 stype = (struct yang_type *)leaflist->type.der;
3255 if (stype->base == LY_TYPE_ENUM) {
3256 for (i = 0; i < leaflist->type.info.enums.count; ++i) {
3257 if (yang_check_iffeatures(module, &leaflist->type.info.enums.enm[i], leaflist, ENUM_KEYWORD, unres)) {
3258 yang_type_free(module->ctx, &leaflist->type);
3259 goto error;
3260 }
3261 }
3262 } else if (stype->base == LY_TYPE_BITS) {
3263 for (i = 0; i < leaflist->type.info.bits.count; ++i) {
3264 if (yang_check_iffeatures(module, &leaflist->type.info.bits.bit[i], leaflist, BIT_KEYWORD, unres)) {
3265 yang_type_free(module->ctx, &leaflist->type);
3266 goto error;
3267 }
3268 }
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003269 } else if (stype->base == LY_TYPE_IDENT) {
3270 if (yang_check_identityref(module, &leaflist->type, unres)) {
3271 goto error;
3272 }
Pavol Vican36aff862016-11-26 17:07:05 +01003273 }
3274
Pavol Vicanfda8c802016-12-03 02:00:42 +01003275 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003276 yang_type_free(module->ctx, &leaflist->type);
3277 goto error;
3278 }
3279
Pavol Vican36aff862016-11-26 17:07:05 +01003280 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003281 /* check for duplicity in case of configuration data,
3282 * in case of status data duplicities are allowed */
3283 if (leaflist->flags & LYS_CONFIG_W) {
3284 for (j = i +1; j < leaflist->dflt_size; ++j) {
3285 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
3286 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, leaflist->dflt[i], "default");
3287 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", leaflist->dflt[i]);
3288 goto error;
3289 }
3290 }
3291 }
3292 /* check default value (if not defined, there still could be some restrictions
3293 * that need to be checked against a default value from a derived type) */
Pavol Vican36aff862016-11-26 17:07:05 +01003294 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaflist->dflt[i])) == -1) {
3295 goto error;
3296 }
3297 }
3298
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003299 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3300 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003301 }
3302
3303 /* check XPath dependencies */
3304 if ((leaflist->when || leaflist->must_size) && (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1)) {
3305 goto error;
3306 }
3307
3308 return EXIT_SUCCESS;
3309error:
3310 return EXIT_FAILURE;
3311}
3312
3313static int
Pavol Vicand8136a42016-11-27 13:28:04 +01003314yang_check_list(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
3315{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003316 struct lys_node *node;
3317
Pavol Vicand8136a42016-11-27 13:28:04 +01003318 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3319 goto error;
3320 }
3321
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003322 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3323 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003324 }
3325
Pavol Vicanfda8c802016-12-03 02:00:42 +01003326 if (list->flags & LYS_CONFIG_R) {
3327 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3328 * ignore oredering MASK - 0x7F
3329 */
3330 list->flags &= 0x7F;
3331 }
3332 /* check - if list is configuration, key statement is mandatory
3333 * (but only if we are not in a grouping or augment, then the check is deferred) */
3334 for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT)); node = node->parent);
3335 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3336 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3337 goto error;
3338 }
3339
Pavol Vicand8136a42016-11-27 13:28:04 +01003340 if (list->keys && yang_read_key(module, list, unres)) {
3341 goto error;
3342 }
3343
3344 if (yang_read_unique(module, list, unres)) {
3345 goto error;
3346 }
3347
3348 /* check XPath dependencies */
3349 if ((list->when || list->must_size) && (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1)) {
3350 goto error;
3351 }
3352
3353 return EXIT_SUCCESS;
3354error:
3355 return EXIT_FAILURE;
3356}
3357
3358static int
Pavol Vican36ace102016-11-28 11:46:59 +01003359yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct unres_schema *unres)
3360{
3361 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003362
3363 if (choice->dflt) {
3364 value = (char *)choice->dflt;
3365 choice->dflt = NULL;
3366 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3367 free(value);
3368 goto error;
3369 }
3370 free(value);
3371 }
3372
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003373 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3374 goto error;
Pavol Vican36ace102016-11-28 11:46:59 +01003375 }
3376
3377 /* check XPath dependencies */
3378 if ((choice->when) && (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1)) {
3379 goto error;
3380 }
3381
3382 return EXIT_SUCCESS;
3383error:
3384 return EXIT_FAILURE;
3385}
3386
3387static int
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003388yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct unres_schema *unres)
3389{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003390 struct lys_node *node;
3391
3392 if (rpc->nodetype == LYS_ACTION) {
3393 for (node = rpc->parent; node; node = lys_parent(node)) {
3394 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003395 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003396 LOGVAL(LYE_INPAR, LY_VLOG_NONE, NULL, strnodetype(node->nodetype), "action");
3397 goto error;
3398 }
3399 }
3400 }
3401 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3402 goto error;
3403 }
3404
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003405 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3406 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003407 }
3408
3409 return EXIT_SUCCESS;
3410error:
3411 return EXIT_FAILURE;
3412}
3413
3414static int
Pavol Vican29bf8802016-11-28 20:44:57 +01003415yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct unres_schema *unres)
3416{
Pavol Vican29bf8802016-11-28 20:44:57 +01003417 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3418 goto error;
3419 }
3420
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003421 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3422 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003423 }
3424
3425 /* check XPath dependencies */
3426 if ((notif->must_size) && (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1)) {
3427 goto error;
3428 }
3429
3430 return EXIT_SUCCESS;
3431error:
3432 return EXIT_FAILURE;
3433}
3434
3435static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003436yang_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 +01003437{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003438 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003439
Pavol Vican3ad50f82016-12-04 15:00:36 +01003440 child = augment->child;
3441 augment->child = NULL;
3442
3443 if (yang_check_nodes(module, (struct lys_node *)augment, child, config_opt, unres)) {
3444 goto error;
3445 }
3446
3447 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
3448 goto error;
3449 }
3450
3451 /* check XPath dependencies */
3452 if (augment->when && (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1)) {
3453 goto error;
3454 }
3455
3456 return EXIT_SUCCESS;
3457error:
3458 return EXIT_FAILURE;
3459}
3460
3461static int
3462yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int config_opt, struct unres_schema *unres)
3463{
3464 uint i, size;
3465
3466 size = uses->augment_size;
3467 uses->augment_size = 0;
3468
3469 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003470 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003471 }
3472
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003473 for (i = 0; i < uses->refine_size; ++i) {
3474 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
3475 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003476 }
3477 }
3478
Pavol Vican3ad50f82016-12-04 15:00:36 +01003479 for (i = 0; i < size; ++i) {
3480 uses->augment_size++;
3481 if (yang_check_augment(module, &uses->augment[i], config_opt, unres)) {
3482 goto error;
3483 }
3484 }
3485
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003486 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
3487 goto error;
3488 }
3489
3490 /* check XPath dependencies */
3491 if (uses->when && (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1)) {
3492 goto error;
3493 }
3494
3495 return EXIT_SUCCESS;
3496error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003497 for (i = uses->augment_size; i < size; ++i) {
3498 yang_free_augment(module->ctx, &uses->augment[i]);
3499 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003500 return EXIT_FAILURE;
3501}
3502
3503static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003504yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
3505 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003506{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003507 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01003508
3509 while (node) {
3510 sibling = node->next;
3511 child = node->child;
3512 node->next = NULL;
3513 node->child = NULL;
3514 node->prev = node;
3515
Pavol Vican24ba7f62016-11-28 12:15:20 +01003516 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
3517 lys_node_unlink(node);
3518 node->next = sibling;
Pavol Vican05810b62016-11-23 14:07:22 +01003519 sibling = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003520 goto error;
3521 }
Pavol Vicanec598812016-11-30 14:13:38 +01003522 config_opt = store_config_flag(node, config_opt);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003523
Pavol Vican3ad50f82016-12-04 15:00:36 +01003524 if (yang_check_nodes(module, node, child, config_opt, unres)) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003525 child = NULL;
3526 goto error;
3527 }
3528 child = NULL;
3529
Pavol Vican05810b62016-11-23 14:07:22 +01003530 switch (node->nodetype) {
3531 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003532 if (yang_check_typedef(module, node, unres)) {
3533 goto error;
3534 }
3535 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003536 goto error;
3537 }
3538 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003539 case LYS_CONTAINER:
3540 if (yang_check_container(module, (struct lys_node_container *)node, unres)) {
3541 goto error;
3542 }
3543 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003544 case LYS_LEAF:
3545 if (yang_check_leaf(module, (struct lys_node_leaf *)node, unres)) {
3546 goto error;
3547 }
3548 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003549 case LYS_LEAFLIST:
3550 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, unres)) {
3551 goto error;
3552 }
3553 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003554 case LYS_LIST:
3555 if (yang_check_list(module, (struct lys_node_list *)node, unres)) {
3556 goto error;
3557 }
3558 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003559 case LYS_CHOICE:
3560 if (yang_check_choice(module, (struct lys_node_choice *)node, unres)) {
3561 goto error;
3562 }
3563 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003564 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003565 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01003566 goto error;
3567 }
3568 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003569 case LYS_ANYDATA:
3570 case LYS_ANYXML:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003571 if (yang_check_iffeatures(module, NULL, node, CHOICE_KEYWORD, unres)) {
3572 goto error;
3573 }
3574 /* check XPath dependencies */
3575 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 +01003576 goto error;
3577 }
3578 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003579 case LYS_RPC:
3580 case LYS_ACTION:
3581 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, unres)){
3582 goto error;
3583 }
3584 break;
Pavol Vican78729392016-11-28 17:18:22 +01003585 case LYS_INPUT:
3586 case LYS_OUTPUT:
3587 /* check XPath dependencies */
3588 if (((struct lys_node_inout *)node)->must_size &&
3589 (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1)) {
3590 goto error;
3591 }
3592 if (yang_check_typedef(module, node, unres)) {
3593 goto error;
3594 }
3595 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003596 case LYS_NOTIF:
3597 if (yang_check_notif(module, (struct lys_node_notif *)node, unres)) {
3598 goto error;
3599 }
3600 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003601 case LYS_USES:
Pavol Vican3ad50f82016-12-04 15:00:36 +01003602 if (yang_check_uses(module, (struct lys_node_uses *)node, config_opt, unres)) {
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003603 goto error;
3604 }
3605 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003606 default:
3607 LOGINT;
3608 sibling = node;
3609 child = NULL;
3610 goto error;
3611 }
Pavol Vican05810b62016-11-23 14:07:22 +01003612 node = sibling;
3613 }
3614
3615 return EXIT_SUCCESS;
3616error:
3617 yang_free_nodes(module->ctx, sibling);
3618 yang_free_nodes(module->ctx, child);
3619 return EXIT_FAILURE;
3620}
3621
3622static int
PavolVican75af21d2016-12-29 20:04:07 +01003623yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
3624 struct lys_node *dev_target, struct ly_set *dflt_check)
3625{
3626 struct lys_node_leaflist *llist;
3627 struct lys_type *type;
3628 struct lys_tpdf *tmp_parent;
3629 int i, j;
3630
3631 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
3632 goto error;
3633 }
3634 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
3635 goto error;
3636 }
3637 if (deviate->dflt_size) {
3638 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
3639 goto error;
3640 }
3641 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
3642 /* consolidate the final list in the target after removing items from it */
3643 llist = (struct lys_node_leaflist *)dev_target;
3644 for (i = j = 0; j < llist->dflt_size; j++) {
3645 llist->dflt[i] = llist->dflt[j];
3646 if (llist->dflt[i]) {
3647 i++;
3648 }
3649 }
3650 llist->dflt_size = i + 1;
3651 }
3652 }
3653
3654 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
3655 goto error;
3656 }
3657
3658 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
3659 goto error;
3660 }
3661
3662 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
3663 goto error;
3664 }
3665
3666 if ((deviate->flags & LYS_CONFIG_MASK)) {
3667 /* add and replace are the same in this case */
3668 /* remove current config value of the target ... */
3669 dev_target->flags &= ~LYS_CONFIG_MASK;
3670
3671 /* ... and replace it with the value specified in deviation */
3672 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
3673 }
3674
3675 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
3676 goto error;
3677 }
3678
3679 if (deviate->type) {
3680 /* check target node type */
3681 if (dev_target->nodetype == LYS_LEAF) {
3682 type = &((struct lys_node_leaf *)dev_target)->type;
3683 } else if (dev_target->nodetype == LYS_LEAFLIST) {
3684 type = &((struct lys_node_leaflist *)dev_target)->type;
3685 } else {
3686 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
3687 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
3688 goto error;
3689 }
3690 /* remove type and initialize it */
3691 tmp_parent = type->parent;
3692 lys_type_free(module->ctx, type);
3693 memcpy(type, deviate->type, sizeof *deviate->type);
3694 free(deviate->type);
3695 deviate->type = type;
3696 deviate->type->parent = tmp_parent;
3697 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
3698 goto error;
3699 }
3700 }
3701
3702 return EXIT_SUCCESS;
3703error:
3704 if (deviate->type) {
3705 yang_type_free(module->ctx, deviate->type);
3706 deviate->type = NULL;
3707 }
3708 return EXIT_FAILURE;
3709}
3710
3711static int
3712yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
3713{
3714 int rc;
3715 uint i;
3716 struct lys_node *dev_target = NULL, *parent;
3717 struct ly_set *dflt_check = ly_set_new();
3718 unsigned int u;
3719 const char *value, *target_name;
3720 struct lys_node_leaflist *llist;
3721 struct lys_node_leaf *leaf;
3722 struct unres_schema tmp_unres;
3723 struct lys_module *mod;
3724
3725 /* resolve target node */
3726 rc = resolve_augment_schema_nodeid(dev->target_name, NULL, module, 1, (const struct lys_node **)&dev_target);
3727 if (rc || !dev_target) {
3728 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
3729 goto error;
3730 }
3731 if (dev_target->module == lys_main_module(module)) {
3732 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
3733 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
3734 goto error;
3735 }
3736
3737 if (!dflt_check) {
3738 LOGMEM;
3739 goto error;
3740 }
3741
3742 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
3743 /* you cannot remove a key leaf */
3744 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
3745 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
3746 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
3747 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
3748 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
3749 return EXIT_FAILURE;
3750 }
3751 }
3752 }
3753 /* unlink and store the original node */
3754 lys_node_unlink(dev_target);
3755 dev->orig_node = dev_target;
3756 } else {
3757 /* store a shallow copy of the original node */
3758 memset(&tmp_unres, 0, sizeof tmp_unres);
3759 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, 0, &tmp_unres, 1);
3760 /* just to be safe */
3761 if (tmp_unres.count) {
3762 LOGINT;
3763 goto error;
3764 }
3765 }
3766
3767 for (i = 0; i < dev->deviate_size; ++i) {
3768 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
3769 yang_free_deviate(module->ctx, dev, i + 1);
3770 dev->deviate_size = i+1;
3771 goto error; // missing free unresolve type in deviate
3772 }
3773 }
3774 /* now check whether default value, if any, matches the type */
3775 for (u = 0; u < dflt_check->number; ++u) {
3776 value = NULL;
3777 rc = EXIT_SUCCESS;
3778 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
3779 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
3780 target_name = leaf->name;
3781 value = leaf->dflt;
3782 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
3783 } else { /* LYS_LEAFLIST */
3784 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
3785 target_name = llist->name;
3786 for (i = 0; i < llist->dflt_size; i++) {
3787 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
3788 (struct lys_node *)(&llist->dflt[i]));
3789 if (rc == -1) {
3790 value = llist->dflt[i];
3791 break;
3792 }
3793 }
3794 }
3795 if (rc == -1) {
3796 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
3797 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
3798 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
3799 target_name);
3800 goto error;
3801 }
3802 }
3803 ly_set_free(dflt_check);
3804
3805 /* mark all the affected modules as deviated and implemented*/
3806 for(parent = dev_target; parent; parent = lys_parent(parent)) {
3807 mod = lys_node_module(parent);
3808 if (module != mod) {
3809 mod->deviated = 1;
3810 lys_set_implemented(mod);
3811 }
3812}
3813
3814 return EXIT_SUCCESS;
3815error:
3816 ly_set_free(dflt_check);
3817 return EXIT_FAILURE;
3818}
3819
3820static int
Pavol Vican7313fc02016-11-14 01:10:31 +01003821yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
3822{
PavolVican75af21d2016-12-29 20:04:07 +01003823 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01003824
3825 aug_size = module->augment_size;
3826 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01003827 dev_size = module->deviation_size;
3828 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01003829
Pavol Vican7313fc02016-11-14 01:10:31 +01003830 if (yang_check_typedef(module, NULL, unres)) {
3831 goto error;
3832 }
3833
Pavol Vican7a7916f2016-11-21 23:38:30 +01003834 /* check features */
3835 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003836 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
3837 goto error;
3838 }
3839 /* check for circular dependencies */
3840 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
3841 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01003842 }
3843 }
Pavol Vican36e27272016-11-22 15:47:28 +01003844 erase_identities = 0;
3845 if (yang_check_identities(module, unres)) {
3846 goto error;
3847 }
Pavol Vican05810b62016-11-23 14:07:22 +01003848 erase_nodes = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01003849 if (yang_check_nodes(module, NULL, node, CONFIG_INHERIT_ENABLE, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003850 goto error;
3851 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01003852
PavolVican75af21d2016-12-29 20:04:07 +01003853 /* check deviation */
3854 for (i = 0; i < dev_size; ++i) {
3855 module->deviation_size++;
3856 if (yang_check_deviation(module, unres, &module->deviation[i])) {
3857 goto error;
3858 }
3859 }
3860
Pavol Vican3ad50f82016-12-04 15:00:36 +01003861 /* check augments */
3862 for (i = 0; i < aug_size; ++i) {
3863 module->augment_size++;
3864 if (yang_check_augment(module, &module->augment[i], CONFIG_INHERIT_ENABLE, unres)) {
3865 goto error;
3866 }
3867 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
3868 goto error;
3869 }
3870 }
3871
Pavol Vican7313fc02016-11-14 01:10:31 +01003872 return EXIT_SUCCESS;
3873error:
Pavol Vican36e27272016-11-22 15:47:28 +01003874 if (erase_identities) {
3875 yang_free_ident_base(module->ident, 0, module->ident_size);
3876 }
Pavol Vican05810b62016-11-23 14:07:22 +01003877 if (erase_nodes) {
3878 yang_free_nodes(module->ctx, node);
3879 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01003880 for (i = module->augment_size; i < aug_size; ++i) {
3881 yang_free_augment(module->ctx, &module->augment[i]);
3882 }
PavolVican75af21d2016-12-29 20:04:07 +01003883 for (i = module->deviation_size; i < dev_size; ++i) {
3884 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3885 free(module->deviation[i].deviate);
3886 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003887 return EXIT_FAILURE;
3888}