blob: 003925c6eeab97196d301bd0f900180196ebb81f [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,
Radek Krejci7212e0a2017-03-08 15:58:22 +010028 int options, 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);
PavolVicanf3091bf2017-02-19 18:27:01 +010030static void yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node);
Frank Rimplerc4db1c72017-09-12 12:56:39 +000031void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size, int shallow,
Radek Krejci5138e9f2017-04-12 13:10:46 +020032 void (*private_destructor)(const struct lys_node *node, void *priv));
Pavol Vican082afd02016-10-25 12:39:15 +020033
Michal Vaskofe7e5a72016-05-02 14:49:23 +020034static int
PavolVican196694c2017-01-27 10:33:09 +010035yang_check_string(struct lys_module *module, const char **target, char *what,
36 char *where, char *value, struct lys_node *node)
Pavol Vican2a064652016-02-02 22:54:34 +010037{
Pavol Vicanbf805472016-01-26 14:24:56 +010038 if (*target) {
Michal Vasko53b7da02018-02-13 15:28:42 +010039 LOGVAL(module->ctx, LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010040 free(value);
41 return 1;
42 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010043 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010044 return 0;
45 }
46}
47
Michal Vaskofe7e5a72016-05-02 14:49:23 +020048int
Pavol Vican5f0316a2016-04-05 21:21:11 +020049yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010050{
Pavol Vican6eb14e82016-02-03 12:27:13 +010051 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010052
53 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010054 case MODULE_KEYWORD:
55 module->name = lydict_insert_zc(module->ctx, value);
56 break;
57 case NAMESPACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010058 ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +010059 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010060 case ORGANIZATION_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010061 ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010062 break;
63 case CONTACT_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010064 ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010065 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020066 default:
67 free(value);
Michal Vasko53b7da02018-02-13 15:28:42 +010068 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +020069 ret = EXIT_FAILURE;
70 break;
Pavol Vican2a064652016-02-02 22:54:34 +010071 }
72
Pavol Vican021488a2016-01-25 23:56:12 +010073 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010074}
75
Michal Vaskofe7e5a72016-05-02 14:49:23 +020076int
Pavol Vicand0b64c12016-07-15 09:56:19 +020077yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
78{
79 int ret = EXIT_SUCCESS;
80
81 if (repeat) {
Michal Vasko53b7da02018-02-13 15:28:42 +010082 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
Michal Vasko3767fb22016-07-21 12:10:57 +020083 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020084 } else {
85 if (!strcmp(value, "1")) {
86 if (submodule) {
87 if (module->version > 1) {
Michal Vasko53b7da02018-02-13 15:28:42 +010088 LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
Pavol Vicand0b64c12016-07-15 09:56:19 +020089 ret = EXIT_FAILURE;
90 }
Radek Krejci29eac3d2017-06-01 16:50:02 +020091 submodule->version = 1;
Pavol Vicand0b64c12016-07-15 09:56:19 +020092 } else {
93 module->version = 1;
94 }
95 } else if (!strcmp(value, "1.1")) {
96 if (submodule) {
97 if (module->version != 2) {
Michal Vasko53b7da02018-02-13 15:28:42 +010098 LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
Pavol Vicand0b64c12016-07-15 09:56:19 +020099 ret = EXIT_FAILURE;
100 }
Radek Krejci29eac3d2017-06-01 16:50:02 +0200101 submodule->version = 2;
Pavol Vicand0b64c12016-07-15 09:56:19 +0200102 } else {
103 module->version = 2;
104 }
105 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100106 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
Pavol Vicand0b64c12016-07-15 09:56:19 +0200107 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200108 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200109 }
110 free(value);
111 return ret;
112}
113
114int
Pavol Vicane024ab72016-07-27 14:27:43 +0200115yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100116{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100117 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100118
Michal Vasko53b7da02018-02-13 15:28:42 +0100119 if (!imp && lyp_check_identifier(module->ctx, value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100120 free(value);
121 return EXIT_FAILURE;
122 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200123
124 if (imp) {
PavolVican196694c2017-01-27 10:33:09 +0100125 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
Pavol Vicane024ab72016-07-27 14:27:43 +0200126 } else {
PavolVican196694c2017-01-27 10:33:09 +0100127 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +0100128 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100129
Pavol Vicanbf805472016-01-26 14:24:56 +0100130 return ret;
131}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100132
Pavol Vican1cc4e192016-10-24 16:38:31 +0200133static int
PavolVican7d0b5ab2017-02-01 13:06:53 +0100134yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
135 char *value, struct unres_schema *unres)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100136{
Pavol Vican0da132e2016-03-21 12:03:03 +0100137 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200138 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100139
Pavol Vican1cc4e192016-10-24 16:38:31 +0200140 if (!imp_old->prefix) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100141 LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 goto error;
143 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100144 if (lyp_check_identifier(module->ctx, imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +0200145 goto error;
146 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200147 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200148 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100149 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200150 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100151 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200152 module->imp_size++;
PavolVican7d0b5ab2017-02-01 13:06:53 +0100153 if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200154 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100155 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100156
Pavol Vican6eb14e82016-02-03 12:27:13 +0100157 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200158
159error:
160 free(value);
161 lydict_remove(module->ctx, imp_old->dsc);
162 lydict_remove(module->ctx, imp_old->ref);
David Sedlákb53e6702018-08-13 09:02:42 +0200163 lydict_remove(module->ctx, imp_old->prefix);
Radek Krejci5138e9f2017-04-12 13:10:46 +0200164 lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200165 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100166}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100167
168int
PavolVican196694c2017-01-27 10:33:09 +0100169yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100170{
171 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100172 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100173
PavolVican196694c2017-01-27 10:33:09 +0100174 switch (type) {
175 case MODULE_KEYWORD:
176 ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
177 break;
178 case REVISION_KEYWORD:
179 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
180 break;
181 case IMPORT_KEYWORD:
182 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
183 break;
184 case INCLUDE_KEYWORD:
185 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
186 break;
187 case NODE_PRINT:
188 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
189 break;
190 default:
191 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
192 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100193 }
194 return ret;
195}
196
197int
PavolVican196694c2017-01-27 10:33:09 +0100198yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100199{
200 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100201 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100202
PavolVican196694c2017-01-27 10:33:09 +0100203 switch (type) {
204 case MODULE_KEYWORD:
205 ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
206 break;
207 case REVISION_KEYWORD:
208 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
209 break;
210 case IMPORT_KEYWORD:
211 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
212 break;
213 case INCLUDE_KEYWORD:
214 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
215 break;
216 case NODE_PRINT:
217 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
218 break;
219 default:
220 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
221 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100222 }
223 return ret;
224}
Pavol Vicanbedff692016-02-03 14:29:17 +0100225
Pavol Vican1eeb1992016-02-09 11:10:45 +0100226int
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100227yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
228 char *value, struct unres_schema *unres, int parent_is_feature)
Pavol Vicane1354e92016-02-09 14:02:09 +0100229{
230 const char *exp;
231 int ret;
232
Michal Vasko97b32be2016-07-25 10:59:53 +0200233 if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100234 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
Michal Vasko97b32be2016-07-25 10:59:53 +0200235 free(value);
236 return EXIT_FAILURE;
237 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100238
Michal Vasko56d082c2016-10-25 14:00:42 +0200239 if (!(exp = transform_iffeat_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100240 free(value);
241 return EXIT_FAILURE;
242 }
243 free(value);
244
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100245 ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
Pavol Vicane1354e92016-02-09 14:02:09 +0100246 lydict_remove(module->ctx, exp);
Pavol Vicane1354e92016-02-09 14:02:09 +0100247
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100248 return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
Pavol Vicane1354e92016-02-09 14:02:09 +0100249}
250
Pavol Vican4fb66c92016-03-17 10:32:27 +0100251int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100252yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100253{
254 const char *exp;
255
Pavol Vican0adf01d2016-03-22 12:29:33 +0100256 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100257 free(value);
258 if (!exp) {
259 return EXIT_FAILURE;
260 }
Pavol Vican4ffd0ab2016-08-27 16:35:04 +0200261
Pavol Vican0adf01d2016-03-22 12:29:33 +0100262 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100263 lydict_remove(module->ctx, exp);
264 return EXIT_FAILURE;
265 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100266
Pavol Vicanbbdef532016-02-09 14:52:12 +0100267 lydict_remove(module->ctx, exp);
268 return EXIT_SUCCESS;
269}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100270
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100271int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100272yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100273{
274 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100275
Pavol Vicandde090a2016-08-30 15:12:14 +0200276 if (message == ERROR_APP_TAG_KEYWORD) {
PavolVican196694c2017-01-27 10:33:09 +0100277 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100278 } else {
PavolVican196694c2017-01-27 10:33:09 +0100279 ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100280 }
281 return ret;
282}
Pavol Vicanb5687112016-02-09 22:35:59 +0100283
284int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100285yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100286{
287 if (cont->presence) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100288 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100289 free(value);
290 return EXIT_FAILURE;
291 } else {
292 cont->presence = lydict_insert_zc(module->ctx, value);
293 return EXIT_SUCCESS;
294 }
295}
296
Pavol Vican235dbd42016-02-10 10:34:19 +0100297void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200298yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100299{
300 struct lys_when *retval;
301
302 retval = calloc(1, sizeof *retval);
Michal Vasko53b7da02018-02-13 15:28:42 +0100303 LY_CHECK_ERR_RETURN(!retval, LOGMEM(module->ctx); free(value), NULL);
Pavol Vican0adf01d2016-03-22 12:29:33 +0100304 retval->cond = transform_schema2json(module, value);
Michal Vasko508a50d2016-09-07 14:50:33 +0200305 if (!retval->cond) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100306 goto error;
307 }
308 switch (type) {
309 case CONTAINER_KEYWORD:
310 if (((struct lys_node_container *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100311 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100312 goto error;
313 }
314 ((struct lys_node_container *)node)->when = retval;
315 break;
Pavol Vicandb7489e2016-08-23 17:23:39 +0200316 case ANYDATA_KEYWORD:
Pavol Vican1f06ba82016-02-10 17:39:50 +0100317 case ANYXML_KEYWORD:
Radek Krejcibf2abff2016-08-23 15:51:52 +0200318 if (((struct lys_node_anydata *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100319 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100320 goto error;
321 }
Radek Krejcibf2abff2016-08-23 15:51:52 +0200322 ((struct lys_node_anydata *)node)->when = retval;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100323 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100324 case CHOICE_KEYWORD:
325 if (((struct lys_node_choice *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100326 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100327 goto error;
328 }
329 ((struct lys_node_choice *)node)->when = retval;
330 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100331 case CASE_KEYWORD:
332 if (((struct lys_node_case *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100333 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100334 goto error;
335 }
336 ((struct lys_node_case *)node)->when = retval;
337 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100338 case LEAF_KEYWORD:
339 if (((struct lys_node_leaf *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100340 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100341 goto error;
342 }
343 ((struct lys_node_leaf *)node)->when = retval;
344 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100345 case LEAF_LIST_KEYWORD:
346 if (((struct lys_node_leaflist *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100347 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100348 goto error;
349 }
350 ((struct lys_node_leaflist *)node)->when = retval;
351 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100352 case LIST_KEYWORD:
353 if (((struct lys_node_list *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100354 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100355 goto error;
356 }
357 ((struct lys_node_list *)node)->when = retval;
358 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100359 case USES_KEYWORD:
360 if (((struct lys_node_uses *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100361 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100362 goto error;
363 }
364 ((struct lys_node_uses *)node)->when = retval;
365 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100366 case AUGMENT_KEYWORD:
367 if (((struct lys_node_augment *)node)->when) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100368 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100369 goto error;
370 }
371 ((struct lys_node_augment *)node)->when = retval;
372 break;
PavolVicanb0317082017-02-19 01:29:22 +0100373 case EXTENSION_INSTANCE:
374 *(struct lys_when **)node = retval;
375 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200376 default:
377 goto error;
378 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100379 }
380 free(value);
381 return retval;
382
383error:
384 free(value);
PavolVicanb0317082017-02-19 01:29:22 +0100385 lydict_remove(module->ctx, retval->cond);
386 free(retval);
Pavol Vican235dbd42016-02-10 10:34:19 +0100387 return NULL;
388}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100389
390void *
Pavol Vican05810b62016-11-23 14:07:22 +0100391yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
392 char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100393{
Pavol Vican05810b62016-11-23 14:07:22 +0100394 struct lys_node *node, **child;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100395
Pavol Vican7cadfe72016-02-11 12:33:34 +0100396 node = calloc(1, sizeof_struct);
Michal Vasko53b7da02018-02-13 15:28:42 +0100397 LY_CHECK_ERR_RETURN(!node, LOGMEM(module->ctx); free(value), NULL);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200398
Michal Vasko3e3228d2017-02-24 14:55:32 +0100399 LOGDBG(LY_LDGYANG, "parsing %s statement \"%s\"", strnodetype(nodetype), value);
PavolVican196694c2017-01-27 10:33:09 +0100400 node->name = lydict_insert_zc(module->ctx, value);
Pavol Vican7cadfe72016-02-11 12:33:34 +0100401 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100402 node->nodetype = nodetype;
PavolVicanbd1d1ae2017-07-20 00:06:00 +0200403 node->parent = parent;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100404
405 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100406 child = (parent) ? &parent->child : root;
407 if (*child) {
408 (*child)->prev->next = node;
409 (*child)->prev = node;
410 } else {
411 *child = node;
412 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100413 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100414 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100415}
416
417int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200418yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100419{
420 int ret;
421
422 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100423 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100424 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100425 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100426 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100427 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100428 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200429 default:
430 free(value);
Michal Vasko53b7da02018-02-13 15:28:42 +0100431 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +0200432 ret = EXIT_FAILURE;
433 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100434 }
435 return ret;
436}
437
438int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200439yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100440{
441 int ret;
442
443 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100444 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100445 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100446 break;
447 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100448 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100449 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100450 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100451 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100452 break;
PavolVican75af21d2016-12-29 20:04:07 +0100453 case ADD_KEYWORD:
454 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +0100455 case DELETE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100456 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100457 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200458 default:
459 free(value);
Michal Vasko53b7da02018-02-13 15:28:42 +0100460 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +0200461 ret = EXIT_FAILURE;
462 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100463 }
464 return ret;
465}
Pavol Vican5de33492016-02-22 14:03:24 +0100466
467int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100468yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100469{
470 char *exp, *value;
471
472 exp = value = (char *) list->keys;
473 while ((value = strpbrk(value, " \t\n"))) {
474 list->keys_size++;
475 while (isspace(*value)) {
476 value++;
477 }
478 }
479 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100480
481 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100482 list->keys = calloc(list->keys_size, sizeof *list->keys);
Michal Vasko53b7da02018-02-13 15:28:42 +0100483 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM(module->ctx), EXIT_FAILURE);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200484
Radek Krejci7a1e6072018-08-13 14:59:16 +0200485 if (unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
Radek Krejci5c08a992016-11-02 13:30:04 +0100486 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100487 }
Pavol Vican5de33492016-02-22 14:03:24 +0100488 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100489}
490
491int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100492yang_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 +0100493{
494 int i, j;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200495 char *vaux, c;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200496 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100497
498 /* count the number of unique leafs in the value */
499 vaux = value;
500 while ((vaux = strpbrk(vaux, " \t\n"))) {
501 unique->expr_size++;
502 while (isspace(*vaux)) {
503 vaux++;
504 }
505 }
506 unique->expr_size++;
507 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
Michal Vasko53b7da02018-02-13 15:28:42 +0100508 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM(module->ctx), error);
Pavol Vican85f12022016-03-05 16:30:35 +0100509
510 for (i = 0; i < unique->expr_size; i++) {
511 vaux = strpbrk(value, " \t\n");
Radek Krejci1a9c3612017-04-24 14:49:43 +0200512 if (vaux) {
513 c = *vaux;
514 *vaux = '\0';
Pavol Vican85f12022016-03-05 16:30:35 +0100515 }
516
Radek Krejci1a9c3612017-04-24 14:49:43 +0200517 /* store token into unique structure (includes converting prefix to the module name) */
518 unique->expr[i] = transform_schema2json(module, value);
519 if (vaux) {
520 *vaux = c;
521 }
Pavol Vican85f12022016-03-05 16:30:35 +0100522
523 /* check that the expression does not repeat */
524 for (j = 0; j < i; j++) {
525 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100526 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
527 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100528 goto error;
529 }
530 }
531 /* try to resolve leaf */
532 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200533 unique_info = malloc(sizeof *unique_info);
Michal Vasko53b7da02018-02-13 15:28:42 +0100534 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM(module->ctx), error);
Radek Krejcid09d1a52016-08-11 14:05:45 +0200535 unique_info->list = (struct lys_node *)list;
536 unique_info->expr = unique->expr[i];
537 unique_info->trg_type = &unique->trg_type;
538 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200539 goto error;
540 }
Pavol Vican85f12022016-03-05 16:30:35 +0100541 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200542 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100543 goto error;
544 }
545 }
546
547 /* move to next token */
548 value = vaux;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200549 while(value && isspace(*value)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100550 value++;
551 }
552 }
553
554 return EXIT_SUCCESS;
555
556error:
557 return EXIT_FAILURE;
558}
559
560int
Pavol Vican5de33492016-02-22 14:03:24 +0100561yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
562{
563 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100564 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100565
Michal Vaskoe59ada92018-02-22 14:05:34 +0100566 for (k = 0; k < list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100567 str = (char *)list->unique[k].expr;
568 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100569 goto error;
570 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100571 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100572 }
573 return EXIT_SUCCESS;
574
575error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100576 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100577 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100578}
579
Pavol Vican07f220f2016-09-02 13:04:37 +0200580int
Pavol Vican81344ac2016-09-02 14:23:06 +0200581yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100582{
Pavol Vican81344ac2016-09-02 14:23:06 +0200583 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100584 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200585 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100586 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200587 if (stype->type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100588 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200589 goto error;
590 }
591 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
592 stype->base = LY_TYPE_LEAFREF;
593 return EXIT_SUCCESS;
594
595error:
596 free(value);
597 return EXIT_FAILURE;
598}
599
600int
Michal Vasko53b7da02018-02-13 15:28:42 +0100601yang_read_require_instance(struct ly_ctx *ctx, struct yang_type *stype, int req)
Pavol Vican81344ac2016-09-02 14:23:06 +0200602{
603 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100604 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200605 return EXIT_FAILURE;
606 }
607 if (stype->type->info.lref.req) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100608 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200609 return EXIT_FAILURE;
610 }
611 stype->type->info.lref.req = req;
612 stype->base = LY_TYPE_LEAFREF;
613 return EXIT_SUCCESS;
614}
615
616int
Pavol Vican7313fc02016-11-14 01:10:31 +0100617yang_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 +0100618{
Michal Vasko53b7da02018-02-13 15:28:42 +0100619 struct ly_ctx *ctx = module->ctx;
Radek Krejcidce5f972017-09-12 15:47:49 +0200620 int rc, ret = -1;
621 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200622 int8_t req;
Michal Vasko568b1952018-01-30 15:53:30 +0100623 const char *name, *value, *module_name = NULL;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100624 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200625 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200626 struct lys_type *dertype;
627 struct lys_type_enum *enms_sc = NULL;
628 struct lys_type_bit *bits_sc = NULL;
629 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100630 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100631
Pavol Vican0adf01d2016-03-22 12:29:33 +0100632 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100633 if (!value) {
634 goto error;
635 }
636
637 i = parse_identifier(value);
638 if (i < 1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100639 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
640 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100641 goto error;
642 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200643 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100644 name = value;
645 if (value[i]) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100646 module_name = lydict_insert(ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100647 name += i;
648 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100649 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
650 lydict_remove(ctx, module_name);
651 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100652 goto error;
653 }
654 ++name;
655 }
656
Michal Vasko568b1952018-01-30 15:53:30 +0100657 rc = resolve_superior_type(name, module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100658 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100659 LOGVAL(ctx, LYE_INMOD, LY_VLOG_NONE, NULL, module_name);
660 lydict_remove(ctx, module_name);
661 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100662 goto error;
663
Michal Vasko01c6fd22016-05-20 11:43:05 +0200664 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100665 } else if (rc == EXIT_FAILURE) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100666 LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
667 lydict_remove(ctx, module_name);
668 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100669 ret = EXIT_FAILURE;
670 goto error;
671 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100672 lydict_remove(ctx, module_name);
673 lydict_remove(ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200674
Michal Vasko101658e2018-06-05 15:05:54 +0200675 if (type->value_flags & LY_VALUE_UNRESGRP) {
Radek Krejcic13db382016-08-16 10:52:42 +0200676 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Michal Vasko70bf8e52018-03-26 11:32:33 +0200677 * unresolved item left inside the grouping, LYTYPE_GRP used as a flag for types inside a grouping. */
Radek Krejcic13db382016-08-16 10:52:42 +0200678 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
679 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200680 assert(((struct lys_node_grp *)siter)->unres_count);
681 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200682 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100683 LOGINT(ctx);
Radek Krejcic13db382016-08-16 10:52:42 +0200684 goto error;
685 }
Michal Vasko101658e2018-06-05 15:05:54 +0200686 type->value_flags &= ~LY_VALUE_UNRESGRP;
Radek Krejcic13db382016-08-16 10:52:42 +0200687 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200688
689 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100690 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
691 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200692 goto error;
693 }
694
Pavol Vican8bd72e42016-08-29 09:53:05 +0200695 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100696 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100697 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100698 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100699 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100700 }
701 switch (base) {
702 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100703 if (type->base == LY_TYPE_BINARY) {
704 if (type->info.str.pat_count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100705 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100706 goto error;
707 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100708 type->info.binary.length = type->info.str.length;
Michal Vasko53b7da02018-02-13 15:28:42 +0100709 if (type->info.binary.length && lyp_check_length_range(ctx, type->info.binary.length->expr, type)) {
710 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100711 goto error;
712 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100713 } else if (type->base == LY_TYPE_STRING) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100714 if (type->info.str.length && lyp_check_length_range(ctx, type->info.str.length->expr, type)) {
715 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100716 goto error;
717 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100718 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100719 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100720 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100721 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100722 break;
723 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100724 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100725 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100726 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100727 /* decimal64 type directly derived from built-in type requires fraction-digits */
Michal Vasko53b7da02018-02-13 15:28:42 +0100728 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100729 goto error;
730 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100731 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100732 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Michal Vasko53b7da02018-02-13 15:28:42 +0100733 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100734 goto error;
735 }
Radek Krejci4800f652016-09-08 14:02:52 +0200736
737 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100738 if (type->der->type.der) {
739 type->info.dec64.dig = type->der->type.info.dec64.dig;
740 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200741 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100742 if (type->info.dec64.range && lyp_check_length_range(ctx, type->info.dec64.range->expr, type)) {
743 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200744 goto error;
745 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100746 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
747 if (type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100748 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100749 goto error;
750 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100751 type->info.num.range = type->info.dec64.range;
Michal Vasko53b7da02018-02-13 15:28:42 +0100752 if (type->info.num.range && lyp_check_length_range(ctx, type->info.num.range->expr, type)) {
753 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100754 goto error;
755 }
756 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100757 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100758 goto error;
759 }
760 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100761 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100762 if (type->base != LY_TYPE_ENUM) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100763 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100764 goto error;
765 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100766 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200767
768 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100769 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200770 /* type is derived directly from buit-in enumeartion type and enum statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100771 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200772 goto error;
773 }
774 } else {
775 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100776 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200777 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
778 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100779 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200780 goto error;
781 }
782
783 /* restricted enumeration type - the name MUST be used in the base type */
784 enms_sc = dertype->info.enums.enm;
Michal Vaskoe59ada92018-02-22 14:05:34 +0100785 for (i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200786 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100787 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200788 break;
789 }
790 }
791 if (j == dertype->info.enums.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100792 LOGVAL(ctx, LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200793 goto error;
794 }
795
Pavol Vican7313fc02016-11-14 01:10:31 +0100796 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200797 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100798 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200799 } else {
800 /* check that the assigned value corresponds to the original
801 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100802 if (type->info.enums.enm[i].value != enms_sc[j].value) {
803 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200804 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100805 LOGVAL(ctx, LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
Pavol Vican7313fc02016-11-14 01:10:31 +0100806 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200807 goto error;
808 }
809 }
810 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100811 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100812 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100813 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100814 if (type->base != LY_TYPE_BITS) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100815 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100816 goto error;
817 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100818 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200819
820 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100821 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200822 /* type is derived directly from buit-in bits type and bit statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100823 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200824 goto error;
825 }
826 } else {
827 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100828 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200829 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
830 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100831 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200832 goto error;
833 }
834
835 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100836 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200837 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200839 break;
840 }
841 }
842 if (j == dertype->info.bits.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100843 LOGVAL(ctx, LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200844 goto error;
845 }
846
847 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100848 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200849 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100850 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200851 } else {
852 /* check that the assigned position corresponds to the original
853 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100854 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
855 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200856 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100857 LOGVAL(ctx, LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
Pavol Vican7313fc02016-11-14 01:10:31 +0100858 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200859 goto error;
860 }
861 }
862 }
Pavol Vican03a59442016-03-21 15:23:45 +0100863 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200864
Radek Krejcidce5f972017-09-12 15:47:49 +0200865 for (i = type->info.bits.count; i > 0; i--) {
866 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200867
868 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100869 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200870 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100871 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
872 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
873 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200874 j--;
875 }
Pavol Vican03a59442016-03-21 15:23:45 +0100876 }
877 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100878 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100879 if (type->base == LY_TYPE_INST) {
880 if (type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100881 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100882 goto error;
883 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100884 if ((req = type->info.lref.req)) {
885 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200886 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100887 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200888 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100889 if (type->info.lref.req && (module->version < 2)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100890 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican92626d72016-09-21 09:36:09 +0200891 goto error;
892 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200893 /* flag resolving for later use */
894 if (!tpdftype) {
895 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
896 if (siter) {
897 /* just a flag - do not resolve */
898 tpdftype = 1;
899 }
900 }
901
Pavol Vican7313fc02016-11-14 01:10:31 +0100902 if (type->info.lref.path) {
903 if (type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100904 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican894ee0f2016-08-30 15:29:46 +0200905 goto error;
906 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100907 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100908 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100909 type->info.lref.path = transform_schema2json(module, value);
Michal Vasko53b7da02018-02-13 15:28:42 +0100910 lydict_remove(ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100911 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100912 goto error;
913 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200914 /* try to resolve leafref path only when this is instantiated
915 * leaf, so it is not:
916 * - typedef's type,
917 * - in grouping definition,
918 * - just instantiated in a grouping definition,
919 * because in those cases the nodes referenced in path might not be present
920 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100921 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100922 goto error;
923 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100924 } else if (!type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100925 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100926 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200927 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200928 /* copy leafref definition into the derived type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100929 type->info.lref.path = lydict_insert(ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200930 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100931 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200932 goto error;
933 }
Pavol Vican191613a2016-02-26 16:21:32 +0100934 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100935 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100936 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100937 goto error;
938 }
939 break;
940 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100941 if (type->base != LY_TYPE_IDENT) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100942 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100943 goto error;
944 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100945 if (type->der->type.der) {
946 if (type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100947 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
Pavol Vican07f220f2016-09-02 13:04:37 +0200948 goto error;
949 }
950 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100951 if (!type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100952 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
Pavol Vican07f220f2016-09-02 13:04:37 +0200953 goto error;
954 }
955 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100956 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100957 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100958 if (type->base != LY_TYPE_UNION) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100959 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100960 goto error;
961 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100962 if (!type->info.uni.types) {
963 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100964 /* this is just a derived type with no additional type specified/required */
Michal Vaskob6ab50c2018-03-08 13:46:10 +0100965 assert(type->der->type.base == LY_TYPE_UNION);
966 type->info.uni.has_ptr_type = type->der->type.info.uni.has_ptr_type;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100967 break;
968 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100969 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100970 goto error;
971 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100972 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100973 dertype = &type->info.uni.types[i];
Michal Vasko70bf8e52018-03-26 11:32:33 +0200974 if (dertype->base == LY_TYPE_DER) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100975 yang = (struct yang_type *)dertype->der;
976 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100977 dertype->parent = type->parent;
978 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100979 dertype->der = (struct lys_tpdf *)yang;
980 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100981 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100982 base = 0;
983 goto error;
984 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100985 lydict_remove(ctx, yang->name);
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100986 free(yang);
987 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100988 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200989 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100990 if (dertype->base == LY_TYPE_EMPTY) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100991 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200992 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100993 } else if (dertype->base == LY_TYPE_LEAFREF) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100994 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200995 goto error;
996 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100997 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100998 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
999 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +01001000 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001001 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001002 }
1003 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001004
1005 default:
1006 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001007 if (type->base != base) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001008 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001009 goto error;
1010 }
1011 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001012 LOGINT(ctx);
Pavol Vicana1827962016-02-29 15:39:42 +01001013 goto error;
1014 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001015 }
PavolVican92f23622017-12-12 13:35:56 +01001016
1017 /* if derived type has extension, which need validate data */
1018 dertype = &type->der->type;
1019 while (dertype->der) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01001020 if (dertype->parent->flags & LYS_VALID_EXT) {
1021 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01001022 }
1023 dertype = &dertype->der->type;
1024 }
1025
Pavol Vican73e7c992016-02-24 12:18:05 +01001026 return EXIT_SUCCESS;
1027
1028error:
Pavol Vican8bd72e42016-08-29 09:53:05 +02001029 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001030 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001031 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001032 return ret;
1033}
1034
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001035void
1036yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1037{
1038 struct lys_type *stype;
1039 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001040 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001041
1042 for (i = 0; i < type->info.uni.count; ++i) {
1043 stype = &type->info.uni.types[i];
Michal Vasko70bf8e52018-03-26 11:32:33 +02001044 if (stype->base == LY_TYPE_DER) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001045 yang = (struct yang_type *)stype->der;
1046 stype->base = yang->base;
1047 lydict_remove(ctx, yang->name);
1048 free(yang);
1049 } else if (stype->base == LY_TYPE_UNION) {
1050 yang_free_type_union(ctx, stype);
1051 }
1052 }
1053}
1054
Pavol Vican73e7c992016-02-24 12:18:05 +01001055void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001056yang_read_type(struct ly_ctx *ctx, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001057{
1058 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001059 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001060
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001061 typ = calloc(1, sizeof *typ);
Michal Vasko53b7da02018-02-13 15:28:42 +01001062 LY_CHECK_ERR_RETURN(!typ, LOGMEM(ctx), NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001063
1064 typ->flags = LY_YANG_STRUCTURE_FLAG;
1065 switch (type) {
1066 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001067 if (((struct lys_node_leaf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001068 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
Pavol Vican85427f02016-09-26 15:21:05 +02001069 goto error;
1070 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001071 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1072 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1073 typ->type = &((struct lys_node_leaf *)parent)->type;
1074 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001075 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001076 if (((struct lys_node_leaflist *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001077 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
Pavol Vican85427f02016-09-26 15:21:05 +02001078 goto error;
1079 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001080 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1081 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1082 typ->type = &((struct lys_node_leaflist *)parent)->type;
1083 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001084 case UNION_KEYWORD:
1085 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1086 typ->type = (struct lys_type *)parent;
1087 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001088 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001089 if (((struct lys_tpdf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001090 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
Pavol Vican85427f02016-09-26 15:21:05 +02001091 goto error;
1092 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001093 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1094 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001095 break;
1096 case REPLACE_KEYWORD:
1097 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001098 dev = (struct lys_deviate *)parent;
1099 if (dev->type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001100 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001101 goto error;
1102 }
PavolVican75af21d2016-12-29 20:04:07 +01001103 dev->type = calloc(1, sizeof *dev->type);
Michal Vasko53b7da02018-02-13 15:28:42 +01001104 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001105 dev->type->der = (struct lys_tpdf *)typ;
1106 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001107 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001108 case EXTENSION_INSTANCE:
1109 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1110 typ->type = parent;
1111 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001112 default:
1113 goto error;
1114 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001115 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001116 typ->name = lydict_insert_zc(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001117 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001118
1119error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001120 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001121 free(typ);
1122 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001123}
1124
1125void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001126yang_read_length(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001127{
PavolVicaneef1d912017-02-19 00:19:15 +01001128 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001129
PavolVicaneef1d912017-02-19 00:19:15 +01001130 if (is_ext_instance) {
1131 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001132 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001133 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1134 stype->base = LY_TYPE_STRING;
1135 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001136 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001137 goto error;
1138 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001139
PavolVicaneef1d912017-02-19 00:19:15 +01001140 if (stype->type->info.str.length) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001141 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001142 goto error;
1143 }
1144 length = calloc(1, sizeof *length);
Michal Vasko53b7da02018-02-13 15:28:42 +01001145 LY_CHECK_ERR_GOTO(!length, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001146 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001147 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001148 length->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001149 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001150
1151error:
1152 free(value);
1153 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001154}
Pavol Vican1c203db2016-02-24 14:05:23 +01001155
Pavol Vican6eecf302016-08-10 11:09:05 +02001156int
Michal Vasko53b7da02018-02-13 15:28:42 +01001157yang_read_pattern(struct ly_ctx *ctx, struct lys_restr *pattern, void **precomp, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001158{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001159 char *buf;
1160 size_t len;
1161
Michal Vasko53b7da02018-02-13 15:28:42 +01001162 if (precomp && lyp_precompile_pattern(ctx, value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001163 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001164 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001165 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001166
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001167 len = strlen(value);
1168 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Michal Vasko53b7da02018-02-13 15:28:42 +01001169 LY_CHECK_ERR_RETURN(!buf, LOGMEM(ctx); free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001170
1171 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001172 strcpy(&buf[1], value);
1173 free(value);
1174
Michal Vasko53b7da02018-02-13 15:28:42 +01001175 pattern->expr = lydict_insert_zc(ctx, buf);
Pavol Vican6eecf302016-08-10 11:09:05 +02001176 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001177}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001178
1179void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001180yang_read_range(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001181{
PavolVicaneef1d912017-02-19 00:19:15 +01001182 struct lys_restr * range;
1183
1184 if (is_ext_instance) {
1185 range = (struct lys_restr *)stype;
1186 } else {
1187 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001188 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001189 goto error;
1190 }
1191 stype->base = LY_TYPE_DEC64;
1192 if (stype->type->info.dec64.range) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001193 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001194 goto error;
1195 }
1196 range = calloc(1, sizeof *range);
Michal Vasko53b7da02018-02-13 15:28:42 +01001197 LY_CHECK_ERR_GOTO(!range, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001198 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001199 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001200 range->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001201 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001202
1203error:
1204 free(value);
1205 return NULL;
1206}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001207
1208int
Michal Vasko53b7da02018-02-13 15:28:42 +01001209yang_read_fraction(struct ly_ctx *ctx, struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001210{
Michal Vasko27e5e682018-07-23 14:22:57 +02001211 uint32_t i;
1212
Pavol Vican6b072512016-04-04 10:50:21 +02001213 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1214 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001215 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001216 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001217 goto error;
1218 }
1219 if (typ->type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001220 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001221 goto error;
1222 }
1223 /* range check */
1224 if (value < 1 || value > 18) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001225 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001226 goto error;
1227 }
1228 typ->type->info.dec64.dig = value;
Michal Vasko27e5e682018-07-23 14:22:57 +02001229 typ->type->info.dec64.div = 10;
1230 for (i = 1; i < value; i++) {
1231 typ->type->info.dec64.div *= 10;
1232 }
Pavol Vican07ea68d2016-02-25 12:01:37 +01001233 return EXIT_SUCCESS;
1234
1235error:
1236 return EXIT_FAILURE;
1237}
Pavol Vican79a763d2016-02-25 15:41:27 +01001238
Pavol Vican874715f2016-10-25 14:52:08 +02001239int
Michal Vasko53b7da02018-02-13 15:28:42 +01001240yang_read_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001241{
Pavol Vican874715f2016-10-25 14:52:08 +02001242 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001243
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001244 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001245 if (!value[0]) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001246 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1247 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
Pavol Vicanc6662412016-08-30 08:06:28 +02001248 free(value);
1249 goto error;
1250 }
1251
Michal Vasko53b7da02018-02-13 15:28:42 +01001252 enm->name = lydict_insert_zc(ctx, value);
Pavol Vican79a763d2016-02-25 15:41:27 +01001253
1254 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1255 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001256 LOGVAL(ctx, LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001257 goto error;
1258 }
1259
Pavol Vican874715f2016-10-25 14:52:08 +02001260 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001261 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001262 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001263 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001264 LOGVAL(ctx, LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001265 goto error;
1266 }
1267 }
1268
Pavol Vican874715f2016-10-25 14:52:08 +02001269 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001270
1271error:
Pavol Vican874715f2016-10-25 14:52:08 +02001272 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001273}
1274
1275int
Michal Vasko53b7da02018-02-13 15:28:42 +01001276yang_check_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001277{
1278 int i, j;
1279
1280 if (!assign) {
1281 /* assign value automatically */
1282 if (*value > INT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001283 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001284 goto error;
1285 }
1286 enm->value = *value;
1287 enm->flags |= LYS_AUTOASSIGNED;
1288 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001289 } else if (typ->type->info.enums.enm == enm) {
1290 /* change value, which is assigned automatically, if first enum has value. */
1291 *value = typ->type->info.enums.enm[0].value;
1292 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001293 }
1294
1295 /* check that the value is unique */
1296 j = typ->type->info.enums.count-1;
1297 for (i = 0; i < j; i++) {
1298 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001299 LOGVAL(ctx, LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001300 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1301 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001302 goto error;
1303 }
1304 }
1305
1306 return EXIT_SUCCESS;
1307
1308error:
1309 return EXIT_FAILURE;
1310}
Pavol Vican9887c682016-02-29 11:32:01 +01001311
Pavol Vican59e8dee2016-10-25 15:29:38 +02001312int
Michal Vasko53b7da02018-02-13 15:28:42 +01001313yang_read_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001314{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001315 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001316
PavolVicane87cb932016-12-30 15:36:18 +01001317 typ->base = LY_TYPE_BITS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001318 bit->name = lydict_insert_zc(ctx, value);
1319 if (lyp_check_identifier(ctx, bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001320 goto error;
1321 }
Pavol Vican9887c682016-02-29 11:32:01 +01001322
Pavol Vican59e8dee2016-10-25 15:29:38 +02001323 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001324 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001325 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001326 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001327 LOGVAL(ctx, LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001328 goto error;
1329 }
1330 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001331 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001332
1333error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001334 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001335}
1336
1337int
Michal Vasko53b7da02018-02-13 15:28:42 +01001338yang_check_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001339{
1340 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001341
1342 if (!assign) {
1343 /* assign value automatically */
1344 if (*value > UINT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001345 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001346 goto error;
1347 }
1348 bit->pos = (uint32_t)*value;
1349 bit->flags |= LYS_AUTOASSIGNED;
1350 (*value)++;
1351 }
1352
1353 j = typ->type->info.bits.count - 1;
1354 /* check that the value is unique */
1355 for (i = 0; i < j; i++) {
1356 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001357 LOGVAL(ctx, 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 +01001358 goto error;
1359 }
1360 }
1361
Pavol Vican9887c682016-02-29 11:32:01 +01001362 return EXIT_SUCCESS;
1363
1364error:
1365 return EXIT_FAILURE;
1366}
Pavol Vican0df02b02016-03-01 10:28:50 +01001367
Pavol Vican3ad50f82016-12-04 15:00:36 +01001368int
1369yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001370{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001371 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001372 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001373 free(value);
1374 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001375 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001376 }
1377 aug->parent = parent;
1378 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001379 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001380}
Pavol Vican220e5a12016-03-03 14:19:43 +01001381
PavolVican6f000922017-02-10 12:56:59 +01001382void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001383yang_read_deviate_unsupported(struct ly_ctx *ctx, struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001384{
PavolVican75af21d2016-12-29 20:04:07 +01001385 if (dev->deviate_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001386 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001387 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001388 }
PavolVican75af21d2016-12-29 20:04:07 +01001389 dev->deviate = calloc(1, sizeof *dev->deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001390 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001391 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1392 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001393 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001394}
1395
1396void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001397yang_read_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001398{
PavolVican75af21d2016-12-29 20:04:07 +01001399 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001400
PavolVican4b80d042017-02-23 14:30:27 +01001401 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001402 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1403 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001404 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001405 }
PavolVican75af21d2016-12-29 20:04:07 +01001406 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1407 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001408 LY_CHECK_ERR_RETURN(!deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001409 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1410 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001411 }
PavolVican75af21d2016-12-29 20:04:07 +01001412 dev->deviate[dev->deviate_size].mod = mod;
1413 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001414}
1415
1416int
PavolVican75af21d2016-12-29 20:04:07 +01001417yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001418{
1419 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001420 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001421
Pavol Vican85f12022016-03-05 16:30:35 +01001422 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001423 if (dev_target->nodetype == LYS_LEAFLIST) {
1424 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1425 } else if (dev_target->nodetype == LYS_LEAF) {
1426 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001427 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001428 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1429 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001430 goto error;
1431 }
1432
PavolVican75af21d2016-12-29 20:04:07 +01001433 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001434 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001435 if (!ly_strequal(*stritem, deviate->units, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001436 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
1437 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001438 goto error;
1439 }
1440 /* remove current units value of the target */
1441 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001442 *stritem = NULL;
1443 /* remove its extensions */
1444 j = -1;
1445 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1446 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1447 --j;
1448 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001449 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001450 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001451 /* check that there is no current value */
1452 if (*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001453 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1454 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001455 goto error;
1456 }
1457 } else { /* replace */
1458 if (!*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001459 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1460 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001461 goto error;
1462 }
1463 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001464 /* remove current units value of the target ... */
1465 lydict_remove(ctx, *stritem);
1466
1467 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001468 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001469 }
1470
Pavol Vican85f12022016-03-05 16:30:35 +01001471 return EXIT_SUCCESS;
1472
1473error:
1474 return EXIT_FAILURE;
1475}
1476
1477int
PavolVican75af21d2016-12-29 20:04:07 +01001478yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001479{
Michal Vasko53b7da02018-02-13 15:28:42 +01001480 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican85f12022016-03-05 16:30:35 +01001481 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001482 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001483
1484 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001485 if (dev_target->nodetype != LYS_LIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001486 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1487 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001488 goto error;
1489 }
1490
PavolVican75af21d2016-12-29 20:04:07 +01001491 list = (struct lys_node_list *)dev_target;
1492 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001493 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001494 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Michal Vasko53b7da02018-02-13 15:28:42 +01001495 LY_CHECK_ERR_GOTO(!unique, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001496 list->unique = unique;
1497 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001498 }
1499
1500 return EXIT_SUCCESS;
1501
1502error:
1503 return EXIT_FAILURE;
1504}
1505
1506int
PavolVican75af21d2016-12-29 20:04:07 +01001507yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1508 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001509{
1510 struct lys_node *node;
1511 struct lys_node_choice *choice;
1512 struct lys_node_leaf *leaf;
1513 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001514 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001515 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001516
Pavol Vican38321d02016-08-16 14:56:02 +02001517 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001518 if (dev_target->nodetype == LYS_CHOICE) {
1519 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001520 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1521 if (rc || !node) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001522 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001523 goto error;
1524 }
PavolVican75af21d2016-12-29 20:04:07 +01001525 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001526 if (!choice->dflt || (choice->dflt != node)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001527 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1528 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001529 goto error;
1530 }
PavolVican6f000922017-02-10 12:56:59 +01001531 choice->dflt = NULL;
1532 /* remove extensions of this default instance from the target node */
1533 j = -1;
1534 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1535 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1536 --j;
1537 }
Pavol Vican38321d02016-08-16 14:56:02 +02001538 } else { /* add or replace */
1539 choice->dflt = node;
1540 if (!choice->dflt) {
1541 /* default branch not found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001542 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001543 goto error;
1544 }
1545 }
PavolVican75af21d2016-12-29 20:04:07 +01001546 } else if (dev_target->nodetype == LYS_LEAF) {
1547 leaf = (struct lys_node_leaf *)dev_target;
1548 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001549 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001550 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1551 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001552 goto error;
1553 }
1554 /* remove value */
1555 lydict_remove(ctx, leaf->dflt);
1556 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001557 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001558 /* remove extensions of this default instance from the target node */
1559 j = -1;
1560 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1561 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1562 --j;
1563 }
Pavol Vican38321d02016-08-16 14:56:02 +02001564 } else { /* add (already checked) and replace */
1565 /* remove value */
1566 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001567 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001568
1569 /* set new value */
1570 leaf->dflt = lydict_insert(ctx, value, u);
1571
1572 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001573 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001574 }
1575 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001576 llist = (struct lys_node_leaflist *)dev_target;
1577 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001578 /* find and remove the value in target list */
1579 for (i = 0; i < llist->dflt_size; i++) {
1580 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1581 /* match, remove the value */
1582 lydict_remove(llist->module->ctx, llist->dflt[i]);
1583 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001584 /* remove extensions of this default instance from the target node */
1585 j = -1;
1586 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1587 if (dev_target->ext[j]->insubstmt_index == i) {
1588 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1589 --j;
1590 } else if (dev_target->ext[j]->insubstmt_index > i) {
1591 /* decrease the substatement index of the extension because of the changed array of defaults */
1592 dev_target->ext[j]->insubstmt_index--;
1593 }
1594 }
Pavol Vican38321d02016-08-16 14:56:02 +02001595 break;
1596 }
1597 }
1598 if (i == llist->dflt_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001599 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1600 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
Pavol Vican38321d02016-08-16 14:56:02 +02001601 goto error;
1602 }
1603 } else {
1604 /* add or replace, anyway we place items into the deviate's list
1605 which propagates to the target */
1606 /* we just want to check that the value isn't already in the list */
1607 for (i = 0; i < llist->dflt_size; i++) {
1608 if (ly_strequal(llist->dflt[i], value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001609 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1610 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
Pavol Vican38321d02016-08-16 14:56:02 +02001611 goto error;
1612 }
1613 }
1614 /* store it in target node */
1615 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1616
1617 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001618 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001619 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001620 }
1621 }
1622
1623 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001624
Pavol Vican38321d02016-08-16 14:56:02 +02001625error:
1626 return EXIT_FAILURE;
1627}
1628
Pavol Vican38321d02016-08-16 14:56:02 +02001629int
PavolVican75af21d2016-12-29 20:04:07 +01001630yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1631 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001632{
Michal Vasko53b7da02018-02-13 15:28:42 +01001633 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001634 int i;
1635 struct lys_node_leaflist *llist;
1636 const char **dflt;
1637
1638 /* check target node type */
1639 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001640 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1641 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001642 goto error;
1643 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
Michal Vasko53b7da02018-02-13 15:28:42 +01001644 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1645 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
PavolVican75af21d2016-12-29 20:04:07 +01001646 goto error;
1647 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001648 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1649 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001650 goto error;
1651 }
1652
PavolVican75af21d2016-12-29 20:04:07 +01001653 if (deviate->mod == LY_DEVIATE_ADD) {
1654 /* check that there is no current value */
1655 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1656 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001657 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1658 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
PavolVican75af21d2016-12-29 20:04:07 +01001659 goto error;
1660 }
Pavol Vican85f12022016-03-05 16:30:35 +01001661
PavolVican75af21d2016-12-29 20:04:07 +01001662 /* check collision with mandatory/min-elements */
1663 if ((dev_target->flags & LYS_MAND_TRUE) ||
1664 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001665 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1666 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
PavolVican75af21d2016-12-29 20:04:07 +01001667 "Adding the \"default\" statement is forbidden on %s statement.",
1668 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1669 goto error;
1670 }
1671 } else if (deviate->mod == LY_DEVIATE_RPL) {
1672 /* check that there was a value before */
1673 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1674 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001675 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1676 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
PavolVican75af21d2016-12-29 20:04:07 +01001677 goto error;
1678 }
1679 }
Pavol Vican85f12022016-03-05 16:30:35 +01001680
PavolVican75af21d2016-12-29 20:04:07 +01001681 if (dev_target->nodetype == LYS_LEAFLIST) {
1682 /* reallocate default list in the target */
1683 llist = (struct lys_node_leaflist *)dev_target;
1684 if (deviate->mod == LY_DEVIATE_ADD) {
1685 /* reallocate (enlarge) the unique array of the target */
1686 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001687 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001688 llist->dflt = dflt;
1689 } else if (deviate->mod == LY_DEVIATE_RPL) {
1690 /* reallocate (replace) the unique array of the target */
1691 for (i = 0; i < llist->dflt_size; i++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001692 lydict_remove(ctx, llist->dflt[i]);
PavolVican75af21d2016-12-29 20:04:07 +01001693 }
1694 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001695 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001696 llist->dflt = dflt;
1697 llist->dflt_size = 0;
1698 }
1699 }
1700
1701 for (i = 0; i < deviate->dflt_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001702 if (yang_fill_deviate_default(ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
PavolVican75af21d2016-12-29 20:04:07 +01001703 goto error;
1704 }
1705 }
Pavol Vican85f12022016-03-05 16:30:35 +01001706
1707 return EXIT_SUCCESS;
1708
1709error:
1710 return EXIT_FAILURE;
1711}
1712
1713int
PavolVican75af21d2016-12-29 20:04:07 +01001714yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001715{
Michal Vasko53b7da02018-02-13 15:28:42 +01001716 struct ly_ctx *ctx = dev_target->module->ctx;
Radek Krejcie00d2312016-08-12 15:27:49 +02001717 struct lys_node *parent;
1718
Pavol Vican85f12022016-03-05 16:30:35 +01001719 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001720 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001721 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1722 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001723 goto error;
1724 }
1725
PavolVican75af21d2016-12-29 20:04:07 +01001726 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001727 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001728 if (dev_target->flags & LYS_MAND_MASK) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001729 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1730 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001731 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001732 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001733 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001734 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
Michal Vasko53b7da02018-02-13 15:28:42 +01001735 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1736 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001737 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001738 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001739 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1740 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001741 goto error;
1742 }
Pavol Vican85f12022016-03-05 16:30:35 +01001743 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001744 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001745 if (!(dev_target->flags & LYS_MAND_MASK)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001746 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1747 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001748 goto error;
1749 }
Pavol Vican85f12022016-03-05 16:30:35 +01001750 }
1751
Pavol Vican85f12022016-03-05 16:30:35 +01001752 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001753 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001754
1755 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001756 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001757
Radek Krejcie00d2312016-08-12 15:27:49 +02001758 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001759 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001760 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1761 parent = parent->parent) {
1762 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1763 /* stop also on presence containers */
1764 break;
1765 }
1766 }
1767 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1768 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1769 if (lyp_check_mandatory_choice(parent)) {
1770 goto error;
1771 }
1772 }
1773
Pavol Vican85f12022016-03-05 16:30:35 +01001774 return EXIT_SUCCESS;
1775
1776error:
1777 return EXIT_FAILURE;
1778}
1779
1780int
PavolVican75af21d2016-12-29 20:04:07 +01001781yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001782{
Michal Vasko53b7da02018-02-13 15:28:42 +01001783 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican09adcc32016-08-25 10:51:36 +02001784 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001785
1786 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001787 if (dev_target->nodetype == LYS_LEAFLIST) {
1788 max = &((struct lys_node_leaflist *)dev_target)->max;
1789 min = &((struct lys_node_leaflist *)dev_target)->min;
1790 } else if (dev_target->nodetype == LYS_LIST) {
1791 max = &((struct lys_node_list *)dev_target)->max;
1792 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001793 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001794 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1795 LOGVAL(ctx, 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 +01001796 goto error;
1797 }
1798
PavolVican75af21d2016-12-29 20:04:07 +01001799 ui32val = (type) ? max : min;
1800 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001801 /* check that there is no current value */
1802 if (*ui32val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001803 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1804 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001805 goto error;
1806 }
PavolVican75af21d2016-12-29 20:04:07 +01001807 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001808 /* unfortunately, there is no way to check reliably that there
1809 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001810 }
1811
1812 /* add (already checked) and replace */
1813 /* set new value specified in deviation */
1814 *ui32val = value;
1815
Pavol Vican09adcc32016-08-25 10:51:36 +02001816 /* check min-elements is smaller than max-elements */
1817 if (*max && *min > *max) {
1818 if (type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001819 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1820 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001821 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001822 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1823 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001824 }
1825 goto error;
1826 }
1827
Pavol Vican85f12022016-03-05 16:30:35 +01001828 return EXIT_SUCCESS;
1829
1830error:
1831 return EXIT_FAILURE;
1832}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001833
1834int
PavolVican75af21d2016-12-29 20:04:07 +01001835yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1836 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001837{
Michal Vasko53b7da02018-02-13 15:28:42 +01001838 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001839 int i, j, erase_must = 1;
1840 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001841 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001842
PavolVican75af21d2016-12-29 20:04:07 +01001843 /* check target node type */
1844 switch (dev_target->nodetype) {
1845 case LYS_LEAF:
1846 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1847 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001848 break;
PavolVican75af21d2016-12-29 20:04:07 +01001849 case LYS_CONTAINER:
1850 trg_must = &((struct lys_node_container *)dev_target)->must;
1851 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1852 break;
1853 case LYS_LEAFLIST:
1854 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1855 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1856 break;
1857 case LYS_LIST:
1858 trg_must = &((struct lys_node_list *)dev_target)->must;
1859 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1860 break;
1861 case LYS_ANYXML:
1862 case LYS_ANYDATA:
1863 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1864 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1865 break;
1866 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01001867 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1868 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001869 goto error;
1870 }
1871
1872 /* flag will be checked again, clear it for now */
Michal Vaskoc04173b2018-03-09 10:43:22 +01001873 dev_target->flags &= ~(LYS_XPCONF_DEP | LYS_XPSTATE_DEP);
PavolVican75af21d2016-12-29 20:04:07 +01001874
1875 if (deviate->mod == LY_DEVIATE_ADD) {
1876 /* reallocate the must array of the target */
1877 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Michal Vasko53b7da02018-02-13 15:28:42 +01001878 LY_CHECK_ERR_GOTO(!must, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001879 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001880 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican214408f2017-02-03 11:54:05 +01001881 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001882 erase_must = 0;
1883 } else if (deviate->mod == LY_DEVIATE_DEL) {
1884 /* find must to delete, we are ok with just matching conditions */
1885 for (j = 0; j < deviate->must_size; ++j) {
1886 for (i = 0; i < *trg_must_size; i++) {
1887 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1888 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001889 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001890 /* ... and maintain the array */
1891 (*trg_must_size)--;
1892 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001893 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001894 }
1895 if (!(*trg_must_size)) {
1896 free(*trg_must);
1897 *trg_must = NULL;
1898 } else {
PavolVican214408f2017-02-03 11:54:05 +01001899 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001900 }
1901
1902 i = -1; /* set match flag */
1903 break;
1904 }
1905 }
1906 if (i != -1) {
1907 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001908 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1909 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
PavolVican75af21d2016-12-29 20:04:07 +01001910 goto error;
1911 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001912 }
1913 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001914
PavolVican6f000922017-02-10 12:56:59 +01001915 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1916 goto error;
1917 }
PavolVican75af21d2016-12-29 20:04:07 +01001918 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02001919 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1920 && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001921 goto error;
1922 }
1923
PavolVican75af21d2016-12-29 20:04:07 +01001924 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001925
PavolVican75af21d2016-12-29 20:04:07 +01001926error:
1927 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1928 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001929 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001930 }
1931 free(deviate->must);
1932 }
1933 return EXIT_FAILURE;
1934}
1935
1936int
1937yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1938 struct lys_node_list *list, int index, char * value)
1939{
Michal Vasko53b7da02018-02-13 15:28:42 +01001940 struct ly_ctx *ctx = module->ctx;
PavolVican6f000922017-02-10 12:56:59 +01001941 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001942
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001943 /* find unique structures to delete */
1944 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001945 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001946 continue;
1947 }
1948
PavolVican75af21d2016-12-29 20:04:07 +01001949 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1950 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001951 break;
1952 }
1953 }
1954
PavolVican75af21d2016-12-29 20:04:07 +01001955 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001956 /* we have a match, free the unique structure ... */
1957 for (j = 0; j < list->unique[i].expr_size; j++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001958 lydict_remove(ctx, list->unique[i].expr[j]);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001959 }
1960 free(list->unique[i].expr);
1961 /* ... and maintain the array */
1962 list->unique_size--;
1963 if (i != list->unique_size) {
1964 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1965 list->unique[i].expr = list->unique[list->unique_size].expr;
1966 }
1967
1968 if (!list->unique_size) {
1969 free(list->unique);
1970 list->unique = NULL;
1971 } else {
1972 list->unique[list->unique_size].expr_size = 0;
1973 list->unique[list->unique_size].expr = NULL;
1974 }
1975
PavolVican6f000922017-02-10 12:56:59 +01001976 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001977 i = -1; /* set match flag */
1978 break;
1979 }
1980 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001981
1982 if (i != -1) {
1983 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001984 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1985 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001986 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001987 }
1988
PavolVican6f000922017-02-10 12:56:59 +01001989 /* remove extensions of this unique instance from the target node */
1990 j = -1;
1991 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1992 if (list->ext[j]->insubstmt_index == k) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001993 lyp_ext_instance_rm(ctx, &list->ext, &list->ext_size, j);
PavolVican6f000922017-02-10 12:56:59 +01001994 --j;
1995 } else if (list->ext[j]->insubstmt_index > k) {
1996 /* decrease the substatement index of the extension because of the changed array of uniques */
1997 list->ext[j]->insubstmt_index--;
1998 }
1999 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002000 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002001}
Pavol Vican021488a2016-01-25 23:56:12 +01002002
PavolVican75af21d2016-12-29 20:04:07 +01002003int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01002004{
PavolVican75af21d2016-12-29 20:04:07 +01002005 struct lys_node_list *list;
2006 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01002007 uint i = 0;
2008 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01002009
PavolVican75af21d2016-12-29 20:04:07 +01002010 if (yang_read_deviate_unique(deviate, dev_target)) {
2011 goto error;
2012 }
2013 list = (struct lys_node_list *)dev_target;
2014 last_unique = &list->unique[list->unique_size];
2015 for (i = 0; i < deviate->unique_size; ++i) {
2016 str = (char *) deviate->unique[i].expr;
2017 if (deviate->mod == LY_DEVIATE_ADD) {
2018 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2019 free(str);
2020 goto error;
2021 }
2022 list->unique_size++;
2023 } else if (deviate->mod == LY_DEVIATE_DEL) {
2024 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2025 free(str);
2026 goto error;
2027 }
2028 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2029 free(str);
2030 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002031 }
2032 }
PavolVican75af21d2016-12-29 20:04:07 +01002033 free(str);
2034 }
2035 if (deviate->mod == LY_DEVIATE_ADD) {
2036 free(deviate->unique);
2037 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002038 }
Pavol Vican38321d02016-08-16 14:56:02 +02002039
PavolVican75af21d2016-12-29 20:04:07 +01002040 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01002041
Pavol Vican021488a2016-01-25 23:56:12 +01002042error:
PavolVican75af21d2016-12-29 20:04:07 +01002043 if (deviate->mod == LY_DEVIATE_ADD) {
2044 for (i = i + 1; i < deviate->unique_size; ++i) {
2045 free(deviate->unique[i].expr);
2046 }
2047 free(deviate->unique);
2048 deviate->unique = last_unique;
2049
2050 }
Pavol Vican021488a2016-01-25 23:56:12 +01002051 return EXIT_FAILURE;
2052}
2053
Pavol Vicanec423c92016-10-24 21:33:43 +02002054static int
2055yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2056 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002057{
Pavol Vican55870412016-03-10 12:36:21 +01002058 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002059 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002060 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002061
Pavol Vicanec423c92016-10-24 21:33:43 +02002062 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002063 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002064 if (!rc) {
2065 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002066 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002067 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2068 &trg->inc[trg->inc_size], unres)) {
2069 ret = -1;
2070 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002071 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002072 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002073 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002074 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002075 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002076
Pavol Vicanec423c92016-10-24 21:33:43 +02002077 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002078 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002079}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002080
PavolVicanc1807262017-01-31 18:00:27 +01002081struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002082yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002083{
2084 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2085 LYEXT_PAR parent_type;
Michal Vaskoa310a452018-11-21 12:34:29 +01002086 uint8_t *size;
PavolVicanc1807262017-01-31 18:00:27 +01002087
2088 switch (type) {
2089 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002090 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002091 ext = &((struct lys_module *)node)->ext;
2092 size = &((struct lys_module *)node)->ext_size;
2093 parent_type = LYEXT_PAR_MODULE;
2094 break;
PavolVican22e88682017-02-14 22:38:18 +01002095 case BELONGS_TO_KEYWORD:
2096 if (is_ext_instance) {
2097 ext = &((struct lys_ext_instance *)node)->ext;
2098 size = &((struct lys_ext_instance *)node)->ext_size;
2099 parent_type = LYEXT_PAR_EXTINST;
2100 } else {
2101 ext = &((struct lys_module *)node)->ext;
2102 size = &((struct lys_module *)node)->ext_size;
2103 parent_type = LYEXT_PAR_MODULE;
2104 }
2105 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002106 case IMPORT_KEYWORD:
2107 ext = &((struct lys_import *)node)->ext;
2108 size = &((struct lys_import *)node)->ext_size;
2109 parent_type = LYEXT_PAR_IMPORT;
2110 break;
2111 case INCLUDE_KEYWORD:
2112 ext = &((struct lys_include *)node)->ext;
2113 size = &((struct lys_include *)node)->ext_size;
2114 parent_type = LYEXT_PAR_INCLUDE;
2115 break;
PavolVican171717d2017-02-01 14:49:55 +01002116 case REVISION_KEYWORD:
2117 ext = &((struct lys_revision *)node)->ext;
2118 size = &((struct lys_revision *)node)->ext_size;
2119 parent_type = LYEXT_PAR_REVISION;
2120 break;
PavolVican70ce7452017-02-01 15:39:39 +01002121 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002122 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002123 case LEAF_KEYWORD:
2124 case LEAF_LIST_KEYWORD:
2125 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002126 case CHOICE_KEYWORD:
2127 case CASE_KEYWORD:
2128 case ANYXML_KEYWORD:
2129 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002130 case USES_KEYWORD:
2131 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002132 case ACTION_KEYWORD:
2133 case RPC_KEYWORD:
2134 case INPUT_KEYWORD:
2135 case OUTPUT_KEYWORD:
2136 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002137 ext = &((struct lys_node *)node)->ext;
2138 size = &((struct lys_node *)node)->ext_size;
2139 parent_type = LYEXT_PAR_NODE;
2140 break;
PavolVican19dc6152017-02-06 12:04:15 +01002141 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002142 if (is_ext_instance) {
2143 ext = &((struct lys_ext_instance *)node)->ext;
2144 size = &((struct lys_ext_instance *)node)->ext_size;
2145 parent_type = LYEXT_PAR_EXTINST;
2146 } else {
2147 ext = &((struct lys_ext *)node)->ext;
2148 size = &((struct lys_ext *)node)->ext_size;
2149 parent_type = LYEXT_PAR_EXT;
2150 }
2151 break;
PavolVican19dc6152017-02-06 12:04:15 +01002152 case EXTENSION_KEYWORD:
2153 ext = &((struct lys_ext *)node)->ext;
2154 size = &((struct lys_ext *)node)->ext_size;
2155 parent_type = LYEXT_PAR_EXT;
2156 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002157 case FEATURE_KEYWORD:
2158 ext = &((struct lys_feature *)node)->ext;
2159 size = &((struct lys_feature *)node)->ext_size;
2160 parent_type = LYEXT_PAR_FEATURE;
2161 break;
PavolVican8fa31242017-02-07 11:04:26 +01002162 case IDENTITY_KEYWORD:
2163 ext = &((struct lys_ident *)node)->ext;
2164 size = &((struct lys_ident *)node)->ext_size;
2165 parent_type = LYEXT_PAR_IDENT;
2166 break;
2167 case IF_FEATURE_KEYWORD:
2168 ext = &((struct lys_iffeature *)node)->ext;
2169 size = &((struct lys_iffeature *)node)->ext_size;
2170 parent_type = LYEXT_PAR_IFFEATURE;
2171 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002172 case TYPEDEF_KEYWORD:
2173 ext = &((struct lys_tpdf *)node)->ext;
2174 size = &((struct lys_tpdf *)node)->ext_size;
2175 parent_type = LYEXT_PAR_TPDF;
2176 break;
PavolVican056fcd12017-02-07 15:36:53 +01002177 case TYPE_KEYWORD:
2178 ext = &((struct yang_type *)node)->type->ext;
2179 size = &((struct yang_type *)node)->type->ext_size;
2180 parent_type = LYEXT_PAR_TYPE;
2181 break;
2182 case LENGTH_KEYWORD:
2183 case PATTERN_KEYWORD:
2184 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002185 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002186 ext = &((struct lys_restr *)node)->ext;
2187 size = &((struct lys_restr *)node)->ext_size;
2188 parent_type = LYEXT_PAR_RESTR;
2189 break;
PavolVican59ba4602017-02-08 11:53:32 +01002190 case WHEN_KEYWORD:
2191 ext = &((struct lys_when *)node)->ext;
2192 size = &((struct lys_when *)node)->ext_size;
2193 parent_type = LYEXT_PAR_RESTR;
2194 break;
PavolVican056fcd12017-02-07 15:36:53 +01002195 case ENUM_KEYWORD:
2196 ext = &((struct lys_type_enum *)node)->ext;
2197 size = &((struct lys_type_enum *)node)->ext_size;
2198 parent_type = LYEXT_PAR_TYPE_ENUM;
2199 break;
2200 case BIT_KEYWORD:
2201 ext = &((struct lys_type_bit *)node)->ext;
2202 size = &((struct lys_type_bit *)node)->ext_size;
2203 parent_type = LYEXT_PAR_TYPE_BIT;
2204 break;
PavolVican77374ee2017-02-08 15:18:45 +01002205 case REFINE_KEYWORD:
2206 ext = &((struct lys_type_bit *)node)->ext;
2207 size = &((struct lys_type_bit *)node)->ext_size;
2208 parent_type = LYEXT_PAR_REFINE;
2209 break;
PavolVican6f000922017-02-10 12:56:59 +01002210 case DEVIATION_KEYWORD:
2211 ext = &((struct lys_deviation *)node)->ext;
2212 size = &((struct lys_deviation *)node)->ext_size;
2213 parent_type = LYEXT_PAR_DEVIATION;
2214 break;
2215 case NOT_SUPPORTED_KEYWORD:
2216 case ADD_KEYWORD:
2217 case DELETE_KEYWORD:
2218 case REPLACE_KEYWORD:
2219 ext = &((struct lys_deviate *)node)->ext;
2220 size = &((struct lys_deviate *)node)->ext_size;
2221 parent_type = LYEXT_PAR_DEVIATE;
2222 break;
PavolVicandefa4852017-02-10 13:13:23 +01002223 case EXTENSION_INSTANCE:
2224 ext = &((struct lys_ext_instance *)node)->ext;
2225 size = &((struct lys_ext_instance *)node)->ext_size;
2226 parent_type = LYEXT_PAR_EXTINST;
2227 break;
PavolVicanc1807262017-01-31 18:00:27 +01002228 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002229 LOGINT(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002230 return NULL;
2231 }
2232
2233 instance = calloc(1, sizeof *instance);
2234 if (!instance) {
2235 goto error;
2236 }
2237 instance->parent_type = parent_type;
2238 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2239 if (!tmp) {
2240 goto error;
2241 }
2242 tmp[*size] = instance;
2243 *ext = tmp;
2244 (*size)++;
2245 return instance;
2246
2247error:
Michal Vasko53b7da02018-02-13 15:28:42 +01002248 LOGMEM(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002249 free(instance);
2250 return NULL;
2251}
2252
2253void *
2254yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002255 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002256{
2257 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002258 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002259
2260 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002261 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002262 if (!instance) {
2263 return NULL;
2264 }
PavolVicanc1807262017-01-31 18:00:27 +01002265 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002266 case YANG_VERSION_KEYWORD:
2267 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002268 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002269 break;
PavolVicanc1807262017-01-31 18:00:27 +01002270 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002271 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002272 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002273 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002274 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002275 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002276 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002277 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002278 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002279 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002280 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002281 break;
2282 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002283 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002284 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002285 break;
2286 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002287 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002288 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002289 break;
PavolVican171717d2017-02-01 14:49:55 +01002290 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002291 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002292 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002293 break;
2294 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002295 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002296 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002297 break;
PavolVican19dc6152017-02-06 12:04:15 +01002298 case YIN_ELEMENT_KEYWORD:
2299 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002300 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002301 break;
2302 case STATUS_KEYWORD:
2303 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002304 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002305 break;
PavolVican8fa31242017-02-07 11:04:26 +01002306 case BASE_KEYWORD:
2307 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002308 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002309 if (backup_type == IDENTITY_KEYWORD) {
2310 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002311 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002312 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2313 }
PavolVican8fa31242017-02-07 11:04:26 +01002314 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002315 case DEFAULT_KEYWORD:
2316 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002317 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002318 switch (backup_type) {
2319 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002320 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002321 break;
2322 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002323 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002324 break;
2325 case ADD_KEYWORD:
2326 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2327 break;
2328 default:
2329 /* nothing changes */
2330 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002331 }
PavolVicandf9e7972017-02-07 11:41:38 +01002332 break;
2333 case UNITS_KEYWORD:
2334 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002335 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002336 break;
PavolVican056fcd12017-02-07 15:36:53 +01002337 case REQUIRE_INSTANCE_KEYWORD:
2338 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002339 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002340 break;
2341 case PATH_KEYWORD:
2342 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002343 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002344 break;
2345 case ERROR_MESSAGE_KEYWORD:
2346 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002347 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002348 break;
2349 case ERROR_APP_TAG_KEYWORD:
2350 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002351 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002352 break;
2353 case MODIFIER_KEYWORD:
2354 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002355 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002356 break;
2357 case FRACTION_DIGITS_KEYWORD:
2358 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002359 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002360 break;
2361 case VALUE_KEYWORD:
2362 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002363 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002364 break;
2365 case POSITION_KEYWORD:
2366 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002367 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002368 break;
PavolVican5b910842017-02-08 13:08:47 +01002369 case PRESENCE_KEYWORD:
2370 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002371 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002372 break;
2373 case CONFIG_KEYWORD:
2374 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002375 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002376 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002377 case MANDATORY_KEYWORD:
2378 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002379 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002380 break;
2381 case MIN_ELEMENTS_KEYWORD:
2382 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002383 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002384 break;
2385 case MAX_ELEMENTS_KEYWORD:
2386 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002387 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002388 break;
2389 case ORDERED_BY_KEYWORD:
2390 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002391 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002392 break;
2393 case KEY_KEYWORD:
2394 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002395 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002396 break;
2397 case UNIQUE_KEYWORD:
2398 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002399 stmt = LY_STMT_UNIQUE;
2400 switch (backup_type) {
2401 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002402 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002403 break;
2404 case ADD_KEYWORD:
2405 case DELETE_KEYWORD:
2406 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002407 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002408 break;
2409 default:
2410 /* nothing changes */
2411 break;
PavolVican6f000922017-02-10 12:56:59 +01002412 }
PavolVican3feb2f92017-02-08 13:44:39 +01002413 break;
PavolVicanc1807262017-01-31 18:00:27 +01002414 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002415 LOGINT(module->ctx);
PavolVicanc1807262017-01-31 18:00:27 +01002416 return NULL;
2417 }
2418 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002419 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002420 if (!instance) {
2421 return NULL;
2422 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002423 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002424 switch (actual_type) {
2425 case ARGUMENT_KEYWORD:
2426 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002427 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002428 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002429 case BELONGS_TO_KEYWORD:
2430 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002431 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002432 break;
PavolVican19dc6152017-02-06 12:04:15 +01002433 default:
2434 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2435 break;
2436 }
PavolVicanc1807262017-01-31 18:00:27 +01002437 }
2438 instance->flags |= LYEXT_OPT_YANG;
2439 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2440 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002441 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2442 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2443 }
PavolVicanc1807262017-01-31 18:00:27 +01002444 return instance;
2445}
2446
PavolVican05c4f9b2017-09-07 13:33:54 +02002447static int
2448check_status_flag(struct lys_node *node, struct lys_node *parent)
2449{
Michal Vasko53b7da02018-02-13 15:28:42 +01002450 struct ly_ctx *ctx = node->module->ctx;
PavolVican05c4f9b2017-09-07 13:33:54 +02002451 char *str;
2452
Radek Krejcie4dce292017-10-30 11:16:47 +01002453 if (node->nodetype & (LYS_OUTPUT | LYS_INPUT)) {
2454 return EXIT_SUCCESS;
2455 }
2456
PavolVican05c4f9b2017-09-07 13:33:54 +02002457 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2458 /* status is not inherited by specification, but it not make sense to have
2459 * current in deprecated or deprecated in obsolete, so we print warning
2460 * and fix the schema by inheriting */
2461 if (!(node->flags & (LYS_STATUS_MASK))) {
2462 /* status not explicitely specified on the current node -> inherit */
Michal Vasko395b0a02018-01-22 09:36:20 +01002463 str = lys_path(node, LYS_PATH_FIRST_PREFIX);
Michal Vasko53b7da02018-02-13 15:28:42 +01002464 LOGWRN(ctx, "Missing status in %s subtree (%s), inheriting.",
PavolVican05c4f9b2017-09-07 13:33:54 +02002465 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2466 free(str);
2467 node->flags |= parent->flags & LYS_STATUS_MASK;
2468 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2469 /* invalid combination of statuses */
2470 switch (node->flags & LYS_STATUS_MASK) {
2471 case 0:
2472 case LYS_STATUS_CURR:
Michal Vasko53b7da02018-02-13 15:28:42 +01002473 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002474 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2475 break;
2476 case LYS_STATUS_DEPRC:
Michal Vasko53b7da02018-02-13 15:28:42 +01002477 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002478 "obsolete", parent->name);
2479 break;
2480 }
2481 return EXIT_FAILURE;
2482 }
2483 }
2484
2485 return EXIT_SUCCESS;
2486}
2487
Pavol Vicanf4717e62016-03-16 11:30:01 +01002488int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002489store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002490{
Pavol Vicanec598812016-11-30 14:13:38 +01002491 switch (node->nodetype) {
2492 case LYS_CONTAINER:
2493 case LYS_LEAF:
2494 case LYS_LEAFLIST:
2495 case LYS_LIST:
2496 case LYS_CHOICE:
2497 case LYS_ANYDATA:
2498 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002499 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002500 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002501 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002502 if (!(node->flags & LYS_CONFIG_MASK)) {
2503 /* get config flag from parent */
2504 if (node->parent) {
2505 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2506 } else {
2507 /* default config is true */
2508 node->flags |= LYS_CONFIG_W;
2509 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002510 }
2511 }
Pavol Vicanec598812016-11-30 14:13:38 +01002512 break;
2513 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002514 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002515 if (!(node->flags & LYS_CONFIG_MASK)) {
2516 /* get config flag from parent */
2517 if (node->parent) {
2518 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2519 } else {
2520 /* default config is true */
2521 node->flags |= LYS_CONFIG_W;
2522 }
2523 }
2524 }
2525 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002526 default:
2527 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002528 }
Pavol Vicanec598812016-11-30 14:13:38 +01002529
Radek Krejci7212e0a2017-03-08 15:58:22 +01002530 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002531}
2532
2533int
Pavol Vican9d50a772016-10-14 22:23:36 +02002534yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2535 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002536{
Pavol Vican974377b2016-03-23 00:38:53 +01002537 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002538 YY_BUFFER_STATE bp;
2539 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002540 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002541 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002542 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002543
Pavol Vican8e7110b2016-03-22 17:00:26 +01002544 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002545 yylex_init(&scanner);
Michal Vasko53b7da02018-02-13 15:28:42 +01002546 yyset_extra(module->ctx, scanner);
Pavol Vican4fb66c92016-03-17 10:32:27 +01002547 bp = yy_scan_buffer((char *)data, size, scanner);
2548 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002549 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002550 param.module = module;
2551 param.submodule = submodule;
2552 param.unres = unres;
2553 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002554 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002555 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002556 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002557 trg = (submodule) ? (struct lys_module *)submodule : module;
2558 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2559 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2560 trg->inc_size = 0;
2561 trg->imp_size = 0;
2562 }
PavolVican22e88682017-02-14 22:38:18 +01002563 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2564 }
2565 yy_delete_buffer(bp, scanner);
2566 yylex_destroy(scanner);
2567 return ret;
2568}
2569
2570int
2571yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2572 char *ext_name, struct lys_ext_instance_complex *ext)
2573{
2574 unsigned int size;
2575 YY_BUFFER_STATE bp;
2576 yyscan_t scanner = NULL;
2577 int ret = 0;
2578 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002579 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002580
PavolVicandb0e8172017-02-20 00:46:09 +01002581 if (!data) {
2582 return EXIT_SUCCESS;
2583 }
PavolVican22e88682017-02-14 22:38:18 +01002584 size = strlen(data) + 2;
2585 yylex_init(&scanner);
2586 bp = yy_scan_buffer((char *)data, size, scanner);
2587 yy_switch_to_buffer(bp, scanner);
2588 memset(&param, 0, sizeof param);
2589 param.module = module;
2590 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002591 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002592 param.actual_node = (void **)ext;
2593 param.data_node = (void **)ext_name;
2594 param.flags |= EXT_INSTANCE_SUBSTMT;
2595 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002596 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002597 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002598 } else {
2599 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002600 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002601 ret = -1;
2602 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002603 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002604 yy_delete_buffer(bp, scanner);
2605 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002606 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002607}
2608
2609struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002610yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002611{
PavolVican9e81c6a2017-02-09 13:09:07 +01002612 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002613 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002614 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002615 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002616
2617 unres = calloc(1, sizeof *unres);
Michal Vasko53b7da02018-02-13 15:28:42 +01002618 LY_CHECK_ERR_GOTO(!unres, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002619
2620 module = calloc(1, sizeof *module);
Michal Vasko53b7da02018-02-13 15:28:42 +01002621 LY_CHECK_ERR_GOTO(!module, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002622
2623 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002624 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002625 module->type = 0;
2626 module->implemented = (implement ? 1 : 0);
2627
Radek Krejci9e757e02017-03-08 17:18:09 +01002628 /* add into the list of processed modules */
2629 if (lyp_check_circmod_add(module)) {
2630 goto error;
2631 }
2632
PavolVican9e81c6a2017-02-09 13:09:07 +01002633 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2634 if (ret == -1) {
Radek Krejciec376502018-08-22 15:32:33 +02002635 if (ly_vecode(ctx) == LYVE_SUBMODULE && !module->name) {
Andrew Langefeldceaf8b42018-08-08 18:32:00 -05002636 /* Remove this module from the list of processed modules,
2637 as we're about to free it */
Andrew Langefeld71e24242018-08-08 20:10:17 -05002638 lyp_check_circmod_pop(ctx);
Andrew Langefeldceaf8b42018-08-08 18:32:00 -05002639
Radek Krejci95e00a42017-11-02 16:29:22 +01002640 free(module);
2641 module = NULL;
2642 } else {
2643 free_yang_common(module, node);
2644 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002645 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002646 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002647 assert(!unres->count);
2648 } else {
2649 if (yang_check_sub_module(module, unres, node)) {
2650 goto error;
2651 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002652
Michal Vasko0f437062018-06-08 15:52:39 +02002653 if (!implement && module->implemented && lys_make_implemented_r(module, unres)) {
2654 goto error;
2655 }
2656
Michal Vasko7b460e52017-02-10 14:50:26 +01002657 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002658 goto error;
2659 }
Michal Vasko78ef03a2018-08-03 14:30:06 +02002660
2661 /* check correctness of includes */
2662 if (lyp_check_include_missing(module)) {
2663 goto error;
2664 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002665 }
2666
PavolVicanfe83b152017-02-19 03:19:29 +01002667 lyp_sort_revisions(module);
2668
Michal Vasko78ef03a2018-08-03 14:30:06 +02002669 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
2670 goto error;
2671 }
2672
Pavol Vican8e7110b2016-03-22 17:00:26 +01002673 if (revision) {
2674 /* check revision of the parsed model */
2675 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2676 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2677 module->name, module->rev[0].date, revision);
2678 goto error;
2679 }
2680 }
2681
PavolVican9e81c6a2017-02-09 13:09:07 +01002682 /* add into context if not already there */
2683 if (!ret) {
2684 if (lyp_ctx_add_module(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002685 goto error;
2686 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002687
Michal Vasko10681e82018-01-16 14:54:16 +01002688 /* remove our submodules from the parsed submodules list */
2689 lyp_del_includedup(module, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002690 } else {
2691 tmp_mod = module;
2692
2693 /* get the model from the context */
Radek Krejcidfb00d62017-09-06 09:39:35 +02002694 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002695 assert(module);
2696
2697 /* free what was parsed */
Michal Vasko10681e82018-01-16 14:54:16 +01002698 lys_free(tmp_mod, NULL, 0, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002699 }
2700
Michal Vasko181b7672018-04-23 12:03:44 +02002701 unres_schema_free(NULL, &unres, 0);
Michal Vasko78ef03a2018-08-03 14:30:06 +02002702 lyp_check_circmod_pop(ctx);
Michal Vaskobe136f62017-09-21 12:08:39 +02002703 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2704 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002705 return module;
2706
2707error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002708 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002709 unres_schema_free(module, &unres, 1);
Michal Vasko78ef03a2018-08-03 14:30:06 +02002710
Radek Krejcif505cd12017-06-13 10:32:48 +02002711 if (!module) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002712 if (ly_vecode(ctx) != LYVE_SUBMODULE) {
2713 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002714 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002715 return NULL;
2716 }
2717
Radek Krejcif505cd12017-06-13 10:32:48 +02002718 if (module->name) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002719 LOGERR(ctx, ly_errno, "Module \"%s\" parsing failed.", module->name);
Radek Krejcif505cd12017-06-13 10:32:48 +02002720 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01002721 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejcif505cd12017-06-13 10:32:48 +02002722 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002723
Michal Vasko78ef03a2018-08-03 14:30:06 +02002724 lyp_check_circmod_pop(ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002725 lys_sub_module_remove_devs_augs(module);
Michal Vasko10681e82018-01-16 14:54:16 +01002726 lyp_del_includedup(module, 1);
2727 lys_free(module, NULL, 0, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002728 return NULL;
2729}
2730
2731struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002732yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002733{
2734 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002735 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002736
2737 submodule = calloc(1, sizeof *submodule);
Michal Vasko53b7da02018-02-13 15:28:42 +01002738 LY_CHECK_ERR_GOTO(!submodule, LOGMEM(module->ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002739
2740 submodule->ctx = module->ctx;
2741 submodule->type = 1;
Radek Krejci29eac3d2017-06-01 16:50:02 +02002742 submodule->implemented = module->implemented;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002743 submodule->belongsto = module;
2744
Radek Krejci9e757e02017-03-08 17:18:09 +01002745 /* add into the list of processed modules */
2746 if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2747 goto error;
2748 }
2749
PavolVican9e81c6a2017-02-09 13:09:07 +01002750 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002751 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002752 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002753 goto error;
2754 }
2755
PavolVicanfe83b152017-02-19 03:19:29 +01002756 lyp_sort_revisions((struct lys_module *)submodule);
2757
Pavol Vican7313fc02016-11-14 01:10:31 +01002758 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002759 goto error;
2760 }
2761
Radek Krejci9e757e02017-03-08 17:18:09 +01002762 lyp_check_circmod_pop(module->ctx);
2763
Pavol Vican8e7110b2016-03-22 17:00:26 +01002764 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002765 return submodule;
2766
2767error:
2768 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002769 if (!submodule || !submodule->name) {
2770 free(submodule);
Michal Vasko53b7da02018-02-13 15:28:42 +01002771 LOGERR(module->ctx, ly_errno, "Submodule parsing failed.");
Pavol Vican8e7110b2016-03-22 17:00:26 +01002772 return NULL;
2773 }
2774
Michal Vasko53b7da02018-02-13 15:28:42 +01002775 LOGERR(module->ctx, ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002776
Michal Vaskoa9728122018-01-16 14:00:13 +01002777 unres_schema_free((struct lys_module *)submodule, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002778 lyp_check_circmod_pop(module->ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002779 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2780 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002781 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002782 return NULL;
2783}
Pavol Vican8760bb72016-04-07 09:44:01 +02002784
2785static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002786read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2787{
2788 int k = 0, j;
2789
2790 while (in_index < size) {
2791 if (input[in_index] == ' ') {
2792 k++;
2793 } else if (input[in_index] == '\t') {
2794 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2795 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002796 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2797 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2798 k += 8;
2799 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002800 } else {
2801 break;
2802 }
2803 ++in_index;
2804 if (k >= indent) {
2805 for (j = k - indent; j > 0; --j) {
2806 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002807 if (j > 1) {
2808 ++(*out_index);
2809 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002810 }
2811 break;
2812 }
2813 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002814 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002815}
2816
2817char *
Michal Vasko53b7da02018-02-13 15:28:42 +01002818yang_read_string(struct ly_ctx *ctx, const char *input, char *output, int size, int offset, int indent)
2819{
Pavol Vican3f598892016-09-28 15:41:07 +02002820 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002821
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002822 while (i < size) {
2823 switch (input[i]) {
2824 case '\n':
2825 out_index -= space;
2826 output[out_index] = '\n';
2827 space = 0;
2828 i = read_indent(input, indent, size, i + 1, &out_index, output);
2829 break;
2830 case ' ':
2831 case '\t':
2832 output[out_index] = input[i];
2833 ++space;
2834 break;
2835 case '\\':
2836 if (input[i + 1] == 'n') {
2837 out_index -= space;
2838 output[out_index] = '\n';
2839 space = 0;
2840 i = read_indent(input, indent, size, i + 2, &out_index, output);
2841 } else if (input[i + 1] == 't') {
2842 output[out_index] = '\t';
2843 ++i;
2844 ++space;
2845 } else if (input[i + 1] == '\\') {
2846 output[out_index] = '\\';
2847 ++i;
2848 } else if ((i + 1) != size && input[i + 1] == '"') {
2849 output[out_index] = '"';
2850 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002851 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002852 /* backslash must not be followed by any other character */
Michal Vaskoc8f80a62018-02-16 12:32:00 +01002853 LOGVAL(ctx, LYE_XML_INCHAR, LY_VLOG_NONE, NULL, input + i);
PavolVican1bc22062017-01-19 15:09:04 +01002854 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002855 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002856 break;
2857 default:
2858 output[out_index] = input[i];
2859 space = 0;
2860 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002861 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002862 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002863 ++out_index;
2864 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002865 output[out_index] = '\0';
2866 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002867 output = realloc(output, out_index + 1);
Michal Vasko53b7da02018-02-13 15:28:42 +01002868 LY_CHECK_ERR_RETURN(!output, LOGMEM(ctx), NULL);
Pavol Vican8760bb72016-04-07 09:44:01 +02002869 }
Pavol Vican3f598892016-09-28 15:41:07 +02002870 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002871}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002872
2873/* free function */
2874
PavolVicana0fdbf32017-02-15 17:59:02 +01002875void
2876yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002877{
2878 struct yang_type *stype = (struct yang_type *)type->der;
Radek Krejcidce5f972017-09-12 15:47:49 +02002879 unsigned int i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002880
2881 if (!stype) {
2882 return ;
2883 }
Michal Vasko70bf8e52018-03-26 11:32:33 +02002884 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_UNION) {
PavolVicane87cb932016-12-30 15:36:18 +01002885 lydict_remove(ctx, stype->name);
2886 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2887 for (i = 0; i < type->info.ident.count; ++i) {
2888 free(type->info.ident.ref[i]);
2889 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002890 }
PavolVicane87cb932016-12-30 15:36:18 +01002891 if (stype->base == LY_TYPE_UNION) {
2892 for (i = 0; i < type->info.uni.count; ++i) {
2893 yang_type_free(ctx, &type->info.uni.types[i]);
2894 }
2895 free(type->info.uni.types);
2896 type->base = LY_TYPE_DER;
2897 } else {
2898 type->base = stype->base;
2899 }
2900 free(stype);
2901 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002902 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02002903 lys_type_free(ctx, type, NULL);
Radek Krejci0ec2cc52017-11-09 16:30:12 +01002904 memset(type, 0, sizeof (struct lys_type));
Pavol Vican7313fc02016-11-14 01:10:31 +01002905}
2906
2907static void
Radek Krejcia2ac9262017-09-12 16:39:04 +02002908yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint16_t start, uint16_t size)
Pavol Vican7313fc02016-11-14 01:10:31 +01002909{
2910 uint8_t i;
2911
2912 assert(ctx);
2913 if (!tpdf) {
2914 return;
2915 }
2916
2917 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002918 lydict_remove(ctx, tpdf[i].name);
2919 lydict_remove(ctx, tpdf[i].dsc);
2920 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002921
Pavol Vicancee10802016-11-22 15:48:35 +01002922 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002923
Pavol Vicancee10802016-11-22 15:48:35 +01002924 lydict_remove(ctx, tpdf[i].units);
2925 lydict_remove(ctx, tpdf[i].dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002926 lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
Pavol Vican7313fc02016-11-14 01:10:31 +01002927 }
2928}
2929
Pavol Vican1cc4e192016-10-24 16:38:31 +02002930static void
2931yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2932{
2933 uint8_t i;
2934
2935 for (i = start; i < size; ++i){
2936 free((char *)imp[i].module);
2937 lydict_remove(ctx, imp[i].prefix);
2938 lydict_remove(ctx, imp[i].dsc);
2939 lydict_remove(ctx, imp[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002940 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002941 }
2942}
2943
Pavol Vicanec423c92016-10-24 21:33:43 +02002944static void
2945yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2946{
2947 uint8_t i;
2948
2949 for (i = start; i < size; ++i){
2950 free((char *)inc[i].submodule);
2951 lydict_remove(ctx, inc[i].dsc);
2952 lydict_remove(ctx, inc[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002953 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
Pavol Vicanec423c92016-10-24 21:33:43 +02002954 }
2955}
2956
Pavol Vican36e27272016-11-22 15:47:28 +01002957static void
2958yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2959{
2960 uint32_t i;
2961 uint8_t j;
2962
2963 /* free base name */
2964 for (i = start; i < size; ++i) {
2965 for (j = 0; j < ident[i].base_size; ++j) {
2966 free(ident[i].base[j]);
2967 }
2968 }
2969}
2970
Pavol Vican05810b62016-11-23 14:07:22 +01002971static void
2972yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2973{
2974 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2975 free(grp->tpdf);
2976}
2977
2978static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002979yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2980{
2981 uint8_t i;
2982
2983 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2984 free(cont->tpdf);
2985 lydict_remove(ctx, cont->presence);
2986
Pavol Vicanfda8c802016-12-03 02:00:42 +01002987 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002988 lys_restr_free(ctx, &cont->must[i], NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002989 }
2990 free(cont->must);
2991
Radek Krejci5138e9f2017-04-12 13:10:46 +02002992 lys_when_free(ctx, cont->when, NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002993}
2994
2995static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002996yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2997{
2998 uint8_t i;
2999
3000 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003001 lys_restr_free(ctx, &leaf->must[i], NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01003002 }
3003 free(leaf->must);
3004
Radek Krejci5138e9f2017-04-12 13:10:46 +02003005 lys_when_free(ctx, leaf->when, NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01003006
3007 yang_type_free(ctx, &leaf->type);
3008 lydict_remove(ctx, leaf->units);
3009 lydict_remove(ctx, leaf->dflt);
3010}
3011
3012static void
Pavol Vican36aff862016-11-26 17:07:05 +01003013yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
3014{
3015 uint8_t i;
3016
3017 for (i = 0; i < leaflist->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003018 lys_restr_free(ctx, &leaflist->must[i], NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003019 }
3020 free(leaflist->must);
3021
3022 for (i = 0; i < leaflist->dflt_size; i++) {
3023 lydict_remove(ctx, leaflist->dflt[i]);
3024 }
3025 free(leaflist->dflt);
3026
Radek Krejci5138e9f2017-04-12 13:10:46 +02003027 lys_when_free(ctx, leaflist->when, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003028
3029 yang_type_free(ctx, &leaflist->type);
3030 lydict_remove(ctx, leaflist->units);
3031}
3032
3033static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003034yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3035{
3036 uint8_t i;
3037
3038 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3039 free(list->tpdf);
3040
3041 for (i = 0; i < list->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003042 lys_restr_free(ctx, &list->must[i], NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003043 }
3044 free(list->must);
3045
Radek Krejci5138e9f2017-04-12 13:10:46 +02003046 lys_when_free(ctx, list->when, NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003047
3048 for (i = 0; i < list->unique_size; ++i) {
3049 free(list->unique[i].expr);
3050 }
3051 free(list->unique);
3052
3053 free(list->keys);
3054}
3055
3056static void
Pavol Vican36ace102016-11-28 11:46:59 +01003057yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3058{
3059 free(choice->dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003060 lys_when_free(ctx, choice->when, NULL);
Pavol Vican36ace102016-11-28 11:46:59 +01003061}
3062
3063static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003064yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3065{
3066 uint8_t i;
3067
3068 for (i = 0; i < anydata->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003069 lys_restr_free(ctx, &anydata->must[i], NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003070 }
3071 free(anydata->must);
3072
Radek Krejci5138e9f2017-04-12 13:10:46 +02003073 lys_when_free(ctx, anydata->when, NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003074}
3075
3076static void
Pavol Vican78729392016-11-28 17:18:22 +01003077yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3078{
3079 uint8_t i;
3080
3081 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3082 free(inout->tpdf);
3083
3084 for (i = 0; i < inout->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003085 lys_restr_free(ctx, &inout->must[i], NULL);
Pavol Vican78729392016-11-28 17:18:22 +01003086 }
3087 free(inout->must);
3088}
3089
3090static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003091yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3092{
3093 uint8_t i;
3094
3095 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3096 free(notif->tpdf);
3097
3098 for (i = 0; i < notif->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003099 lys_restr_free(ctx, &notif->must[i], NULL);
Pavol Vican29bf8802016-11-28 20:44:57 +01003100 }
3101 free(notif->must);
3102}
3103
3104static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003105yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3106{
3107 int i, j;
3108
3109 for (i = 0; i < uses->refine_size; i++) {
3110 lydict_remove(ctx, uses->refine[i].target_name);
3111 lydict_remove(ctx, uses->refine[i].dsc);
3112 lydict_remove(ctx, uses->refine[i].ref);
3113
3114 for (j = 0; j < uses->refine[i].must_size; j++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003115 lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003116 }
3117 free(uses->refine[i].must);
3118
3119 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3120 lydict_remove(ctx, uses->refine[i].dflt[j]);
3121 }
3122 free(uses->refine[i].dflt);
3123
3124 if (uses->refine[i].target_type & LYS_CONTAINER) {
3125 lydict_remove(ctx, uses->refine[i].mod.presence);
3126 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003127 lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003128 }
3129 free(uses->refine);
3130
Radek Krejci5138e9f2017-04-12 13:10:46 +02003131 lys_when_free(ctx, uses->when, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003132}
3133
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003134static void
Pavol Vican05810b62016-11-23 14:07:22 +01003135yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3136{
3137 struct lys_node *tmp, *child, *sibling;
3138
3139 if (!node) {
3140 return;
3141 }
3142 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003143
3144 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003145 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003146 sibling = tmp->next;
3147 /* common part */
3148 lydict_remove(ctx, tmp->name);
3149 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003150 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003151 lydict_remove(ctx, tmp->dsc);
3152 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003153 }
3154
3155 switch (tmp->nodetype) {
3156 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003157 case LYS_RPC:
3158 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003159 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3160 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003161 case LYS_CONTAINER:
3162 yang_free_container(ctx, (struct lys_node_container *)tmp);
3163 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003164 case LYS_LEAF:
3165 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3166 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003167 case LYS_LEAFLIST:
3168 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3169 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003170 case LYS_LIST:
3171 yang_free_list(ctx, (struct lys_node_list *)tmp);
3172 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003173 case LYS_CHOICE:
3174 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3175 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003176 case LYS_CASE:
Radek Krejci5138e9f2017-04-12 13:10:46 +02003177 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
Pavol Vicana420bac2016-11-28 14:51:54 +01003178 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003179 case LYS_ANYXML:
3180 case LYS_ANYDATA:
3181 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3182 break;
Pavol Vican78729392016-11-28 17:18:22 +01003183 case LYS_INPUT:
3184 case LYS_OUTPUT:
3185 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3186 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003187 case LYS_NOTIF:
3188 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3189 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003190 case LYS_USES:
3191 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3192 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003193 default:
3194 break;
3195 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003196 lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
Pavol Vican05810b62016-11-23 14:07:22 +01003197 yang_free_nodes(ctx, child);
3198 free(tmp);
3199 tmp = sibling;
3200 }
3201}
3202
Pavol Vican3ad50f82016-12-04 15:00:36 +01003203static void
3204yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3205{
3206 lydict_remove(ctx, aug->target_name);
3207 lydict_remove(ctx, aug->dsc);
3208 lydict_remove(ctx, aug->ref);
3209
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003210 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003211 lys_when_free(ctx, aug->when, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003212 yang_free_nodes(ctx, aug->child);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003213 lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003214}
3215
PavolVican75af21d2016-12-29 20:04:07 +01003216static void
3217yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3218{
3219 uint i, j;
3220
3221 for (i = index; i < dev->deviate_size; ++i) {
3222 lydict_remove(ctx, dev->deviate[i].units);
3223
3224 if (dev->deviate[i].type) {
3225 yang_type_free(ctx, dev->deviate[i].type);
Radek Krejciec376502018-08-22 15:32:33 +02003226 free(dev->deviate[i].type);
PavolVican75af21d2016-12-29 20:04:07 +01003227 }
3228
3229 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3230 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3231 }
3232 free(dev->deviate[i].dflt);
3233
3234 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003235 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003236 }
3237 free(dev->deviate[i].must);
3238
3239 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3240 free(dev->deviate[i].unique[j].expr);
3241 }
3242 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003243 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003244 }
3245}
3246
PavolVicandb0e8172017-02-20 00:46:09 +01003247void
3248yang_free_ext_data(struct yang_ext_substmt *substmt)
3249{
3250 int i;
3251
3252 if (!substmt) {
3253 return;
3254 }
3255
3256 free(substmt->ext_substmt);
3257 if (substmt->ext_modules) {
3258 for (i = 0; substmt->ext_modules[i]; ++i) {
3259 free(substmt->ext_modules[i]);
3260 }
3261 free(substmt->ext_modules);
3262 }
3263 free(substmt);
3264}
3265
Pavol Vican7313fc02016-11-14 01:10:31 +01003266/* free common item from module and submodule */
3267static void
Pavol Vican05810b62016-11-23 14:07:22 +01003268free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003269{
PavolVican75af21d2016-12-29 20:04:07 +01003270 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003271 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3272 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003273 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003274 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003275 for (i = 0; i < module->augment_size; ++i) {
3276 yang_free_augment(module->ctx, &module->augment[i]);
3277 }
3278 module->augment_size = 0;
3279 for (i = 0; i < module->deviation_size; ++i) {
3280 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3281 free(module->deviation[i].deviate);
David Sedlák437ec402018-08-13 09:07:10 +02003282 lydict_remove(module->ctx, module->deviation[i].target_name);
3283 lydict_remove(module->ctx, module->deviation[i].dsc);
3284 lydict_remove(module->ctx, module->deviation[i].ref);
PavolVican75af21d2016-12-29 20:04:07 +01003285 }
3286 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003287}
3288
Pavol Vican1cc4e192016-10-24 16:38:31 +02003289/* check function*/
3290
3291int
Michal Vaskoa310a452018-11-21 12:34:29 +01003292yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
PavolVicanc1807262017-01-31 18:00:27 +01003293 void *parent, struct unres_schema *unres)
3294{
3295 struct unres_ext *info;
Michal Vaskoa310a452018-11-21 12:34:29 +01003296 uint i;
PavolVicanc1807262017-01-31 18:00:27 +01003297
3298 for (i = 0; i < size; ++i) {
3299 info = malloc(sizeof *info);
Michal Vasko53b7da02018-02-13 15:28:42 +01003300 LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003301 info->data.yang = (*ext)[i]->parent;
3302 info->datatype = LYS_IN_YANG;
3303 info->parent = parent;
3304 info->mod = module;
3305 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003306 info->substmt = (*ext)[i]->insubstmt;
3307 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003308 info->ext_index = i;
3309 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3310 return EXIT_FAILURE;
3311 }
3312 }
3313
3314 return EXIT_SUCCESS;
3315}
3316
3317int
Pavol Vicanec423c92016-10-24 21:33:43 +02003318yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003319{
3320 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003321 struct lys_include *inc;
3322 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003323 char *s;
3324
3325 imp = module->imp;
3326 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003327 inc = module->inc;
3328 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003329
3330 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003331 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003332 module->imp_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003333 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM(module->ctx), error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003334 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003335
Pavol Vicanec423c92016-10-24 21:33:43 +02003336 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003337 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003338 module->inc_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003339 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM(module->ctx), error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003340 }
3341
3342 for (i = 0; i < imp_size; ++i) {
3343 s = (char *) imp[i].module;
3344 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003345 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003346 ++i;
3347 goto error;
3348 }
3349 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003350 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003351 s = (char *) inc[j].submodule;
3352 inc[j].submodule = NULL;
3353 if (yang_fill_include(module, s, &inc[j], unres)) {
3354 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003355 goto error;
3356 }
3357 }
3358 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003359 free(imp);
3360
3361 return EXIT_SUCCESS;
3362
3363error:
3364 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003365 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003366 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003367 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003368 return EXIT_FAILURE;
3369}
Pavol Vican7313fc02016-11-14 01:10:31 +01003370
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003371static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003372yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003373{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003374 struct lys_iffeature *iffeature;
3375 uint8_t *ptr_size, size, i;
3376 char *s;
3377 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003378
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003379 switch (type) {
3380 case FEATURE_KEYWORD:
3381 iffeature = ((struct lys_feature *)parent)->iffeature;
3382 size = ((struct lys_feature *)parent)->iffeature_size;
3383 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3384 parent_is_feature = 1;
3385 break;
3386 case IDENTITY_KEYWORD:
3387 iffeature = ((struct lys_ident *)parent)->iffeature;
3388 size = ((struct lys_ident *)parent)->iffeature_size;
3389 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3390 break;
3391 case ENUM_KEYWORD:
3392 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3393 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3394 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3395 break;
3396 case BIT_KEYWORD:
3397 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3398 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3399 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3400 break;
3401 case REFINE_KEYWORD:
3402 iffeature = ((struct lys_refine *)ptr)->iffeature;
3403 size = ((struct lys_refine *)ptr)->iffeature_size;
3404 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3405 break;
3406 default:
3407 iffeature = ((struct lys_node *)parent)->iffeature;
3408 size = ((struct lys_node *)parent)->iffeature_size;
3409 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3410 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003411 }
3412
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003413 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003414 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003415 s = (char *)iffeature[i].features;
3416 iffeature[i].features = NULL;
3417 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3418 *ptr_size = size;
3419 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003420 }
PavolVican8fa31242017-02-07 11:04:26 +01003421 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3422 *ptr_size = size;
3423 return EXIT_FAILURE;
3424 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003425 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003426 }
3427
3428 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003429}
3430
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003431static int
3432yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3433{
3434 uint size, i;
3435 int rc;
3436 struct lys_ident **ref;
3437 const char *value;
3438 char *expr;
3439
3440 ref = type->info.ident.ref;
3441 size = type->info.ident.count;
3442 type->info.ident.count = 0;
3443 type->info.ident.ref = NULL;
3444 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3445
3446 for (i = 0; i < size; ++i) {
3447 expr = (char *)ref[i];
3448 /* store in the JSON format */
3449 value = transform_schema2json(module, expr);
3450 free(expr);
3451
3452 if (!value) {
3453 goto error;
3454 }
3455 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3456 lydict_remove(module->ctx, value);
3457
3458 if (rc == -1) {
3459 goto error;
3460 }
3461 }
3462 free(ref);
3463
3464 return EXIT_SUCCESS;
3465error:
3466 for (i = i+1; i < size; ++i) {
3467 free(ref[i]);
3468 }
3469 free(ref);
3470 return EXIT_FAILURE;
3471}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003472
Pavol Vican7313fc02016-11-14 01:10:31 +01003473int
PavolVican056fcd12017-02-07 15:36:53 +01003474yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3475 void *parent, struct unres_schema *unres)
3476{
PavolVican92f23622017-12-12 13:35:56 +01003477 unsigned int i, j;
PavolVican056fcd12017-02-07 15:36:53 +01003478
3479 type->parent = parent;
3480 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3481 return EXIT_FAILURE;
3482 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003483 for (j = 0; j < type->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003484 if (type->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003485 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003486 break;
3487 }
3488 }
3489
PavolVican056fcd12017-02-07 15:36:53 +01003490 switch (stype->base) {
3491 case LY_TYPE_ENUM:
3492 for (i = 0; i < type->info.enums.count; ++i) {
3493 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3494 return EXIT_FAILURE;
3495 }
3496 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3497 &type->info.enums.enm[i], unres)) {
3498 return EXIT_FAILURE;
3499 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003500 for (j = 0; j < type->info.enums.enm[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003501 if (type->info.enums.enm[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003502 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003503 break;
3504 }
3505 }
PavolVican056fcd12017-02-07 15:36:53 +01003506 }
3507 break;
3508 case LY_TYPE_BITS:
3509 for (i = 0; i < type->info.bits.count; ++i) {
3510 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3511 return EXIT_FAILURE;
3512 }
3513 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3514 &type->info.bits.bit[i], unres)) {
3515 return EXIT_FAILURE;
3516 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003517 for (j = 0; j < type->info.bits.bit[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003518 if (type->info.bits.bit[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003519 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003520 break;
3521 }
3522 }
PavolVican056fcd12017-02-07 15:36:53 +01003523 }
3524 break;
3525 case LY_TYPE_IDENT:
3526 if (yang_check_identityref(module, type, unres)) {
3527 return EXIT_FAILURE;
3528 }
3529 break;
3530 case LY_TYPE_STRING:
PavolVican92f23622017-12-12 13:35:56 +01003531 if (type->info.str.length) {
3532 if (yang_check_ext_instance(module, &type->info.str.length->ext,
3533 type->info.str.length->ext_size, type->info.str.length, unres)) {
3534 return EXIT_FAILURE;
3535 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003536 for (j = 0; j < type->info.str.length->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003537 if (type->info.str.length->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003538 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003539 break;
3540 }
3541 }
PavolVican056fcd12017-02-07 15:36:53 +01003542 }
PavolVican92f23622017-12-12 13:35:56 +01003543
PavolVican056fcd12017-02-07 15:36:53 +01003544 for (i = 0; i < type->info.str.pat_count; ++i) {
3545 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3546 &type->info.str.patterns[i], unres)) {
3547 return EXIT_FAILURE;
3548 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003549 for (j = 0; j < type->info.str.patterns[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003550 if (type->info.str.patterns[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003551 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003552 break;
3553 }
3554 }
PavolVican056fcd12017-02-07 15:36:53 +01003555 }
3556 break;
3557 case LY_TYPE_DEC64:
PavolVican92f23622017-12-12 13:35:56 +01003558 if (type->info.dec64.range) {
3559 if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
3560 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3561 return EXIT_FAILURE;
3562 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003563 for (j = 0; j < type->info.dec64.range->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003564 if (type->info.dec64.range->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003565 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003566 break;
3567 }
3568 }
PavolVican056fcd12017-02-07 15:36:53 +01003569 }
3570 break;
3571 case LY_TYPE_UNION:
3572 for (i = 0; i < type->info.uni.count; ++i) {
3573 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3574 parent, unres)) {
3575 return EXIT_FAILURE;
3576 }
3577 }
Radek Krejci57b41682017-03-07 12:33:24 +01003578 break;
PavolVican056fcd12017-02-07 15:36:53 +01003579 default:
3580 /* nothing checks */
3581 break;
3582 }
3583 return EXIT_SUCCESS;
3584}
3585
3586int
Pavol Vican7313fc02016-11-14 01:10:31 +01003587yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3588{
3589 struct lys_tpdf *tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003590 uint8_t *ptr_tpdf_size = NULL;
3591 uint16_t j, i, tpdf_size, *ptr_tpdf_size16 = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01003592
3593 if (!parent) {
3594 tpdf = module->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003595 //ptr_tpdf_size = &module->tpdf_size;
3596 ptr_tpdf_size16 = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003597 } else {
3598 switch (parent->nodetype) {
3599 case LYS_GROUPING:
3600 tpdf = ((struct lys_node_grp *)parent)->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003601 ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003602 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003603 case LYS_CONTAINER:
3604 tpdf = ((struct lys_node_container *)parent)->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003605 ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003606 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003607 case LYS_LIST:
3608 tpdf = ((struct lys_node_list *)parent)->tpdf;
3609 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3610 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003611 case LYS_RPC:
3612 case LYS_ACTION:
3613 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003614 ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003615 break;
Pavol Vican78729392016-11-28 17:18:22 +01003616 case LYS_INPUT:
3617 case LYS_OUTPUT:
3618 tpdf = ((struct lys_node_inout *)parent)->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003619 ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
Pavol Vican78729392016-11-28 17:18:22 +01003620 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003621 case LYS_NOTIF:
3622 tpdf = ((struct lys_node_notif *)parent)->tpdf;
Michal Vaskoa310a452018-11-21 12:34:29 +01003623 ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
Pavol Vican29bf8802016-11-28 20:44:57 +01003624 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003625 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01003626 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01003627 return EXIT_FAILURE;
3628 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003629 }
3630
Michal Vaskoa310a452018-11-21 12:34:29 +01003631 if (ptr_tpdf_size16) {
3632 tpdf_size = *ptr_tpdf_size16;
3633 *ptr_tpdf_size16 = 0;
3634 } else {
3635 tpdf_size = *ptr_tpdf_size;
3636 *ptr_tpdf_size = 0;
3637 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003638
3639 for (i = 0; i < tpdf_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003640 if (lyp_check_identifier(module->ctx, tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003641 goto error;
3642 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003643
PavolVican056fcd12017-02-07 15:36:53 +01003644 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3645 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003646 }
PavolVicandf9e7972017-02-07 11:41:38 +01003647 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3648 goto error;
3649 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003650 for (j = 0; j < tpdf[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003651 if (tpdf[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003652 tpdf[i].flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003653 break;
3654 }
3655 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003656 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003657 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003658 }
3659
Michal Vaskoa310a452018-11-21 12:34:29 +01003660 if (ptr_tpdf_size16) {
3661 (*ptr_tpdf_size16)++;
3662 } else {
3663 (*ptr_tpdf_size)++;
3664 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003665 /* check default value*/
Michal Vasko15a43372017-09-25 14:12:42 +02003666 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3667 && unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPEDEF_DFLT, (struct lys_node *)(&tpdf[i].dflt)) == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +01003668 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003669 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003670 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003671 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003672
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003673 return EXIT_SUCCESS;
3674
3675error:
3676 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3677 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003678}
3679
3680static int
Pavol Vican36e27272016-11-22 15:47:28 +01003681yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3682{
3683 uint32_t i, size, base_size;
3684 uint8_t j;
3685
3686 size = module->ident_size;
3687 module->ident_size = 0;
3688 for (i = 0; i < size; ++i) {
3689 base_size = module->ident[i].base_size;
3690 module->ident[i].base_size = 0;
3691 for (j = 0; j < base_size; ++j) {
3692 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3693 ++j;
3694 module->ident_size = size;
3695 goto error;
3696 }
3697 }
3698 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003699 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3700 goto error;
3701 }
PavolVican8fa31242017-02-07 11:04:26 +01003702 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3703 goto error;
3704 }
Pavol Vican36e27272016-11-22 15:47:28 +01003705 }
3706
3707 return EXIT_SUCCESS;
3708
3709error:
3710 for (; j< module->ident[i].base_size; ++j) {
3711 free(module->ident[i].base[j]);
3712 }
3713 yang_free_ident_base(module->ident, i + 1, size);
3714 return EXIT_FAILURE;
3715}
3716
3717static int
PavolVican38104a32017-02-08 12:25:23 +01003718yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3719{
3720 uint i;
3721
3722 for (i = 0; i < size; ++i) {
3723 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3724 return EXIT_FAILURE;
3725 }
3726 }
3727 return EXIT_SUCCESS;
3728}
3729
3730static int
PavolVicane87cb932016-12-30 15:36:18 +01003731yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003732 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003733{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003734 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003735 goto error;
3736 }
3737
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003738 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003739 goto error;
3740 }
3741
Radek Krejci7212e0a2017-03-08 15:58:22 +01003742 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003743 *child = NULL;
3744 goto error;
3745 }
3746 *child = NULL;
3747
PavolVican59ba4602017-02-08 11:53:32 +01003748 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3749 goto error;
3750 }
PavolVican38104a32017-02-08 12:25:23 +01003751 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3752 goto error;
3753 }
3754
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003755 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003756 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003757 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003758 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003759 goto error;
3760 }
3761 } else {
3762 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3763 goto error;
3764 }
3765 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003766 }
3767
3768 return EXIT_SUCCESS;
3769error:
Michal Vasko53b7da02018-02-13 15:28:42 +01003770
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003771 return EXIT_FAILURE;
3772}
3773
3774static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003775yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003776{
PavolVican056fcd12017-02-07 15:36:53 +01003777 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003778 yang_type_free(module->ctx, &leaf->type);
3779 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003780 }
PavolVicana08d3652016-12-29 21:07:47 +01003781 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3782 yang_type_free(module->ctx, &leaf->type);
3783 goto error;
3784 }
3785
Pavol Vicanfda8c802016-12-03 02:00:42 +01003786 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003787 yang_type_free(module->ctx, &leaf->type);
3788 goto error;
3789 }
3790
Michal Vasko6a057782018-03-09 13:24:33 +01003791 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003792 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003793 goto error;
3794 }
3795
PavolVican59ba4602017-02-08 11:53:32 +01003796 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3797 goto error;
3798 }
PavolVican38104a32017-02-08 12:25:23 +01003799 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3800 goto error;
3801 }
Michal Vasko89afc112017-03-16 13:57:28 +01003802
Pavol Vicana69aff22016-11-24 18:23:50 +01003803 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003804 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003805 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003806 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003807 goto error;
3808 }
3809 } else {
3810 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3811 goto error;
3812 }
3813 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003814 }
3815
3816 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003817
Pavol Vicana69aff22016-11-24 18:23:50 +01003818error:
3819 return EXIT_FAILURE;
3820}
3821
3822static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003823yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3824 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003825{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003826 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003827
PavolVican056fcd12017-02-07 15:36:53 +01003828 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003829 yang_type_free(module->ctx, &leaflist->type);
3830 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003831 }
PavolVicana08d3652016-12-29 21:07:47 +01003832 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3833 yang_type_free(module->ctx, &leaflist->type);
3834 goto error;
3835 }
3836
Pavol Vicanfda8c802016-12-03 02:00:42 +01003837 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003838 yang_type_free(module->ctx, &leaflist->type);
3839 goto error;
3840 }
3841
Pavol Vican36aff862016-11-26 17:07:05 +01003842 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003843 /* check for duplicity in case of configuration data,
3844 * in case of status data duplicities are allowed */
3845 if (leaflist->flags & LYS_CONFIG_W) {
3846 for (j = i +1; j < leaflist->dflt_size; ++j) {
3847 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003848 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3849 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003850 goto error;
3851 }
3852 }
3853 }
3854 /* check default value (if not defined, there still could be some restrictions
3855 * that need to be checked against a default value from a derived type) */
Michal Vasko6a057782018-03-09 13:24:33 +01003856 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003857 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3858 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003859 goto error;
3860 }
3861 }
3862
PavolVican59ba4602017-02-08 11:53:32 +01003863 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3864 goto error;
3865 }
PavolVican38104a32017-02-08 12:25:23 +01003866 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3867 goto error;
3868 }
PavolVican59ba4602017-02-08 11:53:32 +01003869
Pavol Vican36aff862016-11-26 17:07:05 +01003870 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003871 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003872 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003873 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003874 goto error;
3875 }
3876 } else {
3877 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3878 goto error;
3879 }
3880 }
Pavol Vican36aff862016-11-26 17:07:05 +01003881 }
3882
3883 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003884
Pavol Vican36aff862016-11-26 17:07:05 +01003885error:
3886 return EXIT_FAILURE;
3887}
3888
3889static int
PavolVicane87cb932016-12-30 15:36:18 +01003890yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003891 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003892{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003893 struct lys_node *node;
3894
Pavol Vicand8136a42016-11-27 13:28:04 +01003895 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3896 goto error;
3897 }
3898
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003899 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3900 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003901 }
3902
Pavol Vicanfda8c802016-12-03 02:00:42 +01003903 if (list->flags & LYS_CONFIG_R) {
3904 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3905 * ignore oredering MASK - 0x7F
3906 */
3907 list->flags &= 0x7F;
3908 }
3909 /* check - if list is configuration, key statement is mandatory
3910 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003911 for (node = (struct lys_node *)list; node && !(node->nodetype & (LYS_GROUPING | LYS_AUGMENT | LYS_EXT)); node = node->parent);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003912 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003913 LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
Pavol Vicanfda8c802016-12-03 02:00:42 +01003914 goto error;
3915 }
3916
Radek Krejci7212e0a2017-03-08 15:58:22 +01003917 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003918 *child = NULL;
3919 goto error;
3920 }
3921 *child = NULL;
3922
Pavol Vicand8136a42016-11-27 13:28:04 +01003923 if (list->keys && yang_read_key(module, list, unres)) {
3924 goto error;
3925 }
3926
3927 if (yang_read_unique(module, list, unres)) {
3928 goto error;
3929 }
3930
PavolVican59ba4602017-02-08 11:53:32 +01003931 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3932 goto error;
3933 }
PavolVican38104a32017-02-08 12:25:23 +01003934 if (yang_check_must(module, list->must, list->must_size, unres)) {
3935 goto error;
3936 }
Michal Vasko89afc112017-03-16 13:57:28 +01003937
Pavol Vicand8136a42016-11-27 13:28:04 +01003938 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003939 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003940 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003941 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003942 goto error;
3943 }
3944 } else {
3945 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3946 goto error;
3947 }
3948 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003949 }
3950
3951 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003952
Pavol Vicand8136a42016-11-27 13:28:04 +01003953error:
3954 return EXIT_FAILURE;
3955}
3956
3957static int
PavolVicane87cb932016-12-30 15:36:18 +01003958yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003959 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003960{
3961 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003962
PavolVicana08d3652016-12-29 21:07:47 +01003963 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3964 free(choice->dflt);
3965 choice->dflt = NULL;
3966 goto error;
3967 }
3968
Radek Krejci7212e0a2017-03-08 15:58:22 +01003969 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003970 *child = NULL;
3971 free(choice->dflt);
3972 choice->dflt = NULL;
3973 goto error;
3974 }
3975 *child = NULL;
3976
Pavol Vican36ace102016-11-28 11:46:59 +01003977 if (choice->dflt) {
3978 value = (char *)choice->dflt;
3979 choice->dflt = NULL;
3980 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3981 free(value);
3982 goto error;
3983 }
3984 free(value);
3985 }
3986
PavolVican59ba4602017-02-08 11:53:32 +01003987 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3988 goto error;
3989 }
3990
Pavol Vican36ace102016-11-28 11:46:59 +01003991 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003992 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01003993 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003994 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003995 goto error;
3996 }
3997 } else {
3998 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3999 goto error;
4000 }
4001 }
Pavol Vican36ace102016-11-28 11:46:59 +01004002 }
4003
4004 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004005
Pavol Vican36ace102016-11-28 11:46:59 +01004006error:
4007 return EXIT_FAILURE;
4008}
4009
4010static int
PavolVicane87cb932016-12-30 15:36:18 +01004011yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004012 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004013{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004014 struct lys_node *node;
4015
4016 if (rpc->nodetype == LYS_ACTION) {
4017 for (node = rpc->parent; node; node = lys_parent(node)) {
4018 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01004019 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004020 LOGVAL(module->ctx, LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004021 goto error;
4022 }
4023 }
4024 }
4025 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
4026 goto error;
4027 }
4028
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004029 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
4030 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004031 }
4032
Radek Krejci7212e0a2017-03-08 15:58:22 +01004033 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004034 *child = NULL;
4035 goto error;
4036 }
4037 *child = NULL;
4038
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004039 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004040
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004041error:
4042 return EXIT_FAILURE;
4043}
4044
4045static int
PavolVicane87cb932016-12-30 15:36:18 +01004046yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004047 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01004048{
Pavol Vican29bf8802016-11-28 20:44:57 +01004049 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
4050 goto error;
4051 }
4052
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004053 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
4054 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01004055 }
4056
Radek Krejci7212e0a2017-03-08 15:58:22 +01004057 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004058 *child = NULL;
4059 goto error;
4060 }
4061 *child = NULL;
4062
Michal Vasko89afc112017-03-16 13:57:28 +01004063 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
4064 goto error;
4065 }
4066
4067 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004068 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01004069 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004070 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004071 goto error;
4072 }
4073 } else {
4074 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
4075 goto error;
4076 }
PavolVican38104a32017-02-08 12:25:23 +01004077 }
Pavol Vican29bf8802016-11-28 20:44:57 +01004078 }
4079
4080 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004081
Pavol Vican29bf8802016-11-28 20:44:57 +01004082error:
4083 return EXIT_FAILURE;
4084}
4085
4086static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004087yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004088{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004089 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004090
Pavol Vican3ad50f82016-12-04 15:00:36 +01004091 child = augment->child;
4092 augment->child = NULL;
4093
PavolVicana08d3652016-12-29 21:07:47 +01004094 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4095 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004096 goto error;
4097 }
4098
Radek Krejci7212e0a2017-03-08 15:58:22 +01004099 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004100 goto error;
4101 }
4102
PavolVicanfa9510e2017-02-08 17:20:46 +01004103 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4104 goto error;
4105 }
4106
PavolVican59ba4602017-02-08 11:53:32 +01004107 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4108 goto error;
4109 }
4110
Pavol Vican3ad50f82016-12-04 15:00:36 +01004111 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004112 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004113 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004114 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004115 goto error;
4116 }
4117 } else {
4118 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4119 goto error;
4120 }
4121 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004122 }
4123
4124 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004125
Pavol Vican3ad50f82016-12-04 15:00:36 +01004126error:
4127 return EXIT_FAILURE;
4128}
4129
4130static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004131yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004132{
4133 uint i, size;
4134
4135 size = uses->augment_size;
4136 uses->augment_size = 0;
4137
4138 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004139 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004140 }
4141
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004142 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004143 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4144 goto error;
4145 }
4146 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4147 goto error;
4148 }
4149 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 +01004150 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004151 }
4152 }
4153
Pavol Vican3ad50f82016-12-04 15:00:36 +01004154 for (i = 0; i < size; ++i) {
4155 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004156 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004157 goto error;
4158 }
4159 }
4160
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004161 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4162 goto error;
4163 }
4164
PavolVican59ba4602017-02-08 11:53:32 +01004165 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4166 goto error;
4167 }
4168
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004169 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004170 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004171 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004172 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004173 goto error;
4174 }
4175 } else {
4176 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4177 goto error;
4178 }
4179 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004180 }
4181
4182 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004183
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004184error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004185 for (i = uses->augment_size; i < size; ++i) {
4186 yang_free_augment(module->ctx, &uses->augment[i]);
4187 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004188 return EXIT_FAILURE;
4189}
4190
4191static int
PavolVican59ba4602017-02-08 11:53:32 +01004192yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004193 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004194{
4195 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4196 goto error;
4197 }
4198
Radek Krejci7212e0a2017-03-08 15:58:22 +01004199 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004200 *child = NULL;
4201 goto error;
4202 }
4203 *child = NULL;
4204
4205 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4206 goto error;
4207 }
PavolVican38104a32017-02-08 12:25:23 +01004208 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4209 goto error;
4210 }
PavolVican59ba4602017-02-08 11:53:32 +01004211
4212 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004213 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004214 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004215 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004216 goto error;
4217 }
4218 } else {
4219 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4220 goto error;
4221 }
4222 }
PavolVican59ba4602017-02-08 11:53:32 +01004223 }
Michal Vasko89afc112017-03-16 13:57:28 +01004224
PavolVican59ba4602017-02-08 11:53:32 +01004225 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004226
PavolVican59ba4602017-02-08 11:53:32 +01004227error:
4228 return EXIT_FAILURE;
4229}
4230
4231static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004232yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004233 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004234{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004235 struct lys_node *node = nodes, *sibling, *child;
PavolVican92f23622017-12-12 13:35:56 +01004236 int i;
Pavol Vican05810b62016-11-23 14:07:22 +01004237
4238 while (node) {
4239 sibling = node->next;
4240 child = node->child;
4241 node->next = NULL;
4242 node->child = NULL;
PavolVicanbd1d1ae2017-07-20 00:06:00 +02004243 node->parent = NULL;
Pavol Vican05810b62016-11-23 14:07:22 +01004244 node->prev = node;
4245
Michal Vasko8d30dd82018-09-10 10:06:12 +02004246 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node, 0) ||
PavolVican05c4f9b2017-09-07 13:33:54 +02004247 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004248 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004249 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004250 goto error;
4251 }
Michal Vasko8d30dd82018-09-10 10:06:12 +02004252 if (node->parent != parent) {
4253 assert(node->parent->parent == parent);
4254 assert((node->parent->nodetype == LYS_CASE) && (node->parent->flags & LYS_IMPLICIT));
4255 store_config_flag(node->parent, options);
4256 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004257 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004258 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4259 goto error;
4260 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01004261 for (i = 0; i < node->ext_size; ++i) {
PavolVican92f23622017-12-12 13:35:56 +01004262 if (node->ext[i]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01004263 node->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01004264 break;
4265 }
4266 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004267
Pavol Vican05810b62016-11-23 14:07:22 +01004268 switch (node->nodetype) {
4269 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004270 if (yang_check_typedef(module, node, unres)) {
4271 goto error;
4272 }
4273 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004274 goto error;
4275 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004276 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004277 child = NULL;
4278 goto error;
4279 }
Pavol Vican05810b62016-11-23 14:07:22 +01004280 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004281 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004282 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004283 goto error;
4284 }
4285 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004286 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004287 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004288 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004289 goto error;
4290 }
4291 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004292 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004293 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004294 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004295 goto error;
4296 }
4297 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004298 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004299 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004300 goto error;
4301 }
4302 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004303 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004304 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004305 goto error;
4306 }
4307 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004308 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004309 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004310 goto error;
4311 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004312 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004313 child = NULL;
4314 goto error;
4315 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004316 if (((struct lys_node_case *)node)->when) {
4317 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4318 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4319 goto error;
4320 }
4321 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004322 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004323 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004324 goto error;
4325 }
4326 } else {
4327 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4328 goto error;
4329 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004330 }
4331 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004332 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004333 case LYS_ANYDATA:
4334 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004335 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004336 goto error;
4337 }
4338 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004339 case LYS_RPC:
4340 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004341 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004342 goto error;
4343 }
4344 break;
Pavol Vican78729392016-11-28 17:18:22 +01004345 case LYS_INPUT:
4346 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004347 if (yang_check_typedef(module, node, unres)) {
4348 goto error;
4349 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004350 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004351 child = NULL;
4352 goto error;
4353 }
PavolVican38104a32017-02-08 12:25:23 +01004354 if (((struct lys_node_inout *)node)->must_size) {
4355 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4356 goto error;
4357 }
4358 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004359 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004360 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004361 goto error;
4362 }
4363 } else {
4364 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4365 goto error;
4366 }
PavolVican38104a32017-02-08 12:25:23 +01004367 }
Pavol Vican78729392016-11-28 17:18:22 +01004368 }
Pavol Vican78729392016-11-28 17:18:22 +01004369 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004370 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004371 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004372 goto error;
4373 }
4374 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004375 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004376 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004377 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004378 goto error;
4379 }
4380 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004381 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01004382 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01004383 goto error;
4384 }
Pavol Vican05810b62016-11-23 14:07:22 +01004385 node = sibling;
4386 }
4387
4388 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004389
Pavol Vican05810b62016-11-23 14:07:22 +01004390error:
4391 yang_free_nodes(module->ctx, sibling);
4392 yang_free_nodes(module->ctx, child);
4393 return EXIT_FAILURE;
4394}
4395
4396static int
PavolVican75af21d2016-12-29 20:04:07 +01004397yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4398 struct lys_node *dev_target, struct ly_set *dflt_check)
4399{
4400 struct lys_node_leaflist *llist;
4401 struct lys_type *type;
4402 struct lys_tpdf *tmp_parent;
4403 int i, j;
4404
PavolVican6f000922017-02-10 12:56:59 +01004405 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4406 goto error;
4407 }
PavolVican75af21d2016-12-29 20:04:07 +01004408 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4409 goto error;
4410 }
4411 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4412 goto error;
4413 }
4414 if (deviate->dflt_size) {
4415 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4416 goto error;
4417 }
4418 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4419 /* consolidate the final list in the target after removing items from it */
4420 llist = (struct lys_node_leaflist *)dev_target;
4421 for (i = j = 0; j < llist->dflt_size; j++) {
4422 llist->dflt[i] = llist->dflt[j];
4423 if (llist->dflt[i]) {
4424 i++;
4425 }
4426 }
4427 llist->dflt_size = i + 1;
4428 }
4429 }
4430
4431 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4432 goto error;
4433 }
4434
4435 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4436 goto error;
4437 }
4438
4439 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4440 goto error;
4441 }
4442
4443 if ((deviate->flags & LYS_CONFIG_MASK)) {
4444 /* add and replace are the same in this case */
4445 /* remove current config value of the target ... */
4446 dev_target->flags &= ~LYS_CONFIG_MASK;
4447
4448 /* ... and replace it with the value specified in deviation */
4449 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4450 }
4451
4452 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4453 goto error;
4454 }
4455
4456 if (deviate->type) {
4457 /* check target node type */
4458 if (dev_target->nodetype == LYS_LEAF) {
4459 type = &((struct lys_node_leaf *)dev_target)->type;
4460 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4461 type = &((struct lys_node_leaflist *)dev_target)->type;
4462 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01004463 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4464 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01004465 goto error;
4466 }
4467 /* remove type and initialize it */
4468 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004469 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004470 memcpy(type, deviate->type, sizeof *deviate->type);
4471 free(deviate->type);
4472 deviate->type = type;
4473 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004474 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4475 goto error;
4476 }
4477
PavolVican75af21d2016-12-29 20:04:07 +01004478 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4479 goto error;
4480 }
4481 }
4482
4483 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004484
PavolVican75af21d2016-12-29 20:04:07 +01004485error:
4486 if (deviate->type) {
4487 yang_type_free(module->ctx, deviate->type);
4488 deviate->type = NULL;
4489 }
4490 return EXIT_FAILURE;
4491}
4492
4493static int
4494yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4495{
4496 int rc;
4497 uint i;
4498 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004499 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004500 unsigned int u;
4501 const char *value, *target_name;
4502 struct lys_node_leaflist *llist;
4503 struct lys_node_leaf *leaf;
Michal Vasko5df038e2018-08-02 09:41:26 +02004504 struct lys_node_inout *inout;
PavolVican75af21d2016-12-29 20:04:07 +01004505 struct unres_schema tmp_unres;
4506 struct lys_module *mod;
4507
4508 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004509 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4510 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004511 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004512 ly_set_free(set);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004513 i = 0;
4514 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004515 }
Michal Vasko50576712017-07-28 12:28:33 +02004516 dev_target = set->set.s[0];
4517 ly_set_free(set);
4518
PavolVican75af21d2016-12-29 20:04:07 +01004519 if (dev_target->module == lys_main_module(module)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004520 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4521 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004522 i = 0;
4523 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004524 }
4525
4526 if (!dflt_check) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004527 LOGMEM(module->ctx);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004528 i = 0;
4529 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004530 }
4531
4532 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4533 /* you cannot remove a key leaf */
4534 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4535 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4536 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004537 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4538 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004539 i = 0;
4540 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004541 }
4542 }
4543 }
4544 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004545 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004546 lys_node_unlink(dev_target);
Michal Vasko5df038e2018-08-02 09:41:26 +02004547 if (parent) {
4548 if (parent->nodetype & (LYS_AUGMENT | LYS_USES)) {
4549 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4550 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4551 * path), so we need to remember the augment as an addition */
4552 /* remember uses parent so we can reconnect to it */
4553 dev_target->parent = parent;
4554 } else if (parent->nodetype & (LYS_RPC | LYS_ACTION)) {
4555 /* re-create implicit node */
4556 inout = calloc(1, sizeof *inout);
4557 LY_CHECK_ERR_GOTO(!inout, LOGMEM(module->ctx), error);
4558
4559 inout->nodetype = dev_target->nodetype;
4560 inout->name = lydict_insert(module->ctx, (inout->nodetype == LYS_INPUT) ? "input" : "output", 0);
4561 inout->module = dev_target->module;
4562 inout->flags = LYS_IMPLICIT;
4563
4564 /* insert it manually */
4565 assert(parent->child && !parent->child->next
4566 && (parent->child->nodetype == (inout->nodetype == LYS_INPUT ? LYS_OUTPUT : LYS_INPUT)));
4567 parent->child->next = (struct lys_node *)inout;
4568 inout->prev = parent->child;
4569 parent->child->prev = (struct lys_node *)inout;
4570 inout->parent = parent;
4571 }
Radek Krejci9cf034c2017-08-24 17:10:35 +02004572 }
PavolVican75af21d2016-12-29 20:04:07 +01004573 dev->orig_node = dev_target;
4574 } else {
4575 /* store a shallow copy of the original node */
4576 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004577 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004578 /* just to be safe */
4579 if (tmp_unres.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004580 LOGINT(module->ctx);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004581 i = 0;
4582 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004583 }
4584 }
4585
PavolVican6f000922017-02-10 12:56:59 +01004586 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004587 i = 0;
4588 goto free_type_error;
PavolVican6f000922017-02-10 12:56:59 +01004589 }
4590
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004591 for (i = 0; i < dev->deviate_size; ++i) {
4592 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4593 yang_free_deviate(module->ctx, dev, i + 1);
4594 dev->deviate_size = i + 1;
4595 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004596 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004597 }
4598 /* now check whether default value, if any, matches the type */
4599 for (u = 0; u < dflt_check->number; ++u) {
4600 value = NULL;
4601 rc = EXIT_SUCCESS;
4602 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4603 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4604 target_name = leaf->name;
4605 value = leaf->dflt;
4606 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4607 } else { /* LYS_LEAFLIST */
4608 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4609 target_name = llist->name;
4610 for (i = 0; i < llist->dflt_size; i++) {
4611 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4612 (struct lys_node *)(&llist->dflt[i]));
4613 if (rc == -1) {
4614 value = llist->dflt[i];
4615 break;
Michal Vasko15a43372017-09-25 14:12:42 +02004616 }
4617 }
PavolVican75af21d2016-12-29 20:04:07 +01004618 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004619 if (rc == -1) {
4620 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4621 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
4622 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4623 target_name);
4624 goto error;
4625 }
PavolVican75af21d2016-12-29 20:04:07 +01004626 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004627 ly_set_free(dflt_check);
4628 dflt_check = NULL;
PavolVican75af21d2016-12-29 20:04:07 +01004629
Radek Krejci29eac3d2017-06-01 16:50:02 +02004630 /* mark all the affected modules as deviated and implemented */
4631 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004632 mod = lys_node_module(parent);
4633 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004634 mod->deviated = 1; /* main module */
4635 parent->module->deviated = 1; /* possible submodule */
Michal Vasko0f437062018-06-08 15:52:39 +02004636 if (!mod->implemented) {
4637 mod->implemented = 1;
4638 if (unres_schema_add_node(mod, unres, NULL, UNRES_MOD_IMPLEMENT, NULL) == -1) {
4639 goto error;
4640 }
Radek Krejci29eac3d2017-06-01 16:50:02 +02004641 }
4642 }
PavolVican75af21d2016-12-29 20:04:07 +01004643 }
PavolVican75af21d2016-12-29 20:04:07 +01004644
4645 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004646
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004647free_type_error:
4648 /* we need to free types because they are for now allocated dynamically (use i as it is now, is set correctly) */
4649 for (; i < dev->deviate_size; ++i) {
4650 if (dev->deviate[i].type) {
4651 yang_type_free(module->ctx, dev->deviate[i].type);
4652 free(dev->deviate[i].type);
4653 dev->deviate[i].type = NULL;
4654 }
4655 }
PavolVican75af21d2016-12-29 20:04:07 +01004656error:
4657 ly_set_free(dflt_check);
4658 return EXIT_FAILURE;
4659}
4660
4661static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004662yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4663{
PavolVican75af21d2016-12-29 20:04:07 +01004664 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004665
4666 aug_size = module->augment_size;
4667 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004668 dev_size = module->deviation_size;
4669 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004670
PavolVican6f87bf92017-02-15 19:38:55 +01004671 if (yang_check_typedef(module, NULL, unres)) {
4672 goto error;
4673 }
4674
PavolVicanc1807262017-01-31 18:00:27 +01004675 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4676 goto error;
4677 }
4678
PavolVican171717d2017-02-01 14:49:55 +01004679 /* check extension in revision */
4680 for (i = 0; i < module->rev_size; ++i) {
4681 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4682 goto error;
4683 }
4684 }
4685
PavolVican19dc6152017-02-06 12:04:15 +01004686 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004687 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004688 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4689 goto error;
4690 }
4691 }
4692
Pavol Vican7a7916f2016-11-21 23:38:30 +01004693 /* check features */
4694 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004695 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4696 goto error;
4697 }
PavolVican5393d3f2017-02-06 23:30:55 +01004698 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4699 goto error;
4700 }
4701
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004702 /* check for circular dependencies */
4703 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4704 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004705 }
4706 }
Pavol Vican36e27272016-11-22 15:47:28 +01004707 erase_identities = 0;
4708 if (yang_check_identities(module, unres)) {
4709 goto error;
4710 }
Pavol Vican05810b62016-11-23 14:07:22 +01004711 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004712 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004713 goto error;
4714 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004715
PavolVican75af21d2016-12-29 20:04:07 +01004716 /* check deviation */
4717 for (i = 0; i < dev_size; ++i) {
4718 module->deviation_size++;
4719 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4720 goto error;
4721 }
4722 }
4723
Pavol Vican3ad50f82016-12-04 15:00:36 +01004724 /* check augments */
4725 for (i = 0; i < aug_size; ++i) {
4726 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004727 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004728 goto error;
4729 }
4730 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4731 goto error;
4732 }
4733 }
4734
Pavol Vican7313fc02016-11-14 01:10:31 +01004735 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004736
Pavol Vican7313fc02016-11-14 01:10:31 +01004737error:
Pavol Vican36e27272016-11-22 15:47:28 +01004738 if (erase_identities) {
4739 yang_free_ident_base(module->ident, 0, module->ident_size);
4740 }
Pavol Vican05810b62016-11-23 14:07:22 +01004741 if (erase_nodes) {
4742 yang_free_nodes(module->ctx, node);
4743 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004744 for (i = module->augment_size; i < aug_size; ++i) {
4745 yang_free_augment(module->ctx, &module->augment[i]);
4746 }
PavolVican75af21d2016-12-29 20:04:07 +01004747 for (i = module->deviation_size; i < dev_size; ++i) {
4748 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4749 free(module->deviation[i].deviate);
Radek Krejciec376502018-08-22 15:32:33 +02004750 lydict_remove(module->ctx, module->deviation[i].target_name);
4751 lydict_remove(module->ctx, module->deviation[i].dsc);
4752 lydict_remove(module->ctx, module->deviation[i].ref);
PavolVican75af21d2016-12-29 20:04:07 +01004753 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004754 return EXIT_FAILURE;
4755}
PavolVican22e88682017-02-14 22:38:18 +01004756
4757int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004758yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004759 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4760{
4761 int c;
4762 const char **str, ***p = NULL;
4763 void *reallocated;
4764 struct lyext_substmt *info;
4765
4766 c = 0;
4767 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004768 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004769 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4770 if (info->cardinality < LY_STMT_CARD_SOME) {
4771 str++;
4772 } else {
4773 /* get the index in the array to add new item */
4774 p = (const char ***)str;
4775 for (c = 0; p[0][c + 1]; c++);
4776 str = p[1];
4777 }
4778 str[c] = lydict_insert_zc(module->ctx, value);
4779 } else {
4780 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4781 if (!str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004782 LOGVAL(module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004783 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004784 }
4785 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004786 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004787 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004788 }
4789
4790 if (info->cardinality >= LY_STMT_CARD_SOME) {
4791 /* there can be multiple instances, str is actually const char *** */
4792 p = (const char ***)str;
4793 if (!p[0]) {
4794 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004795 p[0] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004796 LY_CHECK_ERR_GOTO(!p[0], LOGMEM(module->ctx), error);
PavolVican22e88682017-02-14 22:38:18 +01004797 if (stmt == LY_STMT_BELONGSTO) {
4798 /* allocate another array for the belongs-to's prefixes */
4799 p[1] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004800 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004801 } else if (stmt == LY_STMT_ARGUMENT) {
4802 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004803 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Michal Vasko53b7da02018-02-13 15:28:42 +01004804 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004805 /* default value of yin element */
4806 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004807 }
4808 } else {
4809 /* get the index in the array to add new item */
4810 for (c = 0; p[0][c]; c++);
4811 }
4812 str = p[0];
4813 }
4814
4815 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004816 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004817
PavolVican50809742017-02-18 21:22:54 +01004818 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004819 /* enlarge the array(s) */
4820 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4821 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004822 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004823 lydict_remove(module->ctx, p[0][c]);
4824 p[0][c] = NULL;
4825 return EXIT_FAILURE;
4826 }
4827 p[0] = reallocated;
4828 p[0][c + 1] = NULL;
4829
4830 if (stmt == LY_STMT_BELONGSTO) {
4831 /* enlarge the second belongs-to's array with prefixes */
4832 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4833 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004834 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004835 lydict_remove(module->ctx, p[1][c]);
4836 p[1][c] = NULL;
4837 return EXIT_FAILURE;
4838 }
4839 p[1] = reallocated;
4840 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004841 } else if (stmt == LY_STMT_ARGUMENT) {
4842 /* enlarge the second argument's array with yin element */
4843 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4844 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004845 LOGMEM(module->ctx);
PavolVican50809742017-02-18 21:22:54 +01004846 ((uint8_t *)p[1])[c] = 0;
4847 return EXIT_FAILURE;
4848 }
4849 p[1] = reallocated;
4850 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004851 }
4852 }
4853 }
4854
4855 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004856
4857error:
4858 free(value);
4859 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004860}
PavolVican5334c892017-02-15 16:29:09 +01004861
4862static int
4863yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4864{
4865 int c = 0, decrement = 0;
4866 const char **str, ***p = NULL;
4867 struct lyext_substmt *info;
4868
4869
4870 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4871 stmt = LY_STMT_BELONGSTO;
4872 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004873 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4874 stmt = LY_STMT_ARGUMENT;
4875 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004876 }
4877
4878 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4879 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4880 return 0;
4881 } else {
4882 p = (const char ***)str;
4883 /* get the index in the array */
4884 for (c = 0; p[0][c]; c++);
4885 return c + decrement;
4886 }
4887}
PavolVicana0fdbf32017-02-15 17:59:02 +01004888
4889void **
PavolVicanfe83b152017-02-19 03:19:29 +01004890yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4891 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004892{
Michal Vasko53b7da02018-02-13 15:28:42 +01004893 struct ly_ctx *ctx = ext->module->ctx;
PavolVicana0fdbf32017-02-15 17:59:02 +01004894 int c;
4895 void **data, ***p = NULL;
4896 void *reallocated;
4897 struct lyext_substmt *info;
4898
4899 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4900 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004901 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004902 return NULL;
4903 }
4904 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004905 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004906 return NULL;
4907 }
4908
4909 c = 0;
4910 if (info->cardinality >= LY_STMT_CARD_SOME) {
4911 /* there can be multiple instances, so instead of pointer to array,
4912 * we have in data pointer to pointer to array */
4913 p = (void ***)data;
4914 data = *p;
4915 if (!data) {
4916 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004917 *p = data = calloc(2, sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004918 LY_CHECK_ERR_RETURN(!data, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004919 } else {
4920 for (c = 0; *data; data++, c++);
4921 }
4922 }
4923
PavolVicaneef1d912017-02-19 00:19:15 +01004924 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004925 /* enlarge the array */
4926 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004927 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004928 *p = reallocated;
4929 data = *p;
4930 data[c + 1] = NULL;
4931 }
4932
PavolVicanfe83b152017-02-19 03:19:29 +01004933 if (index) {
4934 *index = c;
4935 return data;
4936 } else {
4937 return &data[c];
4938 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004939}
PavolVicanff0f7f42017-02-16 11:35:42 +01004940
4941int
4942yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4943 LY_STMT stmt, uint16_t value, uint16_t mask)
4944{
4945 uint16_t *data;
4946 struct lyext_substmt *info;
4947
4948 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4949 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004950 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004951 return EXIT_FAILURE;
4952 }
4953 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004954 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004955 return EXIT_FAILURE;
4956 }
4957
4958 *data |= value;
4959 return EXIT_SUCCESS;
4960}
PavolVican8e8dfd12017-02-16 13:51:41 +01004961
4962int
PavolVican6a852a62017-02-16 15:36:01 +01004963yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4964 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004965{
Michal Vasko53b7da02018-02-13 15:28:42 +01004966 struct ly_ctx *ctx = ext->module->ctx;
PavolVican6a852a62017-02-16 15:36:01 +01004967 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004968 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004969 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004970
4971 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4972 if (!val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004973 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican8e8dfd12017-02-16 13:51:41 +01004974 return EXIT_FAILURE;
4975 }
PavolVican6a852a62017-02-16 15:36:01 +01004976 if (stmt == LY_STMT_DIGITS) {
4977 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004978 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01004979 return EXIT_FAILURE;
4980 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004981
PavolVican6a852a62017-02-16 15:36:01 +01004982 if (info->cardinality >= LY_STMT_CARD_SOME) {
4983 /* there can be multiple instances */
4984 pp = (uint8_t**)val;
4985 if (!(*pp)) {
4986 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Michal Vasko53b7da02018-02-13 15:28:42 +01004987 LY_CHECK_ERR_RETURN(!*pp, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004988 } else {
4989 for (i = 0; (*pp)[i]; i++);
4990 }
4991 val = &(*pp)[i];
4992 }
4993
4994 /* stored value */
4995 *val = value;
4996
4997 if (i) {
4998 /* enlarge the array */
4999 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Michal Vasko53b7da02018-02-13 15:28:42 +01005000 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01005001 *pp = reallocated;
5002 (*pp)[i + 1] = 0;
5003 }
PavolVican8e8dfd12017-02-16 13:51:41 +01005004 } else {
PavolVican6a852a62017-02-16 15:36:01 +01005005 if (*val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005006 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01005007 return EXIT_FAILURE;
5008 }
5009
5010 if (stmt == LY_STMT_REQINSTANCE) {
5011 *val = (value == 1) ? 1 : 2;
5012 } else if (stmt == LY_STMT_MODIFIER) {
5013 *val = 1;
5014 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01005015 LOGINT(ctx);
PavolVican6a852a62017-02-16 15:36:01 +01005016 return EXIT_FAILURE;
5017 }
PavolVican8e8dfd12017-02-16 13:51:41 +01005018 }
5019
5020 return EXIT_SUCCESS;
5021}
PavolVican3f47b292017-02-16 20:38:16 +01005022
PavolVicanf3091bf2017-02-19 18:27:01 +01005023int
5024yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
5025 struct lys_node *node, LY_STMT stmt)
5026{
5027 struct lyext_substmt *info;
5028 struct lys_node **snode, *siter;
5029
5030 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
5031 if (!snode) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005032 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01005033 return EXIT_FAILURE;
5034 }
5035 if (info->cardinality < LY_STMT_CARD_SOME) {
5036 LY_TREE_FOR(node, siter) {
5037 if (stmt == lys_snode2stmt(siter->nodetype)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005038 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01005039 return EXIT_FAILURE;
5040 }
5041 }
5042 }
5043
5044 return EXIT_SUCCESS;
5045}
PavolVicandb0e8172017-02-20 00:46:09 +01005046
5047int
5048yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
5049 char *parent_name, char **values, int implemented)
5050{
5051 int c, i;
5052 struct lys_module **modules, ***p, *reallocated, **pp;
5053 struct lyext_substmt *info;
5054
5055 if (!values) {
5056 return EXIT_SUCCESS;
5057 }
5058 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
5059 if (!modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005060 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005061 return EXIT_FAILURE;
5062 }
5063
5064 for (i = 0; values[i]; ++i) {
5065 c = 0;
5066 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005067 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005068 return EXIT_FAILURE;
5069 }
5070 if (info->cardinality >= LY_STMT_CARD_SOME) {
5071 /* there can be multiple instances, so instead of pointer to array,
5072 * we have in modules pointer to pointer to array */
5073 p = (struct lys_module ***)pp;
5074 modules = *p;
5075 if (!modules) {
5076 /* allocate initial array */
5077 *p = modules = calloc(2, sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005078 LY_CHECK_ERR_RETURN(!*p, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005079 } else {
5080 for (c = 0; *modules; modules++, c++);
5081 }
5082 }
5083
5084 if (c) {
5085 /* enlarge the array */
5086 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005087 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005088 *p = (struct lys_module **)reallocated;
5089 modules = *p;
5090 modules[c + 1] = NULL;
5091 }
5092
5093 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
5094 if (!modules[c]) {
5095 return EXIT_FAILURE;
5096 }
5097 }
5098
5099 return EXIT_SUCCESS;
5100}