blob: bacae98e3da73fe92c51741328eb9d68f7f60b2e [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);
PavolVican6f000922017-02-10 12:56:59 +010023static int yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres);
Pavol Vican082afd02016-10-25 12:39:15 +020024static 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 +010025static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
Pavol Vican05810b62016-11-23 14:07:22 +010026static void free_yang_common(struct lys_module *module, struct lys_node *node);
Pavol Vican3ad50f82016-12-04 15:00:36 +010027static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
28 int config_opt, struct unres_schema *unres);
PavolVican5334c892017-02-15 16:29:09 +010029static int yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword);
PavolVican8c33b152017-01-27 12:45:34 +010030void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size);
Pavol Vican082afd02016-10-25 12:39:15 +020031
Michal Vaskofe7e5a72016-05-02 14:49:23 +020032static int
PavolVican196694c2017-01-27 10:33:09 +010033yang_check_string(struct lys_module *module, const char **target, char *what,
34 char *where, char *value, struct lys_node *node)
Pavol Vican2a064652016-02-02 22:54:34 +010035{
Pavol Vicanbf805472016-01-26 14:24:56 +010036 if (*target) {
PavolVican196694c2017-01-27 10:33:09 +010037 LOGVAL(LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010038 free(value);
39 return 1;
40 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010041 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010042 return 0;
43 }
44}
45
Michal Vaskofe7e5a72016-05-02 14:49:23 +020046int
Pavol Vican5f0316a2016-04-05 21:21:11 +020047yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010048{
Pavol Vican6eb14e82016-02-03 12:27:13 +010049 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010050
51 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010052 case MODULE_KEYWORD:
53 module->name = lydict_insert_zc(module->ctx, value);
54 break;
55 case NAMESPACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010056 ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +010057 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010058 case ORGANIZATION_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010059 ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010060 break;
61 case CONTACT_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010062 ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010063 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020064 default:
65 free(value);
66 LOGINT;
67 ret = EXIT_FAILURE;
68 break;
Pavol Vican2a064652016-02-02 22:54:34 +010069 }
70
Pavol Vican021488a2016-01-25 23:56:12 +010071 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010072}
73
Michal Vaskofe7e5a72016-05-02 14:49:23 +020074int
Pavol Vicand0b64c12016-07-15 09:56:19 +020075yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
76{
77 int ret = EXIT_SUCCESS;
78
79 if (repeat) {
Michal Vasko3767fb22016-07-21 12:10:57 +020080 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
81 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020082 } else {
83 if (!strcmp(value, "1")) {
84 if (submodule) {
85 if (module->version > 1) {
86 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
87 ret = EXIT_FAILURE;
88 }
89 } else {
90 module->version = 1;
91 }
92 } else if (!strcmp(value, "1.1")) {
93 if (submodule) {
94 if (module->version != 2) {
95 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
96 ret = EXIT_FAILURE;
97 }
98 } else {
99 module->version = 2;
100 }
101 } else {
102 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
103 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200104 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200105 }
106 free(value);
107 return ret;
108}
109
110int
Pavol Vicane024ab72016-07-27 14:27:43 +0200111yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100112{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100113 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100114
Pavol Vican1cc4e192016-10-24 16:38:31 +0200115 if (!imp && lyp_check_identifier(value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100116 free(value);
117 return EXIT_FAILURE;
118 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200119
120 if (imp) {
PavolVican196694c2017-01-27 10:33:09 +0100121 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
Pavol Vicane024ab72016-07-27 14:27:43 +0200122 } else {
PavolVican196694c2017-01-27 10:33:09 +0100123 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +0100124 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100125
Pavol Vicanbf805472016-01-26 14:24:56 +0100126 return ret;
127}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100128
Pavol Vican1cc4e192016-10-24 16:38:31 +0200129static int
PavolVican7d0b5ab2017-02-01 13:06:53 +0100130yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
131 char *value, struct unres_schema *unres)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100132{
Pavol Vican0da132e2016-03-21 12:03:03 +0100133 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200134 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100135
Pavol Vican1cc4e192016-10-24 16:38:31 +0200136 if (!imp_old->prefix) {
Pavol Vicane024ab72016-07-27 14:27:43 +0200137 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200138 goto error;
139 } else {
140 if (lyp_check_identifier(imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
141 goto error;
142 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200143 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200144 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100145 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200146 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100147 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200148 module->imp_size++;
PavolVican7d0b5ab2017-02-01 13:06:53 +0100149 if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200150 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100151 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100152
Pavol Vican6eb14e82016-02-03 12:27:13 +0100153 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200154
155error:
156 free(value);
157 lydict_remove(module->ctx, imp_old->dsc);
158 lydict_remove(module->ctx, imp_old->ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +0100159 lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200160 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100161}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100162
163int
PavolVican196694c2017-01-27 10:33:09 +0100164yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100165{
166 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100167 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100168
PavolVican196694c2017-01-27 10:33:09 +0100169 switch (type) {
170 case MODULE_KEYWORD:
171 ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
172 break;
173 case REVISION_KEYWORD:
174 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
175 break;
176 case IMPORT_KEYWORD:
177 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
178 break;
179 case INCLUDE_KEYWORD:
180 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
181 break;
182 case NODE_PRINT:
183 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
184 break;
185 default:
186 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
187 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100188 }
189 return ret;
190}
191
192int
PavolVican196694c2017-01-27 10:33:09 +0100193yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100194{
195 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100196 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100197
PavolVican196694c2017-01-27 10:33:09 +0100198 switch (type) {
199 case MODULE_KEYWORD:
200 ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
201 break;
202 case REVISION_KEYWORD:
203 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
204 break;
205 case IMPORT_KEYWORD:
206 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
207 break;
208 case INCLUDE_KEYWORD:
209 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
210 break;
211 case NODE_PRINT:
212 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
213 break;
214 default:
215 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
216 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100217 }
218 return ret;
219}
Pavol Vicanbedff692016-02-03 14:29:17 +0100220
PavolVican171717d2017-02-01 14:49:55 +0100221void *
Pavol Vican866d9912016-10-25 09:13:30 +0200222yang_read_revision(struct lys_module *module, char *value, struct lys_revision *retval)
Pavol Vicanbedff692016-02-03 14:29:17 +0100223{
Pavol Vicanbedff692016-02-03 14:29:17 +0100224 /* first member of array is last revision */
Pavol Vican866d9912016-10-25 09:13:30 +0200225 if ((module->rev_size - 1) && strcmp(module->rev[0].date, value) < 0) {
PavolVican171717d2017-02-01 14:49:55 +0100226 memcpy(retval, &module->rev[0], sizeof *retval);
227 memset(&module->rev[0], 0, sizeof *retval);
Pavol Vicanbedff692016-02-03 14:29:17 +0100228 memcpy(module->rev[0].date, value, LY_REV_SIZE);
Pavol Vicanbedff692016-02-03 14:29:17 +0100229 retval = module->rev;
Pavol Vicanbedff692016-02-03 14:29:17 +0100230 } else {
231 memcpy(retval->date, value, LY_REV_SIZE);
232 }
Pavol Vicanbedff692016-02-03 14:29:17 +0100233 free(value);
PavolVican171717d2017-02-01 14:49:55 +0100234 return retval;
Pavol Vicanbedff692016-02-03 14:29:17 +0100235}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100236
237int
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100238yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
239 char *value, struct unres_schema *unres, int parent_is_feature)
Pavol Vicane1354e92016-02-09 14:02:09 +0100240{
241 const char *exp;
242 int ret;
243
Michal Vasko97b32be2016-07-25 10:59:53 +0200244 if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
245 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
246 free(value);
247 return EXIT_FAILURE;
248 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100249
Michal Vasko56d082c2016-10-25 14:00:42 +0200250 if (!(exp = transform_iffeat_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100251 free(value);
252 return EXIT_FAILURE;
253 }
254 free(value);
255
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100256 ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
Pavol Vicane1354e92016-02-09 14:02:09 +0100257 lydict_remove(module->ctx, exp);
Pavol Vicane1354e92016-02-09 14:02:09 +0100258
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100259 return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
Pavol Vicane1354e92016-02-09 14:02:09 +0100260}
261
Pavol Vican4fb66c92016-03-17 10:32:27 +0100262int
Radek Krejci4372b4e2016-04-14 17:42:16 +0200263yang_check_flags(uint16_t *flags, uint16_t mask, char *what, char *where, uint16_t value, int shortint)
Pavol Vicane1354e92016-02-09 14:02:09 +0100264{
265 if (*flags & mask) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100266 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, what, where);
Pavol Vicane1354e92016-02-09 14:02:09 +0100267 return EXIT_FAILURE;
268 } else {
Radek Krejci4372b4e2016-04-14 17:42:16 +0200269 if (shortint) {
270 *((uint8_t *)flags) |= (uint8_t)value;
271 } else {
272 *flags |= value;
273 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100274 return EXIT_SUCCESS;
275 }
276}
277
Pavol Vicanbbdef532016-02-09 14:52:12 +0100278int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100279yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100280{
281 const char *exp;
282
Pavol Vican0adf01d2016-03-22 12:29:33 +0100283 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100284 free(value);
285 if (!exp) {
286 return EXIT_FAILURE;
287 }
Pavol Vican4ffd0ab2016-08-27 16:35:04 +0200288
Pavol Vican0adf01d2016-03-22 12:29:33 +0100289 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100290 lydict_remove(module->ctx, exp);
291 return EXIT_FAILURE;
292 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100293
Pavol Vicanbbdef532016-02-09 14:52:12 +0100294 lydict_remove(module->ctx, exp);
295 return EXIT_SUCCESS;
296}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100297
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100298int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100299yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100300{
301 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100302
Pavol Vicandde090a2016-08-30 15:12:14 +0200303 if (message == ERROR_APP_TAG_KEYWORD) {
PavolVican196694c2017-01-27 10:33:09 +0100304 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100305 } else {
PavolVican196694c2017-01-27 10:33:09 +0100306 ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100307 }
308 return ret;
309}
Pavol Vicanb5687112016-02-09 22:35:59 +0100310
311int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100312yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100313{
314 if (cont->presence) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100315 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100316 free(value);
317 return EXIT_FAILURE;
318 } else {
319 cont->presence = lydict_insert_zc(module->ctx, value);
320 return EXIT_SUCCESS;
321 }
322}
323
Pavol Vican235dbd42016-02-10 10:34:19 +0100324void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200325yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100326{
327 struct lys_when *retval;
328
329 retval = calloc(1, sizeof *retval);
330 if (!retval) {
331 LOGMEM;
332 free(value);
333 return NULL;
334 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100335 retval->cond = transform_schema2json(module, value);
Michal Vasko508a50d2016-09-07 14:50:33 +0200336 if (!retval->cond) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100337 goto error;
338 }
339 switch (type) {
340 case CONTAINER_KEYWORD:
341 if (((struct lys_node_container *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100342 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100343 goto error;
344 }
345 ((struct lys_node_container *)node)->when = retval;
346 break;
Pavol Vicandb7489e2016-08-23 17:23:39 +0200347 case ANYDATA_KEYWORD:
Pavol Vican1f06ba82016-02-10 17:39:50 +0100348 case ANYXML_KEYWORD:
Radek Krejcibf2abff2016-08-23 15:51:52 +0200349 if (((struct lys_node_anydata *)node)->when) {
Pavol Vicandb7489e2016-08-23 17:23:39 +0200350 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100351 goto error;
352 }
Radek Krejcibf2abff2016-08-23 15:51:52 +0200353 ((struct lys_node_anydata *)node)->when = retval;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100354 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100355 case CHOICE_KEYWORD:
356 if (((struct lys_node_choice *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100357 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100358 goto error;
359 }
360 ((struct lys_node_choice *)node)->when = retval;
361 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100362 case CASE_KEYWORD:
363 if (((struct lys_node_case *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100364 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100365 goto error;
366 }
367 ((struct lys_node_case *)node)->when = retval;
368 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100369 case LEAF_KEYWORD:
370 if (((struct lys_node_leaf *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100371 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100372 goto error;
373 }
374 ((struct lys_node_leaf *)node)->when = retval;
375 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100376 case LEAF_LIST_KEYWORD:
377 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100378 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100379 goto error;
380 }
381 ((struct lys_node_leaflist *)node)->when = retval;
382 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100383 case LIST_KEYWORD:
384 if (((struct lys_node_list *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100385 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100386 goto error;
387 }
388 ((struct lys_node_list *)node)->when = retval;
389 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100390 case USES_KEYWORD:
391 if (((struct lys_node_uses *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100392 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100393 goto error;
394 }
395 ((struct lys_node_uses *)node)->when = retval;
396 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100397 case AUGMENT_KEYWORD:
398 if (((struct lys_node_augment *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100399 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100400 goto error;
401 }
402 ((struct lys_node_augment *)node)->when = retval;
403 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200404 default:
405 goto error;
406 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100407 }
408 free(value);
409 return retval;
410
411error:
412 free(value);
413 lys_when_free(module->ctx, retval);
414 return NULL;
415}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100416
417void *
Pavol Vican05810b62016-11-23 14:07:22 +0100418yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
419 char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100420{
Pavol Vican05810b62016-11-23 14:07:22 +0100421 struct lys_node *node, **child;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100422
Pavol Vican7cadfe72016-02-11 12:33:34 +0100423 node = calloc(1, sizeof_struct);
424 if (!node) {
Pavol Vicand1dbfda2016-03-21 10:03:58 +0100425 free(value);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100426 LOGMEM;
427 return NULL;
428 }
PavolVican196694c2017-01-27 10:33:09 +0100429 LOGDBG("YANG: parsing %s statement \"%s\"", strnodetype(nodetype), value);
430 node->name = lydict_insert_zc(module->ctx, value);
Pavol Vican7cadfe72016-02-11 12:33:34 +0100431 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100432 node->nodetype = nodetype;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100433
434 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100435 child = (parent) ? &parent->child : root;
436 if (*child) {
437 (*child)->prev->next = node;
438 (*child)->prev = node;
439 } else {
440 *child = node;
441 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100442 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100443 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100444}
445
446int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200447yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100448{
449 int ret;
450
451 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100452 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100453 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100454 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100455 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100456 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100457 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200458 default:
459 free(value);
460 LOGINT;
461 ret = EXIT_FAILURE;
462 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100463 }
464 return ret;
465}
466
467int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200468yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100469{
470 int ret;
471
472 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100473 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100474 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100475 break;
476 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100477 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100478 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100479 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100480 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100481 break;
PavolVican75af21d2016-12-29 20:04:07 +0100482 case ADD_KEYWORD:
483 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +0100484 case DELETE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100485 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100486 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200487 default:
488 free(value);
489 LOGINT;
490 ret = EXIT_FAILURE;
491 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100492 }
493 return ret;
494}
Pavol Vican5de33492016-02-22 14:03:24 +0100495
496int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100497yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100498{
499 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100500 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100501
502 exp = value = (char *) list->keys;
503 while ((value = strpbrk(value, " \t\n"))) {
504 list->keys_size++;
505 while (isspace(*value)) {
506 value++;
507 }
508 }
509 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100510
511 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100512 list->keys = calloc(list->keys_size, sizeof *list->keys);
513 if (!list->keys) {
514 LOGMEM;
Radek Krejci5c08a992016-11-02 13:30:04 +0100515 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100516 }
Radek Krejci5c08a992016-11-02 13:30:04 +0100517 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
518 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
519 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100520 }
Pavol Vican5de33492016-02-22 14:03:24 +0100521 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100522}
523
524int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100525yang_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 +0100526{
527 int i, j;
528 char *vaux;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200529 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100530
531 /* count the number of unique leafs in the value */
532 vaux = value;
533 while ((vaux = strpbrk(vaux, " \t\n"))) {
534 unique->expr_size++;
535 while (isspace(*vaux)) {
536 vaux++;
537 }
538 }
539 unique->expr_size++;
540 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
541 if (!unique->expr) {
542 LOGMEM;
543 goto error;
544 }
545
546 for (i = 0; i < unique->expr_size; i++) {
547 vaux = strpbrk(value, " \t\n");
548 if (!vaux) {
549 /* the last token, lydict_insert() will count its size on its own */
550 vaux = value;
551 }
552
553 /* store token into unique structure */
554 unique->expr[i] = lydict_insert(module->ctx, value, vaux - value);
555
556 /* check that the expression does not repeat */
557 for (j = 0; j < i; j++) {
558 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100559 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
PavolVican196694c2017-01-27 10:33:09 +0100560 LOGVAL(LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100561 goto error;
562 }
563 }
564 /* try to resolve leaf */
565 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200566 unique_info = malloc(sizeof *unique_info);
567 unique_info->list = (struct lys_node *)list;
568 unique_info->expr = unique->expr[i];
569 unique_info->trg_type = &unique->trg_type;
570 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200571 goto error;
572 }
Pavol Vican85f12022016-03-05 16:30:35 +0100573 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200574 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100575 goto error;
576 }
577 }
578
579 /* move to next token */
580 value = vaux;
581 while(isspace(*value)) {
582 value++;
583 }
584 }
585
586 return EXIT_SUCCESS;
587
588error:
589 return EXIT_FAILURE;
590}
591
592int
Pavol Vican5de33492016-02-22 14:03:24 +0100593yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
594{
595 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100596 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100597
598 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100599 str = (char *)list->unique[k].expr;
600 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100601 goto error;
602 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100603 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100604 }
605 return EXIT_SUCCESS;
606
607error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100608 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100609 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100610}
611
Pavol Vican07f220f2016-09-02 13:04:37 +0200612int
Pavol Vican81344ac2016-09-02 14:23:06 +0200613yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100614{
Pavol Vican81344ac2016-09-02 14:23:06 +0200615 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
616 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
617 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100618 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200619 if (stype->type->info.lref.path) {
620 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
621 goto error;
622 }
623 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
624 stype->base = LY_TYPE_LEAFREF;
625 return EXIT_SUCCESS;
626
627error:
628 free(value);
629 return EXIT_FAILURE;
630}
631
632int
633yang_read_require_instance(struct yang_type *stype, int req)
634{
635 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
636 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
637 return EXIT_FAILURE;
638 }
639 if (stype->type->info.lref.req) {
640 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
641 return EXIT_FAILURE;
642 }
643 stype->type->info.lref.req = req;
644 stype->base = LY_TYPE_LEAFREF;
645 return EXIT_SUCCESS;
646}
647
648int
Pavol Vican7313fc02016-11-14 01:10:31 +0100649yang_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 +0100650{
Pavol Vican81344ac2016-09-02 14:23:06 +0200651 int i, j, rc, ret = -1;
652 int8_t req;
Pavol Vican73e7c992016-02-24 12:18:05 +0100653 const char *name, *value;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100654 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200655 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200656 struct lys_type *dertype;
657 struct lys_type_enum *enms_sc = NULL;
658 struct lys_type_bit *bits_sc = NULL;
659 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100660 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100661
Pavol Vican0adf01d2016-03-22 12:29:33 +0100662 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100663 if (!value) {
664 goto error;
665 }
666
667 i = parse_identifier(value);
668 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100669 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100670 lydict_remove(module->ctx, value);
671 goto error;
672 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200673 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100674 name = value;
675 if (value[i]) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100676 type->module_name = lydict_insert(module->ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100677 name += i;
678 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100679 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100680 lydict_remove(module->ctx, value);
681 goto error;
682 }
683 ++name;
684 }
685
Pavol Vican7313fc02016-11-14 01:10:31 +0100686 rc = resolve_superior_type(name, type->module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100687 if (rc == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100688 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, type->module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200689 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100690 goto error;
691
Michal Vasko01c6fd22016-05-20 11:43:05 +0200692 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100693 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200694 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200695 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100696 ret = EXIT_FAILURE;
697 goto error;
698 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200699 lydict_remove(module->ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200700
Pavol Vican7313fc02016-11-14 01:10:31 +0100701 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200702 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200703 * 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 +0200704 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
705 if (siter) {
Radek Krejci6ff885d2017-01-03 14:06:22 +0100706#if __BYTE_ORDER == __LITTLE_ENDIAN
707 if (!((uint8_t*)&((struct lys_node_grp *)siter)->flags)[1]) {
Radek Krejcic13db382016-08-16 10:52:42 +0200708 LOGINT;
709 goto error;
710 }
Radek Krejci6ff885d2017-01-03 14:06:22 +0100711 ((uint8_t*)&((struct lys_node_grp *)siter)->flags)[1]--;
712#else
713 if (!((uint8_t*)&((struct lys_node_grp *)siter)->flags)[0]) {
714 LOGINT;
715 goto error;
716 }
717 ((uint8_t*)&((struct lys_node_grp *)siter)->flags)[0]--;
718#endif
Radek Krejcic13db382016-08-16 10:52:42 +0200719 } else {
720 LOGINT;
721 goto error;
722 }
723 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200724
725 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100726 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
727 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200728 goto error;
729 }
730
Pavol Vican8bd72e42016-08-29 09:53:05 +0200731 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100732 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100733 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100734 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100735 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100736 }
737 switch (base) {
738 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100739 if (type->base == LY_TYPE_BINARY) {
740 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100741 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100742 goto error;
743 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100744 type->info.binary.length = type->info.str.length;
745 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
746 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100747 goto error;
748 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100749 } else if (type->base == LY_TYPE_STRING) {
750 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
751 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100752 goto error;
753 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100754 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100755 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100756 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100757 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100758 break;
759 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100760 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100761 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100762 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100763 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100764 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100765 goto error;
766 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100767 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100768 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100769 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100770 goto error;
771 }
Radek Krejci4800f652016-09-08 14:02:52 +0200772
773 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100774 if (type->der->type.der) {
775 type->info.dec64.dig = type->der->type.info.dec64.dig;
776 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200777 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100778 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
779 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200780 goto error;
781 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100782 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
783 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100784 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100785 goto error;
786 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100787 type->info.num.range = type->info.dec64.range;
788 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
789 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100790 goto error;
791 }
792 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100793 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100794 goto error;
795 }
796 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100797 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100798 if (type->base != LY_TYPE_ENUM) {
799 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100800 goto error;
801 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100802 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200803
804 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100805 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200806 /* type is derived directly from buit-in enumeartion type and enum statement is required */
807 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
808 goto error;
809 }
810 } else {
811 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100812 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200813 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
814 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
815 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
816 goto error;
817 }
818
819 /* restricted enumeration type - the name MUST be used in the base type */
820 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100821 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200822 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100823 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200824 break;
825 }
826 }
827 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100828 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200829 goto error;
830 }
831
Pavol Vican7313fc02016-11-14 01:10:31 +0100832 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200833 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100834 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200835 } else {
836 /* check that the assigned value corresponds to the original
837 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 if (type->info.enums.enm[i].value != enms_sc[j].value) {
839 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200840 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100841 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
842 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200843 goto error;
844 }
845 }
846 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100847 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100848 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100849 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100850 if (type->base != LY_TYPE_BITS) {
851 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100852 goto error;
853 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100854 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200855
856 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100857 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200858 /* type is derived directly from buit-in bits type and bit statement is required */
859 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
860 goto error;
861 }
862 } else {
863 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100864 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200865 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
866 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
867 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
868 goto error;
869 }
870
871 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100872 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200873 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100874 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200875 break;
876 }
877 }
878 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100879 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200880 goto error;
881 }
882
883 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100884 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200885 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100886 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200887 } else {
888 /* check that the assigned position corresponds to the original
889 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100890 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
891 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200892 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100893 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
894 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200895 goto error;
896 }
897 }
898 }
Pavol Vican03a59442016-03-21 15:23:45 +0100899 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200900
Pavol Vican7313fc02016-11-14 01:10:31 +0100901 for (i = type->info.bits.count - 1; i > 0; i--) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200902 j = i;
903
904 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100905 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200906 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100907 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
908 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
909 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200910 j--;
911 }
Pavol Vican03a59442016-03-21 15:23:45 +0100912 }
913 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100914 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100915 if (type->base == LY_TYPE_INST) {
916 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200917 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100918 goto error;
919 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100920 if ((req = type->info.lref.req)) {
921 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200922 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100923 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200924 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100925 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200926 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
927 goto error;
928 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200929 /* flag resolving for later use */
930 if (!tpdftype) {
931 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
932 if (siter) {
933 /* just a flag - do not resolve */
934 tpdftype = 1;
935 }
936 }
937
Pavol Vican7313fc02016-11-14 01:10:31 +0100938 if (type->info.lref.path) {
939 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200940 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
941 goto error;
942 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100943 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100944 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100945 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100946 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100947 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100948 goto error;
949 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200950 /* try to resolve leafref path only when this is instantiated
951 * leaf, so it is not:
952 * - typedef's type,
953 * - in grouping definition,
954 * - just instantiated in a grouping definition,
955 * because in those cases the nodes referenced in path might not be present
956 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100957 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100958 goto error;
959 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100960 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100961 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100962 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200963 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200964 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100965 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200966 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100967 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200968 goto error;
969 }
Pavol Vican191613a2016-02-26 16:21:32 +0100970 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100971 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100972 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100973 goto error;
974 }
975 break;
976 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100977 if (type->base != LY_TYPE_IDENT) {
978 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100979 goto error;
980 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100981 if (type->der->type.der) {
982 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200983 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
984 goto error;
985 }
986 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100987 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200988 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
989 goto error;
990 }
991 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100992 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100993 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100994 if (type->base != LY_TYPE_UNION) {
995 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100996 goto error;
997 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100998 if (!type->info.uni.types) {
999 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +01001000 /* this is just a derived type with no additional type specified/required */
1001 break;
1002 }
Pavol Vican0adf01d2016-03-22 12:29:33 +01001003 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +01001004 goto error;
1005 }
Pavol Vican7313fc02016-11-14 01:10:31 +01001006 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +01001007 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001008 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
1009 yang = (struct yang_type *)dertype->der;
1010 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +01001011 dertype->parent = type->parent;
1012 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001013 dertype->der = (struct lys_tpdf *)yang;
1014 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +01001015 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001016 base = 0;
1017 goto error;
1018 } else {
1019 lydict_remove(module->ctx, yang->name);
1020 free(yang);
1021 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001022 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001023 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001024 if (dertype->base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001025 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
1026 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001027 } else if (dertype->base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +02001028 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
1029 goto error;
1030 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001031 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001032 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
1033 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
1034 typ->type->info.uni.has_ptr_type = 1;
1035 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001036 }
1037 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001038
1039 default:
1040 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001041 if (type->base != base) {
1042 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001043 goto error;
1044 }
1045 } else {
1046 LOGINT;
1047 goto error;
1048 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001049 }
1050 return EXIT_SUCCESS;
1051
1052error:
Pavol Vican7313fc02016-11-14 01:10:31 +01001053 if (type->module_name) {
1054 lydict_remove(module->ctx, type->module_name);
1055 type->module_name = NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001056 }
Pavol Vican8bd72e42016-08-29 09:53:05 +02001057 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001058 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001059 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001060 return ret;
1061}
1062
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001063void
1064yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1065{
1066 struct lys_type *stype;
1067 struct yang_type *yang;
1068 int i;
1069
1070 for (i = 0; i < type->info.uni.count; ++i) {
1071 stype = &type->info.uni.types[i];
1072 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1073 yang = (struct yang_type *)stype->der;
1074 stype->base = yang->base;
1075 lydict_remove(ctx, yang->name);
1076 free(yang);
1077 } else if (stype->base == LY_TYPE_UNION) {
1078 yang_free_type_union(ctx, stype);
1079 }
1080 }
1081}
1082
Pavol Vican73e7c992016-02-24 12:18:05 +01001083void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001084yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001085{
1086 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001087 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001088
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001089 typ = calloc(1, sizeof *typ);
1090 if (!typ) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001091 LOGMEM;
1092 return NULL;
1093 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001094
1095 typ->flags = LY_YANG_STRUCTURE_FLAG;
1096 switch (type) {
1097 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001098 if (((struct lys_node_leaf *)parent)->type.der) {
1099 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1100 goto error;
1101 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001102 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1103 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1104 typ->type = &((struct lys_node_leaf *)parent)->type;
1105 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001106 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001107 if (((struct lys_node_leaflist *)parent)->type.der) {
1108 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1109 goto error;
1110 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001111 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1112 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1113 typ->type = &((struct lys_node_leaflist *)parent)->type;
1114 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001115 case UNION_KEYWORD:
1116 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1117 typ->type = (struct lys_type *)parent;
1118 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001119 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001120 if (((struct lys_tpdf *)parent)->type.der) {
1121 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1122 goto error;
1123 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001124 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1125 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001126 break;
1127 case REPLACE_KEYWORD:
1128 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001129 dev = (struct lys_deviate *)parent;
1130 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001131 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001132 goto error;
1133 }
PavolVican75af21d2016-12-29 20:04:07 +01001134 dev->type = calloc(1, sizeof *dev->type);
1135 if (!dev->type) {
1136 LOGMEM;
Pavol Vican4766aca2016-03-07 12:42:36 +01001137 goto error;
1138 }
PavolVican75af21d2016-12-29 20:04:07 +01001139 dev->type->der = (struct lys_tpdf *)typ;
1140 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001141 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001142 case EXTENSION_INSTANCE:
1143 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1144 typ->type = parent;
1145 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001146 default:
1147 goto error;
1148 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001149 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001150 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001151 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001152
1153error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001154 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001155 free(typ);
1156 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001157}
1158
1159void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001160yang_read_length(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican73e7c992016-02-24 12:18:05 +01001161{
1162 struct lys_restr **length;
1163
Pavol Vican6b072512016-04-04 10:50:21 +02001164 if (typ->base == 0 || typ->base == LY_TYPE_STRING) {
Pavol Vican73e7c992016-02-24 12:18:05 +01001165 length = &typ->type->info.str.length;
Pavol Vican6b072512016-04-04 10:50:21 +02001166 typ->base = LY_TYPE_STRING;
Pavol Vican73e7c992016-02-24 12:18:05 +01001167 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001168 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +01001169 goto error;
1170 }
1171
1172 if (*length) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001173 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001174 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001175 }
1176 *length = calloc(1, sizeof **length);
1177 if (!*length) {
1178 LOGMEM;
1179 goto error;
1180 }
1181 (*length)->expr = lydict_insert_zc(module->ctx, value);
1182 return *length;
1183
1184error:
1185 free(value);
1186 return NULL;
1187
1188}
Pavol Vican1c203db2016-02-24 14:05:23 +01001189
Pavol Vican6eecf302016-08-10 11:09:05 +02001190int
1191yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001192{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001193 char *buf;
1194 size_t len;
1195
Michal Vasko0aee5c12016-06-17 14:27:26 +02001196 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001197 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001198 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001199 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001200
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001201 len = strlen(value);
1202 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Pavol Vican6eecf302016-08-10 11:09:05 +02001203
1204 if (!buf) {
1205 LOGMEM;
1206 free(value);
1207 return EXIT_FAILURE;
1208 }
1209
1210 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001211 strcpy(&buf[1], value);
1212 free(value);
1213
Pavol Vican6eecf302016-08-10 11:09:05 +02001214 pattern->expr = lydict_insert_zc(module->ctx, buf);
1215 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001216}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001217
1218void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001219yang_read_range(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001220{
Pavol Vican6b072512016-04-04 10:50:21 +02001221 if (typ->base != 0 && typ->base != LY_TYPE_DEC64) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001222 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001223 goto error;
1224 }
Pavol Vican6b072512016-04-04 10:50:21 +02001225 typ->base = LY_TYPE_DEC64;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001226 if (typ->type->info.dec64.range) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001227 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001228 goto error;
1229 }
1230 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1231 if (!typ->type->info.dec64.range) {
1232 LOGMEM;
1233 goto error;
1234 }
1235 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1236 return typ->type->info.dec64.range;
1237
1238error:
1239 free(value);
1240 return NULL;
1241}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001242
1243int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001244yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001245{
Pavol Vican6b072512016-04-04 10:50:21 +02001246 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1247 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001248 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001249 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001250 goto error;
1251 }
1252 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001253 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001254 goto error;
1255 }
1256 /* range check */
1257 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001258 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001259 goto error;
1260 }
1261 typ->type->info.dec64.dig = value;
1262 return EXIT_SUCCESS;
1263
1264error:
1265 return EXIT_FAILURE;
1266}
Pavol Vican79a763d2016-02-25 15:41:27 +01001267
Pavol Vican874715f2016-10-25 14:52:08 +02001268int
1269yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001270{
Pavol Vican874715f2016-10-25 14:52:08 +02001271 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001272
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001273 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001274 if (!value[0]) {
1275 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1276 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1277 free(value);
1278 goto error;
1279 }
1280
Pavol Vican79a763d2016-02-25 15:41:27 +01001281 enm->name = lydict_insert_zc(module->ctx, value);
1282
1283 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1284 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001285 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001286 goto error;
1287 }
1288
Pavol Vican874715f2016-10-25 14:52:08 +02001289 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001290 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001291 for (i = 0; i < j; i++) {
1292 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[j].name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001293 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001294 goto error;
1295 }
1296 }
1297
Pavol Vican874715f2016-10-25 14:52:08 +02001298 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001299
1300error:
Pavol Vican874715f2016-10-25 14:52:08 +02001301 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001302}
1303
1304int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001305yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001306{
1307 int i, j;
1308
1309 if (!assign) {
1310 /* assign value automatically */
1311 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001312 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001313 goto error;
1314 }
1315 enm->value = *value;
1316 enm->flags |= LYS_AUTOASSIGNED;
1317 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001318 } else if (typ->type->info.enums.enm == enm) {
1319 /* change value, which is assigned automatically, if first enum has value. */
1320 *value = typ->type->info.enums.enm[0].value;
1321 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001322 }
1323
1324 /* check that the value is unique */
1325 j = typ->type->info.enums.count-1;
1326 for (i = 0; i < j; i++) {
1327 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001328 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001329 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1330 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001331 goto error;
1332 }
1333 }
1334
1335 return EXIT_SUCCESS;
1336
1337error:
1338 return EXIT_FAILURE;
1339}
Pavol Vican9887c682016-02-29 11:32:01 +01001340
Pavol Vican59e8dee2016-10-25 15:29:38 +02001341int
1342yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001343{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001344 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001345
PavolVicane87cb932016-12-30 15:36:18 +01001346 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001347 bit->name = lydict_insert_zc(module->ctx, value);
1348 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001349 free(value);
1350 goto error;
1351 }
Pavol Vican9887c682016-02-29 11:32:01 +01001352
Pavol Vican59e8dee2016-10-25 15:29:38 +02001353 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001354 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001355 for (i = 0; i < j; i++) {
Pavol Vican9887c682016-02-29 11:32:01 +01001356 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001357 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001358 goto error;
1359 }
1360 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001361 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001362
1363error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001364 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001365}
1366
1367int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001368yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001369{
1370 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001371
1372 if (!assign) {
1373 /* assign value automatically */
1374 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001375 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001376 goto error;
1377 }
1378 bit->pos = (uint32_t)*value;
1379 bit->flags |= LYS_AUTOASSIGNED;
1380 (*value)++;
1381 }
1382
1383 j = typ->type->info.bits.count - 1;
1384 /* check that the value is unique */
1385 for (i = 0; i < j; i++) {
1386 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001387 LOGVAL(LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
Pavol Vican9887c682016-02-29 11:32:01 +01001388 goto error;
1389 }
1390 }
1391
Pavol Vican9887c682016-02-29 11:32:01 +01001392 return EXIT_SUCCESS;
1393
1394error:
1395 return EXIT_FAILURE;
1396}
Pavol Vican0df02b02016-03-01 10:28:50 +01001397
Pavol Vican3ad50f82016-12-04 15:00:36 +01001398int
1399yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001400{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001401 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001402 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001403 free(value);
1404 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001405 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001406 }
1407 aug->parent = parent;
1408 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001409 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001410}
Pavol Vican220e5a12016-03-03 14:19:43 +01001411
PavolVican6f000922017-02-10 12:56:59 +01001412void *
PavolVican75af21d2016-12-29 20:04:07 +01001413yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001414{
PavolVican75af21d2016-12-29 20:04:07 +01001415 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001416 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001417 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001418 }
PavolVican75af21d2016-12-29 20:04:07 +01001419 dev->deviate = calloc(1, sizeof *dev->deviate);
PavolVican6f000922017-02-10 12:56:59 +01001420 if (!dev->deviate) {
1421 LOGMEM;
1422 return NULL;
1423 }
PavolVican75af21d2016-12-29 20:04:07 +01001424 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1425 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001426 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001427}
1428
1429void *
PavolVican75af21d2016-12-29 20:04:07 +01001430yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001431{
PavolVican75af21d2016-12-29 20:04:07 +01001432 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001433
PavolVican75af21d2016-12-29 20:04:07 +01001434 if (dev->deviate && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001435 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1436 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001437 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001438 }
PavolVican75af21d2016-12-29 20:04:07 +01001439 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1440 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
1441 if (!deviate) {
1442 LOGMEM;
1443 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001444 }
PavolVican75af21d2016-12-29 20:04:07 +01001445 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1446 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001447 }
PavolVican75af21d2016-12-29 20:04:07 +01001448 dev->deviate[dev->deviate_size].mod = mod;
1449 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001450}
1451
1452int
PavolVican75af21d2016-12-29 20:04:07 +01001453yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001454{
1455 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001456 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001457
Pavol Vican85f12022016-03-05 16:30:35 +01001458 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001459 if (dev_target->nodetype == LYS_LEAFLIST) {
1460 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1461 } else if (dev_target->nodetype == LYS_LEAF) {
1462 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001463 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001464 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1465 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001466 goto error;
1467 }
1468
PavolVican75af21d2016-12-29 20:04:07 +01001469 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001470 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001471 if (!ly_strequal(*stritem, deviate->units, 1)) {
1472 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001473 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001474 goto error;
1475 }
1476 /* remove current units value of the target */
1477 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001478 *stritem = NULL;
1479 /* remove its extensions */
1480 j = -1;
1481 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1482 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1483 --j;
1484 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001485 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001486 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001487 /* check that there is no current value */
1488 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001489 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1490 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001491 goto error;
1492 }
1493 } else { /* replace */
1494 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001495 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1496 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001497 goto error;
1498 }
1499 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001500 /* remove current units value of the target ... */
1501 lydict_remove(ctx, *stritem);
1502
1503 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001504 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001505 }
1506
Pavol Vican85f12022016-03-05 16:30:35 +01001507 return EXIT_SUCCESS;
1508
1509error:
1510 return EXIT_FAILURE;
1511}
1512
1513int
PavolVican75af21d2016-12-29 20:04:07 +01001514yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001515{
Pavol Vican85f12022016-03-05 16:30:35 +01001516 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001517 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001518
1519 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001520 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001521 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1522 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001523 goto error;
1524 }
1525
PavolVican75af21d2016-12-29 20:04:07 +01001526 list = (struct lys_node_list *)dev_target;
1527 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001528 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001529 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
1530 if (!unique) {
Pavol Vican85f12022016-03-05 16:30:35 +01001531 LOGMEM;
1532 goto error;
1533 }
PavolVican75af21d2016-12-29 20:04:07 +01001534 list->unique = unique;
1535 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001536 }
1537
1538 return EXIT_SUCCESS;
1539
1540error:
1541 return EXIT_FAILURE;
1542}
1543
1544int
PavolVican75af21d2016-12-29 20:04:07 +01001545yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1546 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001547{
1548 struct lys_node *node;
1549 struct lys_node_choice *choice;
1550 struct lys_node_leaf *leaf;
1551 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001552 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001553 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001554
Pavol Vican38321d02016-08-16 14:56:02 +02001555 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001556 if (dev_target->nodetype == LYS_CHOICE) {
1557 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001558 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1559 if (rc || !node) {
1560 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1561 goto error;
1562 }
PavolVican75af21d2016-12-29 20:04:07 +01001563 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001564 if (!choice->dflt || (choice->dflt != node)) {
1565 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1566 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1567 goto error;
1568 }
PavolVican6f000922017-02-10 12:56:59 +01001569 choice->dflt = NULL;
1570 /* remove extensions of this default instance from the target node */
1571 j = -1;
1572 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1573 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1574 --j;
1575 }
Pavol Vican38321d02016-08-16 14:56:02 +02001576 } else { /* add or replace */
1577 choice->dflt = node;
1578 if (!choice->dflt) {
1579 /* default branch not found */
1580 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1581 goto error;
1582 }
1583 }
PavolVican75af21d2016-12-29 20:04:07 +01001584 } else if (dev_target->nodetype == LYS_LEAF) {
1585 leaf = (struct lys_node_leaf *)dev_target;
1586 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001587 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1588 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1589 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1590 goto error;
1591 }
1592 /* remove value */
1593 lydict_remove(ctx, leaf->dflt);
1594 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001595 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001596 /* remove extensions of this default instance from the target node */
1597 j = -1;
1598 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1599 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1600 --j;
1601 }
Pavol Vican38321d02016-08-16 14:56:02 +02001602 } else { /* add (already checked) and replace */
1603 /* remove value */
1604 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001605 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001606
1607 /* set new value */
1608 leaf->dflt = lydict_insert(ctx, value, u);
1609
1610 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001611 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001612 }
1613 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001614 llist = (struct lys_node_leaflist *)dev_target;
1615 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001616 /* find and remove the value in target list */
1617 for (i = 0; i < llist->dflt_size; i++) {
1618 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1619 /* match, remove the value */
1620 lydict_remove(llist->module->ctx, llist->dflt[i]);
1621 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001622 /* remove extensions of this default instance from the target node */
1623 j = -1;
1624 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1625 if (dev_target->ext[j]->insubstmt_index == i) {
1626 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1627 --j;
1628 } else if (dev_target->ext[j]->insubstmt_index > i) {
1629 /* decrease the substatement index of the extension because of the changed array of defaults */
1630 dev_target->ext[j]->insubstmt_index--;
1631 }
1632 }
Pavol Vican38321d02016-08-16 14:56:02 +02001633 break;
1634 }
1635 }
1636 if (i == llist->dflt_size) {
1637 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1638 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1639 goto error;
1640 }
1641 } else {
1642 /* add or replace, anyway we place items into the deviate's list
1643 which propagates to the target */
1644 /* we just want to check that the value isn't already in the list */
1645 for (i = 0; i < llist->dflt_size; i++) {
1646 if (ly_strequal(llist->dflt[i], value, 1)) {
1647 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1648 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1649 goto error;
1650 }
1651 }
1652 /* store it in target node */
1653 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1654
1655 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001656 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001657 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001658 }
1659 }
1660
1661 return EXIT_SUCCESS;
1662error:
1663 return EXIT_FAILURE;
1664}
1665
Pavol Vican38321d02016-08-16 14:56:02 +02001666int
PavolVican75af21d2016-12-29 20:04:07 +01001667yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1668 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001669{
PavolVican75af21d2016-12-29 20:04:07 +01001670 int i;
1671 struct lys_node_leaflist *llist;
1672 const char **dflt;
1673
1674 /* check target node type */
1675 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1676 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1677 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1678 goto error;
1679 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1680 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1681 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1682 goto error;
1683 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1684 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1685 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001686 goto error;
1687 }
1688
PavolVican75af21d2016-12-29 20:04:07 +01001689 if (deviate->mod == LY_DEVIATE_ADD) {
1690 /* check that there is no current value */
1691 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1692 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1693 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1694 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1695 goto error;
1696 }
Pavol Vican85f12022016-03-05 16:30:35 +01001697
PavolVican75af21d2016-12-29 20:04:07 +01001698 /* check collision with mandatory/min-elements */
1699 if ((dev_target->flags & LYS_MAND_TRUE) ||
1700 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1701 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1702 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1703 "Adding the \"default\" statement is forbidden on %s statement.",
1704 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1705 goto error;
1706 }
1707 } else if (deviate->mod == LY_DEVIATE_RPL) {
1708 /* check that there was a value before */
1709 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1710 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1711 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1712 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1713 goto error;
1714 }
1715 }
Pavol Vican85f12022016-03-05 16:30:35 +01001716
PavolVican75af21d2016-12-29 20:04:07 +01001717 if (dev_target->nodetype == LYS_LEAFLIST) {
1718 /* reallocate default list in the target */
1719 llist = (struct lys_node_leaflist *)dev_target;
1720 if (deviate->mod == LY_DEVIATE_ADD) {
1721 /* reallocate (enlarge) the unique array of the target */
1722 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
1723 if (!dflt) {
1724 LOGMEM;
1725 goto error;
1726 }
1727 llist->dflt = dflt;
1728 } else if (deviate->mod == LY_DEVIATE_RPL) {
1729 /* reallocate (replace) the unique array of the target */
1730 for (i = 0; i < llist->dflt_size; i++) {
1731 lydict_remove(llist->module->ctx, llist->dflt[i]);
1732 }
1733 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
1734 if (!dflt) {
1735 LOGMEM;
1736 goto error;
1737 }
1738 llist->dflt = dflt;
1739 llist->dflt_size = 0;
1740 }
1741 }
1742
1743 for (i = 0; i < deviate->dflt_size; ++i) {
1744 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1745 goto error;
1746 }
1747 }
Pavol Vican85f12022016-03-05 16:30:35 +01001748
1749 return EXIT_SUCCESS;
1750
1751error:
1752 return EXIT_FAILURE;
1753}
1754
1755int
PavolVican75af21d2016-12-29 20:04:07 +01001756yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001757{
Radek Krejcie00d2312016-08-12 15:27:49 +02001758 struct lys_node *parent;
1759
Pavol Vican85f12022016-03-05 16:30:35 +01001760 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001761 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001762 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1763 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001764 goto error;
1765 }
1766
PavolVican75af21d2016-12-29 20:04:07 +01001767 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001768 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001769 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001770 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1771 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001772 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001773 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001774 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001775 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1776 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1777 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1778 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001779 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001780 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1781 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1782 goto error;
1783 }
Pavol Vican85f12022016-03-05 16:30:35 +01001784 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001785 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001786 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001787 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1788 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001789 goto error;
1790 }
Pavol Vican85f12022016-03-05 16:30:35 +01001791 }
1792
Pavol Vican85f12022016-03-05 16:30:35 +01001793 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001794 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001795
1796 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001797 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001798
Radek Krejcie00d2312016-08-12 15:27:49 +02001799 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001800 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001801 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1802 parent = parent->parent) {
1803 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1804 /* stop also on presence containers */
1805 break;
1806 }
1807 }
1808 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1809 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1810 if (lyp_check_mandatory_choice(parent)) {
1811 goto error;
1812 }
1813 }
1814
Pavol Vican85f12022016-03-05 16:30:35 +01001815 return EXIT_SUCCESS;
1816
1817error:
1818 return EXIT_FAILURE;
1819}
1820
1821int
PavolVican75af21d2016-12-29 20:04:07 +01001822yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001823{
Pavol Vican09adcc32016-08-25 10:51:36 +02001824 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001825
1826 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001827 if (dev_target->nodetype == LYS_LEAFLIST) {
1828 max = &((struct lys_node_leaflist *)dev_target)->max;
1829 min = &((struct lys_node_leaflist *)dev_target)->min;
1830 } else if (dev_target->nodetype == LYS_LIST) {
1831 max = &((struct lys_node_list *)dev_target)->max;
1832 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001833 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001834 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1835 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 +01001836 goto error;
1837 }
1838
PavolVican75af21d2016-12-29 20:04:07 +01001839 ui32val = (type) ? max : min;
1840 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001841 /* check that there is no current value */
1842 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001843 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1844 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001845 goto error;
1846 }
PavolVican75af21d2016-12-29 20:04:07 +01001847 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001848 /* unfortunately, there is no way to check reliably that there
1849 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001850 }
1851
1852 /* add (already checked) and replace */
1853 /* set new value specified in deviation */
1854 *ui32val = value;
1855
Pavol Vican09adcc32016-08-25 10:51:36 +02001856 /* check min-elements is smaller than max-elements */
1857 if (*max && *min > *max) {
1858 if (type) {
1859 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1860 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1861 } else {
1862 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1863 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1864 }
1865 goto error;
1866 }
1867
Pavol Vican85f12022016-03-05 16:30:35 +01001868 return EXIT_SUCCESS;
1869
1870error:
1871 return EXIT_FAILURE;
1872}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001873
1874int
PavolVican75af21d2016-12-29 20:04:07 +01001875yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1876 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001877{
PavolVican75af21d2016-12-29 20:04:07 +01001878 int i, j, erase_must = 1;
1879 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001880 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001881
PavolVican75af21d2016-12-29 20:04:07 +01001882 /* check target node type */
1883 switch (dev_target->nodetype) {
1884 case LYS_LEAF:
1885 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1886 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001887 break;
PavolVican75af21d2016-12-29 20:04:07 +01001888 case LYS_CONTAINER:
1889 trg_must = &((struct lys_node_container *)dev_target)->must;
1890 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1891 break;
1892 case LYS_LEAFLIST:
1893 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1894 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1895 break;
1896 case LYS_LIST:
1897 trg_must = &((struct lys_node_list *)dev_target)->must;
1898 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1899 break;
1900 case LYS_ANYXML:
1901 case LYS_ANYDATA:
1902 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1903 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1904 break;
1905 default:
1906 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1907 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1908 goto error;
1909 }
1910
1911 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001912 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001913
1914 if (deviate->mod == LY_DEVIATE_ADD) {
1915 /* reallocate the must array of the target */
1916 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
1917 if (!must) {
1918 LOGMEM;
1919 goto error;
1920 }
1921 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001922 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001923 free(deviate->must);
1924 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001925 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001926 erase_must = 0;
1927 } else if (deviate->mod == LY_DEVIATE_DEL) {
1928 /* find must to delete, we are ok with just matching conditions */
1929 for (j = 0; j < deviate->must_size; ++j) {
1930 for (i = 0; i < *trg_must_size; i++) {
1931 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1932 /* we have a match, free the must structure ... */
1933 lys_restr_free(module->ctx, &((*trg_must)[i]));
1934 /* ... and maintain the array */
1935 (*trg_must_size)--;
1936 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001937 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001938 }
1939 if (!(*trg_must_size)) {
1940 free(*trg_must);
1941 *trg_must = NULL;
1942 } else {
PavolVican214408f2017-02-03 11:54:05 +01001943 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001944 }
1945
1946 i = -1; /* set match flag */
1947 break;
1948 }
1949 }
1950 if (i != -1) {
1951 /* no match found */
1952 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1953 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1954 goto error;
1955 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001956 }
1957 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001958
PavolVican6f000922017-02-10 12:56:59 +01001959 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1960 goto error;
1961 }
PavolVican75af21d2016-12-29 20:04:07 +01001962 /* check XPath dependencies */
1963 if (*trg_must_size && unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001964 goto error;
1965 }
1966
PavolVican75af21d2016-12-29 20:04:07 +01001967 return EXIT_SUCCESS;
1968error:
1969 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1970 for (i = 0; i < deviate->must_size; ++i) {
1971 lys_restr_free(module->ctx, &deviate->must[i]);
1972 }
1973 free(deviate->must);
1974 }
1975 return EXIT_FAILURE;
1976}
1977
1978int
1979yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1980 struct lys_node_list *list, int index, char * value)
1981{
PavolVican6f000922017-02-10 12:56:59 +01001982 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001983
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001984 /* find unique structures to delete */
1985 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001986 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001987 continue;
1988 }
1989
PavolVican75af21d2016-12-29 20:04:07 +01001990 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1991 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001992 break;
1993 }
1994 }
1995
PavolVican75af21d2016-12-29 20:04:07 +01001996 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001997 /* we have a match, free the unique structure ... */
1998 for (j = 0; j < list->unique[i].expr_size; j++) {
1999 lydict_remove(module->ctx, list->unique[i].expr[j]);
2000 }
2001 free(list->unique[i].expr);
2002 /* ... and maintain the array */
2003 list->unique_size--;
2004 if (i != list->unique_size) {
2005 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
2006 list->unique[i].expr = list->unique[list->unique_size].expr;
2007 }
2008
2009 if (!list->unique_size) {
2010 free(list->unique);
2011 list->unique = NULL;
2012 } else {
2013 list->unique[list->unique_size].expr_size = 0;
2014 list->unique[list->unique_size].expr = NULL;
2015 }
2016
PavolVican6f000922017-02-10 12:56:59 +01002017 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002018 i = -1; /* set match flag */
2019 break;
2020 }
2021 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002022
2023 if (i != -1) {
2024 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01002025 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
2026 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01002027 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002028 }
2029
PavolVican6f000922017-02-10 12:56:59 +01002030 /* remove extensions of this unique instance from the target node */
2031 j = -1;
2032 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
2033 if (list->ext[j]->insubstmt_index == k) {
2034 lyp_ext_instance_rm(module->ctx, &list->ext, &list->ext_size, j);
2035 --j;
2036 } else if (list->ext[j]->insubstmt_index > k) {
2037 /* decrease the substatement index of the extension because of the changed array of uniques */
2038 list->ext[j]->insubstmt_index--;
2039 }
2040 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002041 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002042}
Pavol Vican021488a2016-01-25 23:56:12 +01002043
PavolVican75af21d2016-12-29 20:04:07 +01002044int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01002045{
PavolVican75af21d2016-12-29 20:04:07 +01002046 struct lys_node_list *list;
2047 char *str;
2048 uint i;
2049 struct lys_unique *last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002050
PavolVican75af21d2016-12-29 20:04:07 +01002051 if (yang_read_deviate_unique(deviate, dev_target)) {
2052 goto error;
2053 }
2054 list = (struct lys_node_list *)dev_target;
2055 last_unique = &list->unique[list->unique_size];
2056 for (i = 0; i < deviate->unique_size; ++i) {
2057 str = (char *) deviate->unique[i].expr;
2058 if (deviate->mod == LY_DEVIATE_ADD) {
2059 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2060 free(str);
2061 goto error;
2062 }
2063 list->unique_size++;
2064 } else if (deviate->mod == LY_DEVIATE_DEL) {
2065 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2066 free(str);
2067 goto error;
2068 }
2069 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2070 free(str);
2071 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002072 }
2073 }
PavolVican75af21d2016-12-29 20:04:07 +01002074 free(str);
2075 }
2076 if (deviate->mod == LY_DEVIATE_ADD) {
2077 free(deviate->unique);
2078 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002079 }
Pavol Vican38321d02016-08-16 14:56:02 +02002080
Pavol Vican38321d02016-08-16 14:56:02 +02002081
PavolVican75af21d2016-12-29 20:04:07 +01002082 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002083error:
PavolVican75af21d2016-12-29 20:04:07 +01002084 if (deviate->mod == LY_DEVIATE_ADD) {
2085 for (i = i + 1; i < deviate->unique_size; ++i) {
2086 free(deviate->unique[i].expr);
2087 }
2088 free(deviate->unique);
2089 deviate->unique = last_unique;
2090
2091 }
Pavol Vican021488a2016-01-25 23:56:12 +01002092 return EXIT_FAILURE;
2093}
2094
Pavol Vicanec423c92016-10-24 21:33:43 +02002095static int
2096yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2097 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002098{
Pavol Vican55870412016-03-10 12:36:21 +01002099 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002100 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002101 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002102
Pavol Vicanec423c92016-10-24 21:33:43 +02002103 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002104 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002105 if (!rc) {
2106 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002107 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002108 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2109 &trg->inc[trg->inc_size], unres)) {
2110 ret = -1;
2111 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002112 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002113 } else if (rc == -1) {
PavolVican7d0b5ab2017-02-01 13:06:53 +01002114 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002115 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002116 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002117
Pavol Vicanec423c92016-10-24 21:33:43 +02002118 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002119 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002120}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002121
PavolVicanc1807262017-01-31 18:00:27 +01002122struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002123yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002124{
2125 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2126 LYEXT_PAR parent_type;
2127 uint8_t *size;
2128
2129 switch (type) {
2130 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002131 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002132 ext = &((struct lys_module *)node)->ext;
2133 size = &((struct lys_module *)node)->ext_size;
2134 parent_type = LYEXT_PAR_MODULE;
2135 break;
PavolVican22e88682017-02-14 22:38:18 +01002136 case BELONGS_TO_KEYWORD:
2137 if (is_ext_instance) {
2138 ext = &((struct lys_ext_instance *)node)->ext;
2139 size = &((struct lys_ext_instance *)node)->ext_size;
2140 parent_type = LYEXT_PAR_EXTINST;
2141 } else {
2142 ext = &((struct lys_module *)node)->ext;
2143 size = &((struct lys_module *)node)->ext_size;
2144 parent_type = LYEXT_PAR_MODULE;
2145 }
2146 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002147 case IMPORT_KEYWORD:
2148 ext = &((struct lys_import *)node)->ext;
2149 size = &((struct lys_import *)node)->ext_size;
2150 parent_type = LYEXT_PAR_IMPORT;
2151 break;
2152 case INCLUDE_KEYWORD:
2153 ext = &((struct lys_include *)node)->ext;
2154 size = &((struct lys_include *)node)->ext_size;
2155 parent_type = LYEXT_PAR_INCLUDE;
2156 break;
PavolVican171717d2017-02-01 14:49:55 +01002157 case REVISION_KEYWORD:
2158 ext = &((struct lys_revision *)node)->ext;
2159 size = &((struct lys_revision *)node)->ext_size;
2160 parent_type = LYEXT_PAR_REVISION;
2161 break;
PavolVican70ce7452017-02-01 15:39:39 +01002162 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002163 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002164 case LEAF_KEYWORD:
2165 case LEAF_LIST_KEYWORD:
2166 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002167 case CHOICE_KEYWORD:
2168 case CASE_KEYWORD:
2169 case ANYXML_KEYWORD:
2170 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002171 case USES_KEYWORD:
2172 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002173 case ACTION_KEYWORD:
2174 case RPC_KEYWORD:
2175 case INPUT_KEYWORD:
2176 case OUTPUT_KEYWORD:
2177 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002178 ext = &((struct lys_node *)node)->ext;
2179 size = &((struct lys_node *)node)->ext_size;
2180 parent_type = LYEXT_PAR_NODE;
2181 break;
PavolVican19dc6152017-02-06 12:04:15 +01002182 case ARGUMENT_KEYWORD:
2183 case EXTENSION_KEYWORD:
2184 ext = &((struct lys_ext *)node)->ext;
2185 size = &((struct lys_ext *)node)->ext_size;
2186 parent_type = LYEXT_PAR_EXT;
2187 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002188 case FEATURE_KEYWORD:
2189 ext = &((struct lys_feature *)node)->ext;
2190 size = &((struct lys_feature *)node)->ext_size;
2191 parent_type = LYEXT_PAR_FEATURE;
2192 break;
PavolVican8fa31242017-02-07 11:04:26 +01002193 case IDENTITY_KEYWORD:
2194 ext = &((struct lys_ident *)node)->ext;
2195 size = &((struct lys_ident *)node)->ext_size;
2196 parent_type = LYEXT_PAR_IDENT;
2197 break;
2198 case IF_FEATURE_KEYWORD:
2199 ext = &((struct lys_iffeature *)node)->ext;
2200 size = &((struct lys_iffeature *)node)->ext_size;
2201 parent_type = LYEXT_PAR_IFFEATURE;
2202 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002203 case TYPEDEF_KEYWORD:
2204 ext = &((struct lys_tpdf *)node)->ext;
2205 size = &((struct lys_tpdf *)node)->ext_size;
2206 parent_type = LYEXT_PAR_TPDF;
2207 break;
PavolVican056fcd12017-02-07 15:36:53 +01002208 case TYPE_KEYWORD:
2209 ext = &((struct yang_type *)node)->type->ext;
2210 size = &((struct yang_type *)node)->type->ext_size;
2211 parent_type = LYEXT_PAR_TYPE;
2212 break;
2213 case LENGTH_KEYWORD:
2214 case PATTERN_KEYWORD:
2215 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002216 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002217 ext = &((struct lys_restr *)node)->ext;
2218 size = &((struct lys_restr *)node)->ext_size;
2219 parent_type = LYEXT_PAR_RESTR;
2220 break;
PavolVican59ba4602017-02-08 11:53:32 +01002221 case WHEN_KEYWORD:
2222 ext = &((struct lys_when *)node)->ext;
2223 size = &((struct lys_when *)node)->ext_size;
2224 parent_type = LYEXT_PAR_RESTR;
2225 break;
PavolVican056fcd12017-02-07 15:36:53 +01002226 case ENUM_KEYWORD:
2227 ext = &((struct lys_type_enum *)node)->ext;
2228 size = &((struct lys_type_enum *)node)->ext_size;
2229 parent_type = LYEXT_PAR_TYPE_ENUM;
2230 break;
2231 case BIT_KEYWORD:
2232 ext = &((struct lys_type_bit *)node)->ext;
2233 size = &((struct lys_type_bit *)node)->ext_size;
2234 parent_type = LYEXT_PAR_TYPE_BIT;
2235 break;
PavolVican77374ee2017-02-08 15:18:45 +01002236 case REFINE_KEYWORD:
2237 ext = &((struct lys_type_bit *)node)->ext;
2238 size = &((struct lys_type_bit *)node)->ext_size;
2239 parent_type = LYEXT_PAR_REFINE;
2240 break;
PavolVican6f000922017-02-10 12:56:59 +01002241 case DEVIATION_KEYWORD:
2242 ext = &((struct lys_deviation *)node)->ext;
2243 size = &((struct lys_deviation *)node)->ext_size;
2244 parent_type = LYEXT_PAR_DEVIATION;
2245 break;
2246 case NOT_SUPPORTED_KEYWORD:
2247 case ADD_KEYWORD:
2248 case DELETE_KEYWORD:
2249 case REPLACE_KEYWORD:
2250 ext = &((struct lys_deviate *)node)->ext;
2251 size = &((struct lys_deviate *)node)->ext_size;
2252 parent_type = LYEXT_PAR_DEVIATE;
2253 break;
PavolVicandefa4852017-02-10 13:13:23 +01002254 case EXTENSION_INSTANCE:
2255 ext = &((struct lys_ext_instance *)node)->ext;
2256 size = &((struct lys_ext_instance *)node)->ext_size;
2257 parent_type = LYEXT_PAR_EXTINST;
2258 break;
PavolVicanc1807262017-01-31 18:00:27 +01002259 default:
2260 LOGINT;
2261 return NULL;
2262 }
2263
2264 instance = calloc(1, sizeof *instance);
2265 if (!instance) {
2266 goto error;
2267 }
2268 instance->parent_type = parent_type;
2269 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2270 if (!tmp) {
2271 goto error;
2272 }
2273 tmp[*size] = instance;
2274 *ext = tmp;
2275 (*size)++;
2276 return instance;
2277
2278error:
2279 LOGMEM;
2280 free(instance);
2281 return NULL;
2282}
2283
2284void *
2285yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002286 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002287{
2288 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002289 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002290
2291 if (backup_type != NODE) {
PavolVican22e88682017-02-14 22:38:18 +01002292 instance = yang_ext_instance((actual) ? actual : module, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002293 if (!instance) {
2294 return NULL;
2295 }
PavolVicanc1807262017-01-31 18:00:27 +01002296 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002297 case YANG_VERSION_KEYWORD:
2298 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002299 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002300 break;
PavolVicanc1807262017-01-31 18:00:27 +01002301 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002302 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002303 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002304 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002305 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002306 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002307 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002308 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002309 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002310 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002311 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002312 break;
2313 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002314 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002315 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002316 break;
2317 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002318 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002319 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002320 break;
PavolVican171717d2017-02-01 14:49:55 +01002321 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002322 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002323 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002324 break;
2325 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002326 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002327 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002328 break;
PavolVican19dc6152017-02-06 12:04:15 +01002329 case YIN_ELEMENT_KEYWORD:
2330 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002331 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002332 break;
2333 case STATUS_KEYWORD:
2334 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002335 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002336 break;
PavolVican8fa31242017-02-07 11:04:26 +01002337 case BASE_KEYWORD:
2338 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002339 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002340 if (backup_type == IDENTITY_KEYWORD) {
2341 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002342 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002343 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2344 }
PavolVican8fa31242017-02-07 11:04:26 +01002345 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002346 case DEFAULT_KEYWORD:
2347 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002348 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002349 switch (backup_type) {
2350 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002351 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002352 break;
2353 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002354 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002355 break;
2356 case ADD_KEYWORD:
2357 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2358 break;
2359 default:
2360 /* nothing changes */
2361 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002362 }
PavolVicandf9e7972017-02-07 11:41:38 +01002363 break;
2364 case UNITS_KEYWORD:
2365 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002366 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002367 break;
PavolVican056fcd12017-02-07 15:36:53 +01002368 case REQUIRE_INSTANCE_KEYWORD:
2369 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002370 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002371 break;
2372 case PATH_KEYWORD:
2373 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002374 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002375 break;
2376 case ERROR_MESSAGE_KEYWORD:
2377 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002378 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002379 break;
2380 case ERROR_APP_TAG_KEYWORD:
2381 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002382 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002383 break;
2384 case MODIFIER_KEYWORD:
2385 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002386 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002387 break;
2388 case FRACTION_DIGITS_KEYWORD:
2389 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002390 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002391 break;
2392 case VALUE_KEYWORD:
2393 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002394 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002395 break;
2396 case POSITION_KEYWORD:
2397 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002398 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002399 break;
PavolVican5b910842017-02-08 13:08:47 +01002400 case PRESENCE_KEYWORD:
2401 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002402 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002403 break;
2404 case CONFIG_KEYWORD:
2405 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002406 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002407 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002408 case MANDATORY_KEYWORD:
2409 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002410 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002411 break;
2412 case MIN_ELEMENTS_KEYWORD:
2413 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002414 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002415 break;
2416 case MAX_ELEMENTS_KEYWORD:
2417 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002418 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002419 break;
2420 case ORDERED_BY_KEYWORD:
2421 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002422 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002423 break;
2424 case KEY_KEYWORD:
2425 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002426 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002427 break;
2428 case UNIQUE_KEYWORD:
2429 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002430 stmt = LY_STMT_UNIQUE;
2431 switch (backup_type) {
2432 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002433 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002434 break;
2435 case ADD_KEYWORD:
2436 case DELETE_KEYWORD:
2437 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002438 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002439 break;
2440 default:
2441 /* nothing changes */
2442 break;
PavolVican6f000922017-02-10 12:56:59 +01002443 }
PavolVican3feb2f92017-02-08 13:44:39 +01002444 break;
PavolVicanc1807262017-01-31 18:00:27 +01002445 default:
2446 LOGINT;
2447 return NULL;
2448 }
2449 } else {
PavolVican22e88682017-02-14 22:38:18 +01002450 instance = yang_ext_instance((actual) ? actual : module, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002451 if (!instance) {
2452 return NULL;
2453 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002454 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002455 switch (actual_type) {
2456 case ARGUMENT_KEYWORD:
2457 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002458 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002459 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002460 case BELONGS_TO_KEYWORD:
2461 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002462 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002463 break;
PavolVican19dc6152017-02-06 12:04:15 +01002464 default:
2465 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2466 break;
2467 }
PavolVicanc1807262017-01-31 18:00:27 +01002468 }
2469 instance->flags |= LYEXT_OPT_YANG;
2470 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2471 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002472 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2473 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2474 }
PavolVicanc1807262017-01-31 18:00:27 +01002475 return instance;
2476}
2477
Pavol Vicanf4717e62016-03-16 11:30:01 +01002478int
Pavol Vican0adf01d2016-03-22 12:29:33 +01002479yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value)
Pavol Vicanf4717e62016-03-16 11:30:01 +01002480{
2481 char *prefix;
2482 char *identif;
2483 const char *ns = NULL;
2484 int i;
2485
Pavol Vicanf4717e62016-03-16 11:30:01 +01002486 /* check to the same pointer */
2487 if (data_node != actual) {
2488 return EXIT_SUCCESS;
2489 }
2490
Pavol Vicana302aa62016-03-17 10:45:35 +01002491 prefix = strdup(value);
2492 if (!prefix) {
2493 LOGMEM;
2494 goto error;
2495 }
2496 /* find prefix anf identificator*/
2497 identif = strchr(prefix, ':');
Pavol Vicanfbd02782016-08-29 11:14:45 +02002498 if (!identif) {
2499 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, prefix);
2500 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The extension must have prefix.");
2501 goto error;
2502 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002503 *identif = '\0';
2504 identif++;
2505
Pavol Vicanf4717e62016-03-16 11:30:01 +01002506 for(i = 0; i < module->imp_size; ++i) {
2507 if (!strcmp(module->imp[i].prefix, prefix)) {
2508 ns = module->imp[i].module->ns;
2509 break;
2510 }
2511 }
Pavol Vican1ff1b7b2016-04-07 09:51:49 +02002512 if (!ns && !strcmp(module->prefix, prefix)) {
2513 ns = (module->type) ? ((struct lys_submodule *)module)->belongsto->ns : module->ns;
2514 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002515 free(prefix);
Pavol Vicanf4717e62016-03-16 11:30:01 +01002516 return EXIT_SUCCESS;
Pavol Vicana302aa62016-03-17 10:45:35 +01002517
2518error:
2519 free(prefix);
2520 return EXIT_FAILURE;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002521}
2522
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002523int
Pavol Vican1dac40c2016-09-28 11:39:26 +02002524store_flags(struct lys_node *node, uint8_t flags, int config_opt)
Pavol Vican4fb66c92016-03-17 10:32:27 +01002525{
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002526 struct lys_node *elem;
2527
Pavol Vican1dac40c2016-09-28 11:39:26 +02002528 node->flags |= (config_opt == CONFIG_IGNORE) ? flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET)): flags;
2529 if (config_opt == CONFIG_INHERIT_ENABLE) {
2530 if (!(node->flags & LYS_CONFIG_MASK)) {
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002531 /* get config flag from parent */
Radek Krejcif71f48f2016-10-25 16:37:24 +02002532 if (node->parent) {
2533 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002534 } else {
2535 /* default config is true */
2536 node->flags |= LYS_CONFIG_W;
2537 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002538 } else {
Pavol Vican1dac40c2016-09-28 11:39:26 +02002539 /* do we even care about config flags? */
2540 for (elem = node; elem && !(elem->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT | LYS_RPC)); elem = elem->parent);
Michal Vaskoe10d14a2016-08-26 15:17:13 +02002541
Pavol Vican1dac40c2016-09-28 11:39:26 +02002542 if (!elem && (node->flags & LYS_CONFIG_W) && node->parent && (node->parent->flags & LYS_CONFIG_R)) {
2543 LOGVAL(LYE_INARG, LY_VLOG_LYS, node, "true", "config");
Michal Vasko51e5c582017-01-19 14:16:39 +01002544 LOGVAL(LYE_SPEC, LY_VLOG_PREV, NULL, "State nodes cannot have configuration nodes as children.");
Pavol Vican1dac40c2016-09-28 11:39:26 +02002545 return EXIT_FAILURE;
2546 }
Pavol Vican4fb66c92016-03-17 10:32:27 +01002547 }
2548 }
Michal Vaskoe1e351e2016-08-25 12:13:39 +02002549
2550 return EXIT_SUCCESS;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002551}
Pavol Vican8e7110b2016-03-22 17:00:26 +01002552
Pavol Vicanec598812016-11-30 14:13:38 +01002553int
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002554store_config_flag(struct lys_node *node, int config_opt)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002555{
Pavol Vicanec598812016-11-30 14:13:38 +01002556 int ret = config_opt;
Pavol Vican1938d882016-04-10 13:36:31 +02002557
Pavol Vicanec598812016-11-30 14:13:38 +01002558 switch (node->nodetype) {
2559 case LYS_CONTAINER:
2560 case LYS_LEAF:
2561 case LYS_LEAFLIST:
2562 case LYS_LIST:
2563 case LYS_CHOICE:
2564 case LYS_ANYDATA:
2565 case LYS_ANYXML:
2566 if (config_opt == CONFIG_IGNORE) {
2567 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
2568 } else if (config_opt == CONFIG_INHERIT_ENABLE) {
2569 if (!(node->flags & LYS_CONFIG_MASK)) {
2570 /* get config flag from parent */
2571 if (node->parent) {
2572 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2573 } else {
2574 /* default config is true */
2575 node->flags |= LYS_CONFIG_W;
2576 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002577 }
2578 }
Pavol Vicanec598812016-11-30 14:13:38 +01002579 break;
2580 case LYS_CASE:
2581 if (config_opt == CONFIG_INHERIT_ENABLE) {
2582 if (!(node->flags & LYS_CONFIG_MASK)) {
2583 /* get config flag from parent */
2584 if (node->parent) {
2585 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2586 } else {
2587 /* default config is true */
2588 node->flags |= LYS_CONFIG_W;
2589 }
2590 }
2591 }
2592 break;
2593 case LYS_RPC:
2594 case LYS_ACTION:
2595 case LYS_NOTIF:
2596 ret = CONFIG_IGNORE;
2597 break;
2598 default:
2599 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002600 }
Pavol Vicanec598812016-11-30 14:13:38 +01002601
Pavol Vican1938d882016-04-10 13:36:31 +02002602 return ret;
2603}
2604
2605int
Pavol Vican9d50a772016-10-14 22:23:36 +02002606yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2607 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002608{
Pavol Vican974377b2016-03-23 00:38:53 +01002609 unsigned int size;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002610 YY_BUFFER_STATE bp;
2611 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002612 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002613 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002614 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002615
Pavol Vican8e7110b2016-03-22 17:00:26 +01002616 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002617 yylex_init(&scanner);
2618 bp = yy_scan_buffer((char *)data, size, scanner);
2619 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002620 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002621 param.module = module;
2622 param.submodule = submodule;
2623 param.unres = unres;
2624 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002625 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002626 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002627 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002628 trg = (submodule) ? (struct lys_module *)submodule : module;
2629 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2630 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2631 trg->inc_size = 0;
2632 trg->imp_size = 0;
2633 }
PavolVican22e88682017-02-14 22:38:18 +01002634 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2635 }
2636 yy_delete_buffer(bp, scanner);
2637 yylex_destroy(scanner);
2638 return ret;
2639}
2640
2641int
2642yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2643 char *ext_name, struct lys_ext_instance_complex *ext)
2644{
2645 unsigned int size;
2646 YY_BUFFER_STATE bp;
2647 yyscan_t scanner = NULL;
2648 int ret = 0;
2649 struct yang_parameter param;
2650
2651 size = strlen(data) + 2;
2652 yylex_init(&scanner);
2653 bp = yy_scan_buffer((char *)data, size, scanner);
2654 yy_switch_to_buffer(bp, scanner);
2655 memset(&param, 0, sizeof param);
2656 param.module = module;
2657 param.unres = unres;
2658 param.actual_node = (void **)ext;
2659 param.data_node = (void **)ext_name;
2660 param.flags |= EXT_INSTANCE_SUBSTMT;
2661 if (yyparse(scanner, &param)) {
2662 ret = -1;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002663 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002664 yy_delete_buffer(bp, scanner);
2665 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002666 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002667}
2668
2669struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002670yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002671{
2672
PavolVican9e81c6a2017-02-09 13:09:07 +01002673 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002674 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002675 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002676 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002677
2678 unres = calloc(1, sizeof *unres);
2679 if (!unres) {
2680 LOGMEM;
2681 goto error;
2682 }
2683
2684 module = calloc(1, sizeof *module);
2685 if (!module) {
2686 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002687 goto error;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002688 }
2689
2690 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002691 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002692 module->type = 0;
2693 module->implemented = (implement ? 1 : 0);
2694
PavolVican9e81c6a2017-02-09 13:09:07 +01002695 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2696 if (ret == -1) {
Pavol Vican05810b62016-11-23 14:07:22 +01002697 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002698 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002699 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002700 assert(!unres->count);
2701 } else {
2702 if (yang_check_sub_module(module, unres, node)) {
2703 goto error;
2704 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002705
Michal Vasko7b460e52017-02-10 14:50:26 +01002706 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002707 goto error;
2708 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002709 }
2710
2711 if (revision) {
2712 /* check revision of the parsed model */
2713 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2714 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2715 module->name, module->rev[0].date, revision);
2716 goto error;
2717 }
2718 }
2719
PavolVican9e81c6a2017-02-09 13:09:07 +01002720 /* add into context if not already there */
2721 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002722 /* check correctness of includes */
2723 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002724 goto error;
2725 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002726
PavolVicanfd6f6952017-02-14 00:09:42 +01002727 /* remove our submodules from the parsed submodules list */
2728 lyp_del_includedup(module);
2729
2730
PavolVican6f000922017-02-10 12:56:59 +01002731 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002732 goto error;
2733 }
2734
PavolVican9e81c6a2017-02-09 13:09:07 +01002735 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002736 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002737 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002738
2739 if (module->deviation_size && !module->implemented) {
2740 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2741 /* deviations always causes target to be made implemented,
2742 * but augents and leafrefs not, so we have to apply them now */
2743 if (lys_set_implemented(module)) {
2744 goto error;
2745 }
2746 }
2747 } else {
2748 tmp_mod = module;
2749
2750 /* get the model from the context */
2751 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision);
2752 assert(module);
2753
2754 /* free what was parsed */
2755 lys_free(tmp_mod, NULL, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002756 }
2757
Pavol Vican8e7110b2016-03-22 17:00:26 +01002758 unres_schema_free(NULL, &unres);
2759 LOGVRB("Module \"%s\" successfully parsed.", module->name);
2760 return module;
2761
2762error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002763 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002764 unres_schema_free(module, &unres);
2765 if (!module || !module->name) {
2766 free(module);
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002767 if (ly_vecode != LYVE_SUBMODULE) {
2768 LOGERR(ly_errno, "Module parsing failed.");
2769 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002770 return NULL;
2771 }
2772
2773 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002774
Michal Vaskocf0489e2017-02-13 11:57:45 +01002775 lyp_del_includedup(module);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002776 lys_sub_module_remove_devs_augs(module);
2777 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002778 return NULL;
2779}
2780
2781struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002782yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002783{
2784 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002785 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002786
2787 submodule = calloc(1, sizeof *submodule);
2788 if (!submodule) {
2789 LOGMEM;
2790 goto error;
2791 }
2792
2793 submodule->ctx = module->ctx;
2794 submodule->type = 1;
2795 submodule->belongsto = module;
2796
PavolVican9e81c6a2017-02-09 13:09:07 +01002797 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002798 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002799 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002800 goto error;
2801 }
2802
2803 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002804 goto error;
2805 }
2806
Pavol Vican8e7110b2016-03-22 17:00:26 +01002807 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002808 return submodule;
2809
2810error:
2811 /* cleanup */
2812 unres_schema_free((struct lys_module *)submodule, &unres);
2813
2814 if (!submodule || !submodule->name) {
2815 free(submodule);
2816 LOGERR(ly_errno, "Submodule parsing failed.");
2817 return NULL;
2818 }
2819
2820 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2821
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002822 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2823 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002824 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002825 return NULL;
2826}
Pavol Vican8760bb72016-04-07 09:44:01 +02002827
2828static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002829read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2830{
2831 int k = 0, j;
2832
2833 while (in_index < size) {
2834 if (input[in_index] == ' ') {
2835 k++;
2836 } else if (input[in_index] == '\t') {
2837 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2838 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002839 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2840 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2841 k += 8;
2842 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002843 } else {
2844 break;
2845 }
2846 ++in_index;
2847 if (k >= indent) {
2848 for (j = k - indent; j > 0; --j) {
2849 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002850 if (j > 1) {
2851 ++(*out_index);
2852 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002853 }
2854 break;
2855 }
2856 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002857 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002858}
2859
2860char *
PavolVican1bc22062017-01-19 15:09:04 +01002861yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002862 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002863
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002864 while (i < size) {
2865 switch (input[i]) {
2866 case '\n':
2867 out_index -= space;
2868 output[out_index] = '\n';
2869 space = 0;
2870 i = read_indent(input, indent, size, i + 1, &out_index, output);
2871 break;
2872 case ' ':
2873 case '\t':
2874 output[out_index] = input[i];
2875 ++space;
2876 break;
2877 case '\\':
2878 if (input[i + 1] == 'n') {
2879 out_index -= space;
2880 output[out_index] = '\n';
2881 space = 0;
2882 i = read_indent(input, indent, size, i + 2, &out_index, output);
2883 } else if (input[i + 1] == 't') {
2884 output[out_index] = '\t';
2885 ++i;
2886 ++space;
2887 } else if (input[i + 1] == '\\') {
2888 output[out_index] = '\\';
2889 ++i;
2890 } else if ((i + 1) != size && input[i + 1] == '"') {
2891 output[out_index] = '"';
2892 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002893 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002894 /* backslash must not be followed by any other character */
2895 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2896 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002897 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002898 break;
2899 default:
2900 output[out_index] = input[i];
2901 space = 0;
2902 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002903 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002904 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002905 ++out_index;
2906 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002907 output[out_index] = '\0';
2908 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002909 output = realloc(output, out_index + 1);
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002910 if (!output) {
2911 LOGMEM;
Pavol Vican3f598892016-09-28 15:41:07 +02002912 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002913 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002914 }
Pavol Vican3f598892016-09-28 15:41:07 +02002915 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002916}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002917
2918/* free function */
2919
PavolVicana0fdbf32017-02-15 17:59:02 +01002920void
2921yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002922{
2923 struct yang_type *stype = (struct yang_type *)type->der;
2924 int i;
2925
2926 if (!stype) {
2927 return ;
2928 }
PavolVicane87cb932016-12-30 15:36:18 +01002929 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2930 lydict_remove(ctx, stype->name);
2931 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2932 for (i = 0; i < type->info.ident.count; ++i) {
2933 free(type->info.ident.ref[i]);
2934 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002935 }
PavolVicane87cb932016-12-30 15:36:18 +01002936 if (stype->base == LY_TYPE_UNION) {
2937 for (i = 0; i < type->info.uni.count; ++i) {
2938 yang_type_free(ctx, &type->info.uni.types[i]);
2939 }
2940 free(type->info.uni.types);
2941 type->base = LY_TYPE_DER;
2942 } else {
2943 type->base = stype->base;
2944 }
2945 free(stype);
2946 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002947 }
2948 lys_type_free(ctx, type);
Pavol Vican36aff862016-11-26 17:07:05 +01002949 type->base = LY_TYPE_DER;
Pavol Vican7313fc02016-11-14 01:10:31 +01002950}
2951
2952static void
2953yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint8_t start, uint8_t size)
2954{
2955 uint8_t i;
2956
2957 assert(ctx);
2958 if (!tpdf) {
2959 return;
2960 }
2961
2962 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002963 lydict_remove(ctx, tpdf[i].name);
2964 lydict_remove(ctx, tpdf[i].dsc);
2965 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002966
Pavol Vicancee10802016-11-22 15:48:35 +01002967 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002968
Pavol Vicancee10802016-11-22 15:48:35 +01002969 lydict_remove(ctx, tpdf[i].units);
2970 lydict_remove(ctx, tpdf[i].dflt);
Pavol Vican7313fc02016-11-14 01:10:31 +01002971 }
2972}
2973
Pavol Vican1cc4e192016-10-24 16:38:31 +02002974static void
2975yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2976{
2977 uint8_t i;
2978
2979 for (i = start; i < size; ++i){
2980 free((char *)imp[i].module);
2981 lydict_remove(ctx, imp[i].prefix);
2982 lydict_remove(ctx, imp[i].dsc);
2983 lydict_remove(ctx, imp[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002984 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002985 }
2986}
2987
Pavol Vicanec423c92016-10-24 21:33:43 +02002988static void
2989yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2990{
2991 uint8_t i;
2992
2993 for (i = start; i < size; ++i){
2994 free((char *)inc[i].submodule);
2995 lydict_remove(ctx, inc[i].dsc);
2996 lydict_remove(ctx, inc[i].ref);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002997 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02002998 }
2999}
3000
Pavol Vican36e27272016-11-22 15:47:28 +01003001static void
3002yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
3003{
3004 uint32_t i;
3005 uint8_t j;
3006
3007 /* free base name */
3008 for (i = start; i < size; ++i) {
3009 for (j = 0; j < ident[i].base_size; ++j) {
3010 free(ident[i].base[j]);
3011 }
3012 }
3013}
3014
Pavol Vican05810b62016-11-23 14:07:22 +01003015static void
3016yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
3017{
3018 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
3019 free(grp->tpdf);
3020}
3021
3022static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003023yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
3024{
3025 uint8_t i;
3026
3027 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
3028 free(cont->tpdf);
3029 lydict_remove(ctx, cont->presence);
3030
Pavol Vicanfda8c802016-12-03 02:00:42 +01003031 for (i = 0; i < cont->must_size; ++i) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003032 lys_restr_free(ctx, &cont->must[i]);
3033 }
3034 free(cont->must);
3035
3036 lys_when_free(ctx, cont->when);
3037}
3038
3039static void
Pavol Vicana69aff22016-11-24 18:23:50 +01003040yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
3041{
3042 uint8_t i;
3043
3044 for (i = 0; i < leaf->must_size; i++) {
3045 lys_restr_free(ctx, &leaf->must[i]);
3046 }
3047 free(leaf->must);
3048
3049 lys_when_free(ctx, leaf->when);
3050
3051 yang_type_free(ctx, &leaf->type);
3052 lydict_remove(ctx, leaf->units);
3053 lydict_remove(ctx, leaf->dflt);
3054}
3055
3056static void
Pavol Vican36aff862016-11-26 17:07:05 +01003057yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
3058{
3059 uint8_t i;
3060
3061 for (i = 0; i < leaflist->must_size; i++) {
3062 lys_restr_free(ctx, &leaflist->must[i]);
3063 }
3064 free(leaflist->must);
3065
3066 for (i = 0; i < leaflist->dflt_size; i++) {
3067 lydict_remove(ctx, leaflist->dflt[i]);
3068 }
3069 free(leaflist->dflt);
3070
3071 lys_when_free(ctx, leaflist->when);
3072
3073 yang_type_free(ctx, &leaflist->type);
3074 lydict_remove(ctx, leaflist->units);
3075}
3076
3077static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003078yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3079{
3080 uint8_t i;
3081
3082 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3083 free(list->tpdf);
3084
3085 for (i = 0; i < list->must_size; ++i) {
3086 lys_restr_free(ctx, &list->must[i]);
3087 }
3088 free(list->must);
3089
3090 lys_when_free(ctx, list->when);
3091
3092 for (i = 0; i < list->unique_size; ++i) {
3093 free(list->unique[i].expr);
3094 }
3095 free(list->unique);
3096
3097 free(list->keys);
3098}
3099
3100static void
Pavol Vican36ace102016-11-28 11:46:59 +01003101yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3102{
3103 free(choice->dflt);
3104 lys_when_free(ctx, choice->when);
3105}
3106
3107static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003108yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3109{
3110 uint8_t i;
3111
3112 for (i = 0; i < anydata->must_size; ++i) {
3113 lys_restr_free(ctx, &anydata->must[i]);
3114 }
3115 free(anydata->must);
3116
3117 lys_when_free(ctx, anydata->when);
3118}
3119
3120static void
Pavol Vican78729392016-11-28 17:18:22 +01003121yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3122{
3123 uint8_t i;
3124
3125 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3126 free(inout->tpdf);
3127
3128 for (i = 0; i < inout->must_size; ++i) {
3129 lys_restr_free(ctx, &inout->must[i]);
3130 }
3131 free(inout->must);
3132}
3133
3134static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003135yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3136{
3137 uint8_t i;
3138
3139 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3140 free(notif->tpdf);
3141
3142 for (i = 0; i < notif->must_size; ++i) {
3143 lys_restr_free(ctx, &notif->must[i]);
3144 }
3145 free(notif->must);
3146}
3147
3148static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003149yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3150{
3151 int i, j;
3152
3153 for (i = 0; i < uses->refine_size; i++) {
3154 lydict_remove(ctx, uses->refine[i].target_name);
3155 lydict_remove(ctx, uses->refine[i].dsc);
3156 lydict_remove(ctx, uses->refine[i].ref);
3157
3158 for (j = 0; j < uses->refine[i].must_size; j++) {
3159 lys_restr_free(ctx, &uses->refine[i].must[j]);
3160 }
3161 free(uses->refine[i].must);
3162
3163 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3164 lydict_remove(ctx, uses->refine[i].dflt[j]);
3165 }
3166 free(uses->refine[i].dflt);
3167
3168 if (uses->refine[i].target_type & LYS_CONTAINER) {
3169 lydict_remove(ctx, uses->refine[i].mod.presence);
3170 }
3171 }
3172 free(uses->refine);
3173
3174 lys_when_free(ctx, uses->when);
3175}
3176
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003177static void
Pavol Vican05810b62016-11-23 14:07:22 +01003178yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3179{
3180 struct lys_node *tmp, *child, *sibling;
3181
3182 if (!node) {
3183 return;
3184 }
3185 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003186
3187 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003188 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003189 sibling = tmp->next;
3190 /* common part */
3191 lydict_remove(ctx, tmp->name);
3192 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
PavolVican8c33b152017-01-27 12:45:34 +01003193 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003194 lydict_remove(ctx, tmp->dsc);
3195 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003196 }
3197
3198 switch (tmp->nodetype) {
3199 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003200 case LYS_RPC:
3201 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003202 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3203 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003204 case LYS_CONTAINER:
3205 yang_free_container(ctx, (struct lys_node_container *)tmp);
3206 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003207 case LYS_LEAF:
3208 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3209 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003210 case LYS_LEAFLIST:
3211 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3212 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003213 case LYS_LIST:
3214 yang_free_list(ctx, (struct lys_node_list *)tmp);
3215 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003216 case LYS_CHOICE:
3217 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3218 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003219 case LYS_CASE:
3220 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when);
3221 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003222 case LYS_ANYXML:
3223 case LYS_ANYDATA:
3224 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3225 break;
Pavol Vican78729392016-11-28 17:18:22 +01003226 case LYS_INPUT:
3227 case LYS_OUTPUT:
3228 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3229 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003230 case LYS_NOTIF:
3231 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3232 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003233 case LYS_USES:
3234 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3235 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003236 default:
3237 break;
3238 }
3239
3240 yang_free_nodes(ctx, child);
3241 free(tmp);
3242 tmp = sibling;
3243 }
3244}
3245
Pavol Vican3ad50f82016-12-04 15:00:36 +01003246static void
3247yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3248{
3249 lydict_remove(ctx, aug->target_name);
3250 lydict_remove(ctx, aug->dsc);
3251 lydict_remove(ctx, aug->ref);
3252
PavolVican8c33b152017-01-27 12:45:34 +01003253 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003254 lys_when_free(ctx, aug->when);
3255 yang_free_nodes(ctx, aug->child);
3256}
3257
PavolVican75af21d2016-12-29 20:04:07 +01003258static void
3259yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3260{
3261 uint i, j;
3262
3263 for (i = index; i < dev->deviate_size; ++i) {
3264 lydict_remove(ctx, dev->deviate[i].units);
3265
3266 if (dev->deviate[i].type) {
3267 yang_type_free(ctx, dev->deviate[i].type);
3268 }
3269
3270 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3271 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3272 }
3273 free(dev->deviate[i].dflt);
3274
3275 for (j = 0; j < dev->deviate[i].must_size; ++j) {
3276 lys_restr_free(ctx, &dev->deviate[i].must[j]);
3277 }
3278 free(dev->deviate[i].must);
3279
3280 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3281 free(dev->deviate[i].unique[j].expr);
3282 }
3283 free(dev->deviate[i].unique);
3284 }
3285}
3286
Pavol Vican7313fc02016-11-14 01:10:31 +01003287/* free common item from module and submodule */
3288static void
Pavol Vican05810b62016-11-23 14:07:22 +01003289free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003290{
PavolVican75af21d2016-12-29 20:04:07 +01003291 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003292 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3293 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003294 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003295 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003296 for (i = 0; i < module->augment_size; ++i) {
3297 yang_free_augment(module->ctx, &module->augment[i]);
3298 }
3299 module->augment_size = 0;
3300 for (i = 0; i < module->deviation_size; ++i) {
3301 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3302 free(module->deviation[i].deviate);
3303 }
3304 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003305}
3306
Pavol Vican1cc4e192016-10-24 16:38:31 +02003307/* check function*/
3308
3309int
PavolVicanc1807262017-01-31 18:00:27 +01003310yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3311 void *parent, struct unres_schema *unres)
3312{
3313 struct unres_ext *info;
3314 uint i;
3315
3316 for (i = 0; i < size; ++i) {
3317 info = malloc(sizeof *info);
3318 info->data.yang = (*ext)[i]->parent;
3319 info->datatype = LYS_IN_YANG;
3320 info->parent = parent;
3321 info->mod = module;
3322 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003323 info->substmt = (*ext)[i]->insubstmt;
3324 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003325 info->ext_index = i;
3326 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
PavolVican5334c892017-02-15 16:29:09 +01003327 free(info->data.yang);
3328 free(info);
PavolVicanc1807262017-01-31 18:00:27 +01003329 return EXIT_FAILURE;
3330 }
3331 }
3332
3333 return EXIT_SUCCESS;
3334}
3335
3336int
Pavol Vicanec423c92016-10-24 21:33:43 +02003337yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003338{
3339 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003340 struct lys_include *inc;
3341 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003342 size_t size;
3343 char *s;
3344
3345 imp = module->imp;
3346 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003347 inc = module->inc;
3348 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003349
3350 if (imp_size) {
3351 size = (imp_size * sizeof *module->imp) + sizeof(void*);
3352 module->imp_size = 0;
3353 module->imp = calloc(1, size);
3354 if (!module->imp) {
3355 LOGMEM;
3356 goto error;
3357 }
3358 /* set stop block for possible realloc */
3359 module->imp[imp_size].module = (void*)0x1;
Pavol Vicanec423c92016-10-24 21:33:43 +02003360 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003361
Pavol Vicanec423c92016-10-24 21:33:43 +02003362 if (inc_size) {
3363 size = (inc_size * sizeof *module->inc) + sizeof(void*);
3364 module->inc_size = 0;
3365 module->inc = calloc(1, size);
3366 if (!module->inc) {
3367 LOGMEM;
3368 goto error;
3369 }
3370 /* set stop block for possible realloc */
3371 module->inc[inc_size].submodule = (void*)0x1;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003372 }
3373
3374 for (i = 0; i < imp_size; ++i) {
3375 s = (char *) imp[i].module;
3376 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003377 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003378 ++i;
3379 goto error;
3380 }
3381 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003382 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003383 s = (char *) inc[j].submodule;
3384 inc[j].submodule = NULL;
3385 if (yang_fill_include(module, s, &inc[j], unres)) {
3386 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003387 goto error;
3388 }
3389 }
3390 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003391 free(imp);
3392
3393 return EXIT_SUCCESS;
3394
3395error:
3396 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003397 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003398 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003399 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003400 return EXIT_FAILURE;
3401}
Pavol Vican7313fc02016-11-14 01:10:31 +01003402
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003403static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003404yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003405{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003406 struct lys_iffeature *iffeature;
3407 uint8_t *ptr_size, size, i;
3408 char *s;
3409 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003410
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003411 switch (type) {
3412 case FEATURE_KEYWORD:
3413 iffeature = ((struct lys_feature *)parent)->iffeature;
3414 size = ((struct lys_feature *)parent)->iffeature_size;
3415 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3416 parent_is_feature = 1;
3417 break;
3418 case IDENTITY_KEYWORD:
3419 iffeature = ((struct lys_ident *)parent)->iffeature;
3420 size = ((struct lys_ident *)parent)->iffeature_size;
3421 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3422 break;
3423 case ENUM_KEYWORD:
3424 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3425 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3426 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3427 break;
3428 case BIT_KEYWORD:
3429 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3430 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3431 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3432 break;
3433 case REFINE_KEYWORD:
3434 iffeature = ((struct lys_refine *)ptr)->iffeature;
3435 size = ((struct lys_refine *)ptr)->iffeature_size;
3436 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3437 break;
3438 default:
3439 iffeature = ((struct lys_node *)parent)->iffeature;
3440 size = ((struct lys_node *)parent)->iffeature_size;
3441 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3442 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003443 }
3444
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003445 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003446 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003447 s = (char *)iffeature[i].features;
3448 iffeature[i].features = NULL;
3449 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3450 *ptr_size = size;
3451 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003452 }
PavolVican8fa31242017-02-07 11:04:26 +01003453 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3454 *ptr_size = size;
3455 return EXIT_FAILURE;
3456 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003457 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003458 }
3459
3460 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003461}
3462
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003463static int
3464yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3465{
3466 uint size, i;
3467 int rc;
3468 struct lys_ident **ref;
3469 const char *value;
3470 char *expr;
3471
3472 ref = type->info.ident.ref;
3473 size = type->info.ident.count;
3474 type->info.ident.count = 0;
3475 type->info.ident.ref = NULL;
3476 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3477
3478 for (i = 0; i < size; ++i) {
3479 expr = (char *)ref[i];
3480 /* store in the JSON format */
3481 value = transform_schema2json(module, expr);
3482 free(expr);
3483
3484 if (!value) {
3485 goto error;
3486 }
3487 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3488 lydict_remove(module->ctx, value);
3489
3490 if (rc == -1) {
3491 goto error;
3492 }
3493 }
3494 free(ref);
3495
3496 return EXIT_SUCCESS;
3497error:
3498 for (i = i+1; i < size; ++i) {
3499 free(ref[i]);
3500 }
3501 free(ref);
3502 return EXIT_FAILURE;
3503}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003504
Pavol Vican7313fc02016-11-14 01:10:31 +01003505int
PavolVican056fcd12017-02-07 15:36:53 +01003506yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3507 void *parent, struct unres_schema *unres)
3508{
3509 int i;
3510
3511 type->parent = parent;
3512 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3513 return EXIT_FAILURE;
3514 }
3515 switch (stype->base) {
3516 case LY_TYPE_ENUM:
3517 for (i = 0; i < type->info.enums.count; ++i) {
3518 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3519 return EXIT_FAILURE;
3520 }
3521 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3522 &type->info.enums.enm[i], unres)) {
3523 return EXIT_FAILURE;
3524 }
3525 }
3526 break;
3527 case LY_TYPE_BITS:
3528 for (i = 0; i < type->info.bits.count; ++i) {
3529 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3530 return EXIT_FAILURE;
3531 }
3532 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3533 &type->info.bits.bit[i], unres)) {
3534 return EXIT_FAILURE;
3535 }
3536 }
3537 break;
3538 case LY_TYPE_IDENT:
3539 if (yang_check_identityref(module, type, unres)) {
3540 return EXIT_FAILURE;
3541 }
3542 break;
3543 case LY_TYPE_STRING:
3544 if (type->info.str.length && yang_check_ext_instance(module, &type->info.str.length->ext,
3545 type->info.str.length->ext_size, type->info.str.length, unres)) {
3546 return EXIT_FAILURE;
3547 }
3548 for (i = 0; i < type->info.str.pat_count; ++i) {
3549 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3550 &type->info.str.patterns[i], unres)) {
3551 return EXIT_FAILURE;
3552 }
3553 }
3554 break;
3555 case LY_TYPE_DEC64:
3556 if (type->info.dec64.range && yang_check_ext_instance(module, &type->info.dec64.range->ext,
3557 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3558 return EXIT_FAILURE;
3559 }
3560 break;
3561 case LY_TYPE_UNION:
3562 for (i = 0; i < type->info.uni.count; ++i) {
3563 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3564 parent, unres)) {
3565 return EXIT_FAILURE;
3566 }
3567 }
3568 default:
3569 /* nothing checks */
3570 break;
3571 }
3572 return EXIT_SUCCESS;
3573}
3574
3575int
Pavol Vican7313fc02016-11-14 01:10:31 +01003576yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3577{
3578 struct lys_tpdf *tpdf;
PavolVican056fcd12017-02-07 15:36:53 +01003579 uint8_t i, tpdf_size, *ptr_tpdf_size;
Pavol Vican7313fc02016-11-14 01:10:31 +01003580
3581 if (!parent) {
3582 tpdf = module->tpdf;
3583 ptr_tpdf_size = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003584 } else {
3585 switch (parent->nodetype) {
3586 case LYS_GROUPING:
3587 tpdf = ((struct lys_node_grp *)parent)->tpdf;
3588 ptr_tpdf_size = &((struct lys_node_grp *)parent)->tpdf_size;
3589 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003590 case LYS_CONTAINER:
3591 tpdf = ((struct lys_node_container *)parent)->tpdf;
3592 ptr_tpdf_size = &((struct lys_node_container *)parent)->tpdf_size;
3593 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003594 case LYS_LIST:
3595 tpdf = ((struct lys_node_list *)parent)->tpdf;
3596 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3597 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003598 case LYS_RPC:
3599 case LYS_ACTION:
3600 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3601 ptr_tpdf_size = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3602 break;
Pavol Vican78729392016-11-28 17:18:22 +01003603 case LYS_INPUT:
3604 case LYS_OUTPUT:
3605 tpdf = ((struct lys_node_inout *)parent)->tpdf;
3606 ptr_tpdf_size = &((struct lys_node_inout *)parent)->tpdf_size;
3607 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003608 case LYS_NOTIF:
3609 tpdf = ((struct lys_node_notif *)parent)->tpdf;
3610 ptr_tpdf_size = &((struct lys_node_notif *)parent)->tpdf_size;
3611 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003612 default:
3613 LOGINT;
3614 return EXIT_FAILURE;
3615 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003616 }
3617
3618 tpdf_size = *ptr_tpdf_size;
3619 *ptr_tpdf_size = 0;
3620
3621 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003622 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3623 goto error;
3624 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003625
PavolVican056fcd12017-02-07 15:36:53 +01003626 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3627 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003628 }
PavolVicandf9e7972017-02-07 11:41:38 +01003629 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3630 goto error;
3631 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003632 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003633 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003634 }
3635
PavolVicane87cb932016-12-30 15:36:18 +01003636 (*ptr_tpdf_size)++;
Pavol Vican7313fc02016-11-14 01:10:31 +01003637 /* check default value*/
Pavol Vicanfda8c802016-12-03 02:00:42 +01003638 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 +01003639 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003640 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003641 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003642 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003643
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003644 return EXIT_SUCCESS;
3645
3646error:
3647 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3648 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003649}
3650
3651static int
Pavol Vican36e27272016-11-22 15:47:28 +01003652yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3653{
3654 uint32_t i, size, base_size;
3655 uint8_t j;
3656
3657 size = module->ident_size;
3658 module->ident_size = 0;
3659 for (i = 0; i < size; ++i) {
3660 base_size = module->ident[i].base_size;
3661 module->ident[i].base_size = 0;
3662 for (j = 0; j < base_size; ++j) {
3663 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3664 ++j;
3665 module->ident_size = size;
3666 goto error;
3667 }
3668 }
3669 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003670 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3671 goto error;
3672 }
PavolVican8fa31242017-02-07 11:04:26 +01003673 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3674 goto error;
3675 }
Pavol Vican36e27272016-11-22 15:47:28 +01003676 }
3677
PavolVican8fa31242017-02-07 11:04:26 +01003678
Pavol Vican36e27272016-11-22 15:47:28 +01003679 return EXIT_SUCCESS;
3680
3681error:
3682 for (; j< module->ident[i].base_size; ++j) {
3683 free(module->ident[i].base[j]);
3684 }
3685 yang_free_ident_base(module->ident, i + 1, size);
3686 return EXIT_FAILURE;
3687}
3688
3689static int
PavolVican38104a32017-02-08 12:25:23 +01003690yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3691{
3692 uint i;
3693
3694 for (i = 0; i < size; ++i) {
3695 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3696 return EXIT_FAILURE;
3697 }
3698 }
3699 return EXIT_SUCCESS;
3700}
3701
3702static int
PavolVicane87cb932016-12-30 15:36:18 +01003703yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
3704 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003705{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003706 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003707 goto error;
3708 }
3709
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003710 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003711 goto error;
3712 }
3713
PavolVicane87cb932016-12-30 15:36:18 +01003714 if (yang_check_nodes(module, (struct lys_node *)cont, *child, config_opt, unres)) {
3715 *child = NULL;
3716 goto error;
3717 }
3718 *child = NULL;
3719
PavolVican59ba4602017-02-08 11:53:32 +01003720 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3721 goto error;
3722 }
PavolVican38104a32017-02-08 12:25:23 +01003723 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3724 goto error;
3725 }
3726
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003727 /* check XPath dependencies */
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003728 if ((cont->when || cont->must_size) && (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003729 goto error;
3730 }
3731
3732 return EXIT_SUCCESS;
3733error:
3734 return EXIT_FAILURE;
3735}
3736
3737static int
Pavol Vicana69aff22016-11-24 18:23:50 +01003738yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, struct unres_schema *unres)
3739{
PavolVican056fcd12017-02-07 15:36:53 +01003740 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003741 yang_type_free(module->ctx, &leaf->type);
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003742 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003743 }
PavolVicana08d3652016-12-29 21:07:47 +01003744 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3745 yang_type_free(module->ctx, &leaf->type);
3746 goto error;
3747 }
3748
Pavol Vicanfda8c802016-12-03 02:00:42 +01003749 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003750 yang_type_free(module->ctx, &leaf->type);
3751 goto error;
3752 }
3753
Pavol Vicanfda8c802016-12-03 02:00:42 +01003754 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 +01003755 goto error;
3756 }
3757
PavolVican59ba4602017-02-08 11:53:32 +01003758 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3759 goto error;
3760 }
PavolVican38104a32017-02-08 12:25:23 +01003761 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3762 goto error;
3763 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003764 /* check XPath dependencies */
3765 if ((leaf->when || leaf->must_size) && (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1)) {
3766 goto error;
3767 }
3768
3769 return EXIT_SUCCESS;
3770error:
3771 return EXIT_FAILURE;
3772}
3773
3774static int
Pavol Vican36aff862016-11-26 17:07:05 +01003775yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, struct unres_schema *unres)
3776{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003777 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003778
PavolVican056fcd12017-02-07 15:36:53 +01003779 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003780 yang_type_free(module->ctx, &leaflist->type);
3781 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003782 }
PavolVicana08d3652016-12-29 21:07:47 +01003783 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3784 yang_type_free(module->ctx, &leaflist->type);
3785 goto error;
3786 }
3787
Pavol Vicanfda8c802016-12-03 02:00:42 +01003788 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003789 yang_type_free(module->ctx, &leaflist->type);
3790 goto error;
3791 }
3792
Pavol Vican36aff862016-11-26 17:07:05 +01003793 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003794 /* check for duplicity in case of configuration data,
3795 * in case of status data duplicities are allowed */
3796 if (leaflist->flags & LYS_CONFIG_W) {
3797 for (j = i +1; j < leaflist->dflt_size; ++j) {
3798 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003799 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3800 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003801 goto error;
3802 }
3803 }
3804 }
3805 /* check default value (if not defined, there still could be some restrictions
3806 * that need to be checked against a default value from a derived type) */
Pavol Vican36aff862016-11-26 17:07:05 +01003807 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaflist->dflt[i])) == -1) {
3808 goto error;
3809 }
3810 }
3811
PavolVican59ba4602017-02-08 11:53:32 +01003812 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3813 goto error;
3814 }
PavolVican38104a32017-02-08 12:25:23 +01003815 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3816 goto error;
3817 }
PavolVican59ba4602017-02-08 11:53:32 +01003818
Pavol Vican36aff862016-11-26 17:07:05 +01003819 /* check XPath dependencies */
3820 if ((leaflist->when || leaflist->must_size) && (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1)) {
3821 goto error;
3822 }
3823
3824 return EXIT_SUCCESS;
3825error:
3826 return EXIT_FAILURE;
3827}
3828
3829static int
PavolVicane87cb932016-12-30 15:36:18 +01003830yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
3831 int config_opt, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003832{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003833 struct lys_node *node;
3834
Pavol Vicand8136a42016-11-27 13:28:04 +01003835 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3836 goto error;
3837 }
3838
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003839 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3840 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003841 }
3842
Pavol Vicanfda8c802016-12-03 02:00:42 +01003843 if (list->flags & LYS_CONFIG_R) {
3844 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3845 * ignore oredering MASK - 0x7F
3846 */
3847 list->flags &= 0x7F;
3848 }
3849 /* check - if list is configuration, key statement is mandatory
3850 * (but only if we are not in a grouping or augment, then the check is deferred) */
3851 for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT)); node = node->parent);
3852 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3853 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3854 goto error;
3855 }
3856
PavolVicane87cb932016-12-30 15:36:18 +01003857 if (yang_check_nodes(module, (struct lys_node *)list, *child, config_opt, unres)) {
3858 *child = NULL;
3859 goto error;
3860 }
3861 *child = NULL;
3862
Pavol Vicand8136a42016-11-27 13:28:04 +01003863 if (list->keys && yang_read_key(module, list, unres)) {
3864 goto error;
3865 }
3866
3867 if (yang_read_unique(module, list, unres)) {
3868 goto error;
3869 }
3870
PavolVican59ba4602017-02-08 11:53:32 +01003871 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3872 goto error;
3873 }
PavolVican38104a32017-02-08 12:25:23 +01003874 if (yang_check_must(module, list->must, list->must_size, unres)) {
3875 goto error;
3876 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003877 /* check XPath dependencies */
3878 if ((list->when || list->must_size) && (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1)) {
3879 goto error;
3880 }
3881
3882 return EXIT_SUCCESS;
3883error:
3884 return EXIT_FAILURE;
3885}
3886
3887static int
PavolVicane87cb932016-12-30 15:36:18 +01003888yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
3889 int config_opt, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003890{
3891 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003892
PavolVicana08d3652016-12-29 21:07:47 +01003893 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3894 free(choice->dflt);
3895 choice->dflt = NULL;
3896 goto error;
3897 }
3898
PavolVicane87cb932016-12-30 15:36:18 +01003899 if (yang_check_nodes(module, (struct lys_node *)choice, *child, config_opt, unres)) {
3900 *child = NULL;
3901 free(choice->dflt);
3902 choice->dflt = NULL;
3903 goto error;
3904 }
3905 *child = NULL;
3906
Pavol Vican36ace102016-11-28 11:46:59 +01003907 if (choice->dflt) {
3908 value = (char *)choice->dflt;
3909 choice->dflt = NULL;
3910 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3911 free(value);
3912 goto error;
3913 }
3914 free(value);
3915 }
3916
PavolVican59ba4602017-02-08 11:53:32 +01003917 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3918 goto error;
3919 }
3920
Pavol Vican36ace102016-11-28 11:46:59 +01003921 /* check XPath dependencies */
3922 if ((choice->when) && (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1)) {
3923 goto error;
3924 }
3925
3926 return EXIT_SUCCESS;
3927error:
3928 return EXIT_FAILURE;
3929}
3930
3931static int
PavolVicane87cb932016-12-30 15:36:18 +01003932yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
3933 int config_opt, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003934{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003935 struct lys_node *node;
3936
3937 if (rpc->nodetype == LYS_ACTION) {
3938 for (node = rpc->parent; node; node = lys_parent(node)) {
3939 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003940 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003941 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003942 goto error;
3943 }
3944 }
3945 }
3946 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3947 goto error;
3948 }
3949
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003950 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3951 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003952 }
3953
PavolVicane87cb932016-12-30 15:36:18 +01003954 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, config_opt, unres)) {
3955 *child = NULL;
3956 goto error;
3957 }
3958 *child = NULL;
3959
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003960 return EXIT_SUCCESS;
3961error:
3962 return EXIT_FAILURE;
3963}
3964
3965static int
PavolVicane87cb932016-12-30 15:36:18 +01003966yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
3967 int config_opt, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01003968{
Pavol Vican29bf8802016-11-28 20:44:57 +01003969 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3970 goto error;
3971 }
3972
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003973 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3974 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003975 }
3976
PavolVicane87cb932016-12-30 15:36:18 +01003977 if (yang_check_nodes(module, (struct lys_node *)notif, *child, config_opt, unres)) {
3978 *child = NULL;
3979 goto error;
3980 }
3981 *child = NULL;
3982
PavolVican38104a32017-02-08 12:25:23 +01003983 if (notif->must_size) {
3984 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
3985 goto error;
3986 }
3987 /* check XPath dependencies */
3988 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
3989 goto error;
3990 }
Pavol Vican29bf8802016-11-28 20:44:57 +01003991 }
3992
3993 return EXIT_SUCCESS;
3994error:
3995 return EXIT_FAILURE;
3996}
3997
3998static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01003999yang_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 +01004000{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004001 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004002
Pavol Vican3ad50f82016-12-04 15:00:36 +01004003 child = augment->child;
4004 augment->child = NULL;
4005
PavolVicana08d3652016-12-29 21:07:47 +01004006 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4007 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004008 goto error;
4009 }
4010
PavolVicana08d3652016-12-29 21:07:47 +01004011 if (yang_check_nodes(module, (struct lys_node *)augment, child, config_opt, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004012 goto error;
4013 }
4014
PavolVicanfa9510e2017-02-08 17:20:46 +01004015 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4016 goto error;
4017 }
4018
PavolVican59ba4602017-02-08 11:53:32 +01004019 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4020 goto error;
4021 }
4022
Pavol Vican3ad50f82016-12-04 15:00:36 +01004023 /* check XPath dependencies */
4024 if (augment->when && (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1)) {
4025 goto error;
4026 }
4027
4028 return EXIT_SUCCESS;
4029error:
4030 return EXIT_FAILURE;
4031}
4032
4033static int
4034yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int config_opt, struct unres_schema *unres)
4035{
4036 uint i, size;
4037
4038 size = uses->augment_size;
4039 uses->augment_size = 0;
4040
4041 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004042 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004043 }
4044
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004045 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004046 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4047 goto error;
4048 }
4049 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4050 goto error;
4051 }
4052 if (yang_check_ext_instance(module, &uses->refine[i].ext, uses->refine[i].ext_size, &uses->refine[i], unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004053 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004054 }
4055 }
4056
Pavol Vican3ad50f82016-12-04 15:00:36 +01004057 for (i = 0; i < size; ++i) {
4058 uses->augment_size++;
4059 if (yang_check_augment(module, &uses->augment[i], config_opt, unres)) {
4060 goto error;
4061 }
4062 }
4063
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004064 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4065 goto error;
4066 }
4067
PavolVican59ba4602017-02-08 11:53:32 +01004068 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4069 goto error;
4070 }
4071
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004072 /* check XPath dependencies */
4073 if (uses->when && (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1)) {
4074 goto error;
4075 }
4076
4077 return EXIT_SUCCESS;
4078error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004079 for (i = uses->augment_size; i < size; ++i) {
4080 yang_free_augment(module->ctx, &uses->augment[i]);
4081 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004082 return EXIT_FAILURE;
4083}
4084
4085static int
PavolVican59ba4602017-02-08 11:53:32 +01004086yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
4087 int config_opt, struct unres_schema *unres)
4088{
4089 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4090 goto error;
4091 }
4092
4093 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, config_opt, unres)) {
4094 *child = NULL;
4095 goto error;
4096 }
4097 *child = NULL;
4098
4099 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4100 goto error;
4101 }
PavolVican38104a32017-02-08 12:25:23 +01004102 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4103 goto error;
4104 }
PavolVican59ba4602017-02-08 11:53:32 +01004105
4106 /* check XPath dependencies */
PavolVican38104a32017-02-08 12:25:23 +01004107 if ((anydata->when || anydata->must_size) && (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1)) {
PavolVican59ba4602017-02-08 11:53:32 +01004108 goto error;
4109 }
4110 return EXIT_SUCCESS;
4111error:
4112 return EXIT_FAILURE;
4113}
4114
4115static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004116yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
4117 int config_opt, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004118{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004119 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01004120
4121 while (node) {
4122 sibling = node->next;
4123 child = node->child;
4124 node->next = NULL;
4125 node->child = NULL;
4126 node->prev = node;
4127
Pavol Vican24ba7f62016-11-28 12:15:20 +01004128 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
4129 lys_node_unlink(node);
4130 node->next = sibling;
Pavol Vican05810b62016-11-23 14:07:22 +01004131 sibling = node;
Pavol Vican05810b62016-11-23 14:07:22 +01004132 goto error;
4133 }
Pavol Vicanec598812016-11-30 14:13:38 +01004134 config_opt = store_config_flag(node, config_opt);
PavolVican70ce7452017-02-01 15:39:39 +01004135 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4136 goto error;
4137 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004138
Pavol Vican05810b62016-11-23 14:07:22 +01004139 switch (node->nodetype) {
4140 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004141 if (yang_check_typedef(module, node, unres)) {
4142 goto error;
4143 }
4144 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004145 goto error;
4146 }
PavolVicane87cb932016-12-30 15:36:18 +01004147 if (yang_check_nodes(module, node, child, config_opt, unres)) {
4148 child = NULL;
4149 goto error;
4150 }
Pavol Vican05810b62016-11-23 14:07:22 +01004151 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004152 case LYS_CONTAINER:
PavolVicane87cb932016-12-30 15:36:18 +01004153 if (yang_check_container(module, (struct lys_node_container *)node, &child, config_opt, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004154 goto error;
4155 }
4156 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004157 case LYS_LEAF:
4158 if (yang_check_leaf(module, (struct lys_node_leaf *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004159 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004160 goto error;
4161 }
4162 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004163 case LYS_LEAFLIST:
4164 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004165 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004166 goto error;
4167 }
4168 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004169 case LYS_LIST:
PavolVicane87cb932016-12-30 15:36:18 +01004170 if (yang_check_list(module, (struct lys_node_list *)node, &child, config_opt, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004171 goto error;
4172 }
4173 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004174 case LYS_CHOICE:
PavolVicane87cb932016-12-30 15:36:18 +01004175 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, config_opt, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004176 goto error;
4177 }
4178 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004179 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004180 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004181 goto error;
4182 }
PavolVicane87cb932016-12-30 15:36:18 +01004183 if (yang_check_nodes(module, node, child, config_opt, unres)) {
4184 child = NULL;
4185 goto error;
4186 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004187 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004188 case LYS_ANYDATA:
4189 case LYS_ANYXML:
PavolVican59ba4602017-02-08 11:53:32 +01004190 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, config_opt, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004191 goto error;
4192 }
4193 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004194 case LYS_RPC:
4195 case LYS_ACTION:
PavolVicane87cb932016-12-30 15:36:18 +01004196 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, config_opt, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004197 goto error;
4198 }
4199 break;
Pavol Vican78729392016-11-28 17:18:22 +01004200 case LYS_INPUT:
4201 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004202 if (yang_check_typedef(module, node, unres)) {
4203 goto error;
4204 }
4205 if (yang_check_nodes(module, node, child, config_opt, unres)) {
4206 child = NULL;
4207 goto error;
4208 }
PavolVican38104a32017-02-08 12:25:23 +01004209 if (((struct lys_node_inout *)node)->must_size) {
4210 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4211 goto error;
4212 }
4213 /* check XPath dependencies */
4214 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4215 goto error;
4216 }
Pavol Vican78729392016-11-28 17:18:22 +01004217 }
Pavol Vican78729392016-11-28 17:18:22 +01004218 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004219 case LYS_NOTIF:
PavolVicane87cb932016-12-30 15:36:18 +01004220 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, config_opt, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004221 goto error;
4222 }
4223 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004224 case LYS_USES:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004225 if (yang_check_uses(module, (struct lys_node_uses *)node, config_opt, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004226 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004227 goto error;
4228 }
4229 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004230 default:
4231 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01004232 goto error;
4233 }
Pavol Vican05810b62016-11-23 14:07:22 +01004234 node = sibling;
4235 }
4236
4237 return EXIT_SUCCESS;
4238error:
4239 yang_free_nodes(module->ctx, sibling);
4240 yang_free_nodes(module->ctx, child);
4241 return EXIT_FAILURE;
4242}
4243
4244static int
PavolVican75af21d2016-12-29 20:04:07 +01004245yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4246 struct lys_node *dev_target, struct ly_set *dflt_check)
4247{
4248 struct lys_node_leaflist *llist;
4249 struct lys_type *type;
4250 struct lys_tpdf *tmp_parent;
4251 int i, j;
4252
PavolVican6f000922017-02-10 12:56:59 +01004253 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4254 goto error;
4255 }
PavolVican75af21d2016-12-29 20:04:07 +01004256 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4257 goto error;
4258 }
4259 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4260 goto error;
4261 }
4262 if (deviate->dflt_size) {
4263 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4264 goto error;
4265 }
4266 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4267 /* consolidate the final list in the target after removing items from it */
4268 llist = (struct lys_node_leaflist *)dev_target;
4269 for (i = j = 0; j < llist->dflt_size; j++) {
4270 llist->dflt[i] = llist->dflt[j];
4271 if (llist->dflt[i]) {
4272 i++;
4273 }
4274 }
4275 llist->dflt_size = i + 1;
4276 }
4277 }
4278
4279 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4280 goto error;
4281 }
4282
4283 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4284 goto error;
4285 }
4286
4287 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4288 goto error;
4289 }
4290
4291 if ((deviate->flags & LYS_CONFIG_MASK)) {
4292 /* add and replace are the same in this case */
4293 /* remove current config value of the target ... */
4294 dev_target->flags &= ~LYS_CONFIG_MASK;
4295
4296 /* ... and replace it with the value specified in deviation */
4297 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4298 }
4299
4300 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4301 goto error;
4302 }
4303
4304 if (deviate->type) {
4305 /* check target node type */
4306 if (dev_target->nodetype == LYS_LEAF) {
4307 type = &((struct lys_node_leaf *)dev_target)->type;
4308 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4309 type = &((struct lys_node_leaflist *)dev_target)->type;
4310 } else {
4311 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4312 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
4313 goto error;
4314 }
4315 /* remove type and initialize it */
4316 tmp_parent = type->parent;
4317 lys_type_free(module->ctx, type);
4318 memcpy(type, deviate->type, sizeof *deviate->type);
4319 free(deviate->type);
4320 deviate->type = type;
4321 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004322 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4323 goto error;
4324 }
4325
PavolVican75af21d2016-12-29 20:04:07 +01004326 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4327 goto error;
4328 }
4329 }
4330
4331 return EXIT_SUCCESS;
4332error:
4333 if (deviate->type) {
4334 yang_type_free(module->ctx, deviate->type);
4335 deviate->type = NULL;
4336 }
4337 return EXIT_FAILURE;
4338}
4339
4340static int
4341yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4342{
4343 int rc;
4344 uint i;
4345 struct lys_node *dev_target = NULL, *parent;
4346 struct ly_set *dflt_check = ly_set_new();
4347 unsigned int u;
4348 const char *value, *target_name;
4349 struct lys_node_leaflist *llist;
4350 struct lys_node_leaf *leaf;
4351 struct unres_schema tmp_unres;
4352 struct lys_module *mod;
4353
4354 /* resolve target node */
4355 rc = resolve_augment_schema_nodeid(dev->target_name, NULL, module, 1, (const struct lys_node **)&dev_target);
4356 if (rc || !dev_target) {
4357 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4358 goto error;
4359 }
4360 if (dev_target->module == lys_main_module(module)) {
4361 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4362 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4363 goto error;
4364 }
4365
4366 if (!dflt_check) {
4367 LOGMEM;
4368 goto error;
4369 }
4370
4371 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4372 /* you cannot remove a key leaf */
4373 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4374 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4375 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4376 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4377 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
4378 return EXIT_FAILURE;
4379 }
4380 }
4381 }
4382 /* unlink and store the original node */
4383 lys_node_unlink(dev_target);
4384 dev->orig_node = dev_target;
4385 } else {
4386 /* store a shallow copy of the original node */
4387 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004388 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004389 /* just to be safe */
4390 if (tmp_unres.count) {
4391 LOGINT;
4392 goto error;
4393 }
4394 }
4395
PavolVican6f000922017-02-10 12:56:59 +01004396 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
4397 goto error;
4398 }
4399
PavolVican75af21d2016-12-29 20:04:07 +01004400 for (i = 0; i < dev->deviate_size; ++i) {
4401 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4402 yang_free_deviate(module->ctx, dev, i + 1);
4403 dev->deviate_size = i+1;
4404 goto error; // missing free unresolve type in deviate
4405 }
4406 }
4407 /* now check whether default value, if any, matches the type */
4408 for (u = 0; u < dflt_check->number; ++u) {
4409 value = NULL;
4410 rc = EXIT_SUCCESS;
4411 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4412 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4413 target_name = leaf->name;
4414 value = leaf->dflt;
4415 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4416 } else { /* LYS_LEAFLIST */
4417 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4418 target_name = llist->name;
4419 for (i = 0; i < llist->dflt_size; i++) {
4420 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4421 (struct lys_node *)(&llist->dflt[i]));
4422 if (rc == -1) {
4423 value = llist->dflt[i];
4424 break;
4425 }
4426 }
4427 }
4428 if (rc == -1) {
4429 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4430 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
4431 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4432 target_name);
4433 goto error;
4434 }
4435 }
4436 ly_set_free(dflt_check);
4437
4438 /* mark all the affected modules as deviated and implemented*/
4439 for(parent = dev_target; parent; parent = lys_parent(parent)) {
4440 mod = lys_node_module(parent);
4441 if (module != mod) {
4442 mod->deviated = 1;
4443 lys_set_implemented(mod);
4444 }
4445}
4446
4447 return EXIT_SUCCESS;
4448error:
4449 ly_set_free(dflt_check);
4450 return EXIT_FAILURE;
4451}
4452
4453static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004454yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4455{
PavolVican75af21d2016-12-29 20:04:07 +01004456 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004457
4458 aug_size = module->augment_size;
4459 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004460 dev_size = module->deviation_size;
4461 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004462
PavolVicanc1807262017-01-31 18:00:27 +01004463 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4464 goto error;
4465 }
4466
PavolVican171717d2017-02-01 14:49:55 +01004467 /* check extension in revision */
4468 for (i = 0; i < module->rev_size; ++i) {
4469 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4470 goto error;
4471 }
4472 }
4473
PavolVican19dc6152017-02-06 12:04:15 +01004474 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004475 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004476 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4477 goto error;
4478 }
4479 }
4480
Pavol Vican7313fc02016-11-14 01:10:31 +01004481 if (yang_check_typedef(module, NULL, unres)) {
4482 goto error;
4483 }
4484
Pavol Vican7a7916f2016-11-21 23:38:30 +01004485 /* check features */
4486 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004487 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4488 goto error;
4489 }
PavolVican5393d3f2017-02-06 23:30:55 +01004490 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4491 goto error;
4492 }
4493
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004494 /* check for circular dependencies */
4495 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4496 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004497 }
4498 }
Pavol Vican36e27272016-11-22 15:47:28 +01004499 erase_identities = 0;
4500 if (yang_check_identities(module, unres)) {
4501 goto error;
4502 }
Pavol Vican05810b62016-11-23 14:07:22 +01004503 erase_nodes = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004504 if (yang_check_nodes(module, NULL, node, CONFIG_INHERIT_ENABLE, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004505 goto error;
4506 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004507
PavolVican75af21d2016-12-29 20:04:07 +01004508 /* check deviation */
4509 for (i = 0; i < dev_size; ++i) {
4510 module->deviation_size++;
4511 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4512 goto error;
4513 }
4514 }
4515
Pavol Vican3ad50f82016-12-04 15:00:36 +01004516 /* check augments */
4517 for (i = 0; i < aug_size; ++i) {
4518 module->augment_size++;
4519 if (yang_check_augment(module, &module->augment[i], CONFIG_INHERIT_ENABLE, unres)) {
4520 goto error;
4521 }
4522 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4523 goto error;
4524 }
4525 }
4526
Pavol Vican7313fc02016-11-14 01:10:31 +01004527 return EXIT_SUCCESS;
4528error:
Pavol Vican36e27272016-11-22 15:47:28 +01004529 if (erase_identities) {
4530 yang_free_ident_base(module->ident, 0, module->ident_size);
4531 }
Pavol Vican05810b62016-11-23 14:07:22 +01004532 if (erase_nodes) {
4533 yang_free_nodes(module->ctx, node);
4534 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004535 for (i = module->augment_size; i < aug_size; ++i) {
4536 yang_free_augment(module->ctx, &module->augment[i]);
4537 }
PavolVican75af21d2016-12-29 20:04:07 +01004538 for (i = module->deviation_size; i < dev_size; ++i) {
4539 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4540 free(module->deviation[i].deviate);
4541 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004542 return EXIT_FAILURE;
4543}
PavolVican22e88682017-02-14 22:38:18 +01004544
4545int
4546yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
4547 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4548{
4549 int c;
4550 const char **str, ***p = NULL;
4551 void *reallocated;
4552 struct lyext_substmt *info;
4553
4554 c = 0;
4555 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
4556 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4557 if (info->cardinality < LY_STMT_CARD_SOME) {
4558 str++;
4559 } else {
4560 /* get the index in the array to add new item */
4561 p = (const char ***)str;
4562 for (c = 0; p[0][c + 1]; c++);
4563 str = p[1];
4564 }
4565 str[c] = lydict_insert_zc(module->ctx, value);
4566 } else {
4567 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4568 if (!str) {
4569 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
4570 free(value);
4571 return EXIT_FAILURE;
4572 }
4573 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
4574 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
4575 free(value);
4576 return EXIT_FAILURE;
4577 }
4578
4579 if (info->cardinality >= LY_STMT_CARD_SOME) {
4580 /* there can be multiple instances, str is actually const char *** */
4581 p = (const char ***)str;
4582 if (!p[0]) {
4583 /* allocate initial array */
4584 p[0] = malloc(2 * sizeof(const char *));
4585 if (stmt == LY_STMT_BELONGSTO) {
4586 /* allocate another array for the belongs-to's prefixes */
4587 p[1] = calloc(2, sizeof(const char *));
4588 }
4589 } else {
4590 /* get the index in the array to add new item */
4591 for (c = 0; p[0][c]; c++);
4592 }
4593 str = p[0];
4594 }
4595
4596 str[c] = lydict_insert_zc(module->ctx, value);
4597
4598 if (p) {
4599 /* enlarge the array(s) */
4600 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4601 if (!reallocated) {
4602 LOGMEM;
4603 lydict_remove(module->ctx, p[0][c]);
4604 p[0][c] = NULL;
4605 return EXIT_FAILURE;
4606 }
4607 p[0] = reallocated;
4608 p[0][c + 1] = NULL;
4609
4610 if (stmt == LY_STMT_BELONGSTO) {
4611 /* enlarge the second belongs-to's array with prefixes */
4612 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4613 if (!reallocated) {
4614 LOGMEM;
4615 lydict_remove(module->ctx, p[1][c]);
4616 p[1][c] = NULL;
4617 return EXIT_FAILURE;
4618 }
4619 p[1] = reallocated;
4620 p[1][c + 1] = NULL;
4621 }
4622 }
4623 }
4624
4625 return EXIT_SUCCESS;
4626}
PavolVican5334c892017-02-15 16:29:09 +01004627
4628static int
4629yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4630{
4631 int c = 0, decrement = 0;
4632 const char **str, ***p = NULL;
4633 struct lyext_substmt *info;
4634
4635
4636 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4637 stmt = LY_STMT_BELONGSTO;
4638 decrement = -1;
4639 }
4640
4641 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4642 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4643 return 0;
4644 } else {
4645 p = (const char ***)str;
4646 /* get the index in the array */
4647 for (c = 0; p[0][c]; c++);
4648 return c + decrement;
4649 }
4650}
PavolVicana0fdbf32017-02-15 17:59:02 +01004651
4652void **
4653yang_getplace_for_extcomplex_struct(char *parent_name, char *node_name, struct lys_ext_instance_complex *ext, LY_STMT stmt)
4654{
4655 int c;
4656 void **data, ***p = NULL;
4657 void *reallocated;
4658 struct lyext_substmt *info;
4659
4660 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4661 if (!data) {
4662 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4663 return NULL;
4664 }
4665 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
4666 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4667 return NULL;
4668 }
4669
4670 c = 0;
4671 if (info->cardinality >= LY_STMT_CARD_SOME) {
4672 /* there can be multiple instances, so instead of pointer to array,
4673 * we have in data pointer to pointer to array */
4674 p = (void ***)data;
4675 data = *p;
4676 if (!data) {
4677 /* allocate initial array */
4678 *p = data = malloc(2 * sizeof(void *));
4679 } else {
4680 for (c = 0; *data; data++, c++);
4681 }
4682 }
4683
4684 if (p) {
4685 /* enlarge the array */
4686 reallocated = realloc(*p, (c + 2) * sizeof(void *));
4687 if (!reallocated) {
4688 LOGMEM;
4689 return NULL;
4690 }
4691 *p = reallocated;
4692 data = *p;
4693 data[c + 1] = NULL;
4694 }
4695
4696 return &data[c];
4697}