blob: dcd80eb1e26207bc294550dcaa8c1dd3e3c908d0 [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;
Radek Krejci5c08a992016-11-02 13:30:04 +0100471 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100472
473 exp = value = (char *) list->keys;
474 while ((value = strpbrk(value, " \t\n"))) {
475 list->keys_size++;
476 while (isspace(*value)) {
477 value++;
478 }
479 }
480 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100481
482 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100483 list->keys = calloc(list->keys_size, sizeof *list->keys);
Michal Vasko53b7da02018-02-13 15:28:42 +0100484 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM(module->ctx), EXIT_FAILURE);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200485
Radek Krejci5c08a992016-11-02 13:30:04 +0100486 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
487 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
488 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100489 }
Pavol Vican5de33492016-02-22 14:03:24 +0100490 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100491}
492
493int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100494yang_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 +0100495{
496 int i, j;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200497 char *vaux, c;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200498 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100499
500 /* count the number of unique leafs in the value */
501 vaux = value;
502 while ((vaux = strpbrk(vaux, " \t\n"))) {
503 unique->expr_size++;
504 while (isspace(*vaux)) {
505 vaux++;
506 }
507 }
508 unique->expr_size++;
509 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
Michal Vasko53b7da02018-02-13 15:28:42 +0100510 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM(module->ctx), error);
Pavol Vican85f12022016-03-05 16:30:35 +0100511
512 for (i = 0; i < unique->expr_size; i++) {
513 vaux = strpbrk(value, " \t\n");
Radek Krejci1a9c3612017-04-24 14:49:43 +0200514 if (vaux) {
515 c = *vaux;
516 *vaux = '\0';
Pavol Vican85f12022016-03-05 16:30:35 +0100517 }
518
Radek Krejci1a9c3612017-04-24 14:49:43 +0200519 /* store token into unique structure (includes converting prefix to the module name) */
520 unique->expr[i] = transform_schema2json(module, value);
521 if (vaux) {
522 *vaux = c;
523 }
Pavol Vican85f12022016-03-05 16:30:35 +0100524
525 /* check that the expression does not repeat */
526 for (j = 0; j < i; j++) {
527 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100528 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
529 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100530 goto error;
531 }
532 }
533 /* try to resolve leaf */
534 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200535 unique_info = malloc(sizeof *unique_info);
Michal Vasko53b7da02018-02-13 15:28:42 +0100536 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM(module->ctx), error);
Radek Krejcid09d1a52016-08-11 14:05:45 +0200537 unique_info->list = (struct lys_node *)list;
538 unique_info->expr = unique->expr[i];
539 unique_info->trg_type = &unique->trg_type;
540 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200541 goto error;
542 }
Pavol Vican85f12022016-03-05 16:30:35 +0100543 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200544 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100545 goto error;
546 }
547 }
548
549 /* move to next token */
550 value = vaux;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200551 while(value && isspace(*value)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100552 value++;
553 }
554 }
555
556 return EXIT_SUCCESS;
557
558error:
559 return EXIT_FAILURE;
560}
561
562int
Pavol Vican5de33492016-02-22 14:03:24 +0100563yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
564{
565 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100566 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100567
Michal Vaskoe59ada92018-02-22 14:05:34 +0100568 for (k = 0; k < list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100569 str = (char *)list->unique[k].expr;
570 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100571 goto error;
572 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100573 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100574 }
575 return EXIT_SUCCESS;
576
577error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100578 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100579 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100580}
581
Pavol Vican07f220f2016-09-02 13:04:37 +0200582int
Pavol Vican81344ac2016-09-02 14:23:06 +0200583yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100584{
Pavol Vican81344ac2016-09-02 14:23:06 +0200585 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100586 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200587 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100588 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200589 if (stype->type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100590 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200591 goto error;
592 }
593 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
594 stype->base = LY_TYPE_LEAFREF;
595 return EXIT_SUCCESS;
596
597error:
598 free(value);
599 return EXIT_FAILURE;
600}
601
602int
Michal Vasko53b7da02018-02-13 15:28:42 +0100603yang_read_require_instance(struct ly_ctx *ctx, struct yang_type *stype, int req)
Pavol Vican81344ac2016-09-02 14:23:06 +0200604{
605 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100606 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200607 return EXIT_FAILURE;
608 }
609 if (stype->type->info.lref.req) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100610 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200611 return EXIT_FAILURE;
612 }
613 stype->type->info.lref.req = req;
614 stype->base = LY_TYPE_LEAFREF;
615 return EXIT_SUCCESS;
616}
617
618int
Pavol Vican7313fc02016-11-14 01:10:31 +0100619yang_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 +0100620{
Michal Vasko53b7da02018-02-13 15:28:42 +0100621 struct ly_ctx *ctx = module->ctx;
Radek Krejcidce5f972017-09-12 15:47:49 +0200622 int rc, ret = -1;
623 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200624 int8_t req;
Michal Vasko568b1952018-01-30 15:53:30 +0100625 const char *name, *value, *module_name = NULL;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100626 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200627 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200628 struct lys_type *dertype;
629 struct lys_type_enum *enms_sc = NULL;
630 struct lys_type_bit *bits_sc = NULL;
631 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100632 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100633
Pavol Vican0adf01d2016-03-22 12:29:33 +0100634 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100635 if (!value) {
636 goto error;
637 }
638
639 i = parse_identifier(value);
640 if (i < 1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100641 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
642 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100643 goto error;
644 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200645 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100646 name = value;
647 if (value[i]) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100648 module_name = lydict_insert(ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100649 name += i;
650 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100651 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
652 lydict_remove(ctx, module_name);
653 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100654 goto error;
655 }
656 ++name;
657 }
658
Michal Vasko568b1952018-01-30 15:53:30 +0100659 rc = resolve_superior_type(name, module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100660 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100661 LOGVAL(ctx, LYE_INMOD, LY_VLOG_NONE, NULL, module_name);
662 lydict_remove(ctx, module_name);
663 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100664 goto error;
665
Michal Vasko01c6fd22016-05-20 11:43:05 +0200666 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100667 } else if (rc == EXIT_FAILURE) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100668 LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
669 lydict_remove(ctx, module_name);
670 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100671 ret = EXIT_FAILURE;
672 goto error;
673 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100674 lydict_remove(ctx, module_name);
675 lydict_remove(ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200676
Michal Vasko101658e2018-06-05 15:05:54 +0200677 if (type->value_flags & LY_VALUE_UNRESGRP) {
Radek Krejcic13db382016-08-16 10:52:42 +0200678 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Michal Vasko70bf8e52018-03-26 11:32:33 +0200679 * unresolved item left inside the grouping, LYTYPE_GRP used as a flag for types inside a grouping. */
Radek Krejcic13db382016-08-16 10:52:42 +0200680 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
681 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200682 assert(((struct lys_node_grp *)siter)->unres_count);
683 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200684 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100685 LOGINT(ctx);
Radek Krejcic13db382016-08-16 10:52:42 +0200686 goto error;
687 }
Michal Vasko101658e2018-06-05 15:05:54 +0200688 type->value_flags &= ~LY_VALUE_UNRESGRP;
Radek Krejcic13db382016-08-16 10:52:42 +0200689 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200690
691 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100692 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
693 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200694 goto error;
695 }
696
Pavol Vican8bd72e42016-08-29 09:53:05 +0200697 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100698 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100699 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100700 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100701 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100702 }
703 switch (base) {
704 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100705 if (type->base == LY_TYPE_BINARY) {
706 if (type->info.str.pat_count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100707 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100708 goto error;
709 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100710 type->info.binary.length = type->info.str.length;
Michal Vasko53b7da02018-02-13 15:28:42 +0100711 if (type->info.binary.length && lyp_check_length_range(ctx, type->info.binary.length->expr, type)) {
712 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100713 goto error;
714 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100715 } else if (type->base == LY_TYPE_STRING) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100716 if (type->info.str.length && lyp_check_length_range(ctx, type->info.str.length->expr, type)) {
717 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100718 goto error;
719 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100720 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100721 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100722 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100723 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100724 break;
725 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100726 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100727 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100728 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100729 /* decimal64 type directly derived from built-in type requires fraction-digits */
Michal Vasko53b7da02018-02-13 15:28:42 +0100730 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100731 goto error;
732 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100733 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100734 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Michal Vasko53b7da02018-02-13 15:28:42 +0100735 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100736 goto error;
737 }
Radek Krejci4800f652016-09-08 14:02:52 +0200738
739 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100740 if (type->der->type.der) {
741 type->info.dec64.dig = type->der->type.info.dec64.dig;
742 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200743 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100744 if (type->info.dec64.range && lyp_check_length_range(ctx, type->info.dec64.range->expr, type)) {
745 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200746 goto error;
747 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100748 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
749 if (type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100750 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100751 goto error;
752 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100753 type->info.num.range = type->info.dec64.range;
Michal Vasko53b7da02018-02-13 15:28:42 +0100754 if (type->info.num.range && lyp_check_length_range(ctx, type->info.num.range->expr, type)) {
755 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100756 goto error;
757 }
758 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100759 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100760 goto error;
761 }
762 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100763 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100764 if (type->base != LY_TYPE_ENUM) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100765 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100766 goto error;
767 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100768 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200769
770 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100771 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200772 /* type is derived directly from buit-in enumeartion type and enum statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100773 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200774 goto error;
775 }
776 } else {
777 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100778 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200779 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
780 * 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 +0100781 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200782 goto error;
783 }
784
785 /* restricted enumeration type - the name MUST be used in the base type */
786 enms_sc = dertype->info.enums.enm;
Michal Vaskoe59ada92018-02-22 14:05:34 +0100787 for (i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200788 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100789 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200790 break;
791 }
792 }
793 if (j == dertype->info.enums.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100794 LOGVAL(ctx, LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200795 goto error;
796 }
797
Pavol Vican7313fc02016-11-14 01:10:31 +0100798 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200799 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100800 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200801 } else {
802 /* check that the assigned value corresponds to the original
803 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100804 if (type->info.enums.enm[i].value != enms_sc[j].value) {
805 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200806 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100807 LOGVAL(ctx, LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
Pavol Vican7313fc02016-11-14 01:10:31 +0100808 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200809 goto error;
810 }
811 }
812 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100813 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100814 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100815 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100816 if (type->base != LY_TYPE_BITS) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100817 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100818 goto error;
819 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100820 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200821
822 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100823 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200824 /* type is derived directly from buit-in bits type and bit statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100825 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200826 goto error;
827 }
828 } else {
829 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100830 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200831 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
832 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100833 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200834 goto error;
835 }
836
837 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200839 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100840 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200841 break;
842 }
843 }
844 if (j == dertype->info.bits.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100845 LOGVAL(ctx, LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200846 goto error;
847 }
848
849 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100850 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200851 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100852 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200853 } else {
854 /* check that the assigned position corresponds to the original
855 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100856 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
857 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200858 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100859 LOGVAL(ctx, LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
Pavol Vican7313fc02016-11-14 01:10:31 +0100860 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200861 goto error;
862 }
863 }
864 }
Pavol Vican03a59442016-03-21 15:23:45 +0100865 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200866
Radek Krejcidce5f972017-09-12 15:47:49 +0200867 for (i = type->info.bits.count; i > 0; i--) {
868 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200869
870 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100871 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200872 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100873 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
874 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
875 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200876 j--;
877 }
Pavol Vican03a59442016-03-21 15:23:45 +0100878 }
879 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100880 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100881 if (type->base == LY_TYPE_INST) {
882 if (type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100883 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100884 goto error;
885 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100886 if ((req = type->info.lref.req)) {
887 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200888 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100889 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200890 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100891 if (type->info.lref.req && (module->version < 2)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100892 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican92626d72016-09-21 09:36:09 +0200893 goto error;
894 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200895 /* flag resolving for later use */
896 if (!tpdftype) {
897 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
898 if (siter) {
899 /* just a flag - do not resolve */
900 tpdftype = 1;
901 }
902 }
903
Pavol Vican7313fc02016-11-14 01:10:31 +0100904 if (type->info.lref.path) {
905 if (type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100906 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican894ee0f2016-08-30 15:29:46 +0200907 goto error;
908 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100909 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100910 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100911 type->info.lref.path = transform_schema2json(module, value);
Michal Vasko53b7da02018-02-13 15:28:42 +0100912 lydict_remove(ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100913 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100914 goto error;
915 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200916 /* try to resolve leafref path only when this is instantiated
917 * leaf, so it is not:
918 * - typedef's type,
919 * - in grouping definition,
920 * - just instantiated in a grouping definition,
921 * because in those cases the nodes referenced in path might not be present
922 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100923 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100924 goto error;
925 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100926 } else if (!type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100927 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100928 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200929 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200930 /* copy leafref definition into the derived type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100931 type->info.lref.path = lydict_insert(ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200932 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100933 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200934 goto error;
935 }
Pavol Vican191613a2016-02-26 16:21:32 +0100936 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100937 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100938 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100939 goto error;
940 }
941 break;
942 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100943 if (type->base != LY_TYPE_IDENT) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100944 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100945 goto error;
946 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100947 if (type->der->type.der) {
948 if (type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100949 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
Pavol Vican07f220f2016-09-02 13:04:37 +0200950 goto error;
951 }
952 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100953 if (!type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100954 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
Pavol Vican07f220f2016-09-02 13:04:37 +0200955 goto error;
956 }
957 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100958 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100959 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100960 if (type->base != LY_TYPE_UNION) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100961 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100962 goto error;
963 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100964 if (!type->info.uni.types) {
965 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100966 /* this is just a derived type with no additional type specified/required */
Michal Vaskob6ab50c2018-03-08 13:46:10 +0100967 assert(type->der->type.base == LY_TYPE_UNION);
968 type->info.uni.has_ptr_type = type->der->type.info.uni.has_ptr_type;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100969 break;
970 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100971 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100972 goto error;
973 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100974 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100975 dertype = &type->info.uni.types[i];
Michal Vasko70bf8e52018-03-26 11:32:33 +0200976 if (dertype->base == LY_TYPE_DER) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100977 yang = (struct yang_type *)dertype->der;
978 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100979 dertype->parent = type->parent;
980 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100981 dertype->der = (struct lys_tpdf *)yang;
982 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100983 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100984 base = 0;
985 goto error;
986 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100987 lydict_remove(ctx, yang->name);
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100988 free(yang);
989 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100990 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200991 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100992 if (dertype->base == LY_TYPE_EMPTY) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100993 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200994 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100995 } else if (dertype->base == LY_TYPE_LEAFREF) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100996 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200997 goto error;
998 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100999 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001000 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
1001 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +01001002 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001003 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001004 }
1005 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001006
1007 default:
1008 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001009 if (type->base != base) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001010 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001011 goto error;
1012 }
1013 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001014 LOGINT(ctx);
Pavol Vicana1827962016-02-29 15:39:42 +01001015 goto error;
1016 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001017 }
PavolVican92f23622017-12-12 13:35:56 +01001018
1019 /* if derived type has extension, which need validate data */
1020 dertype = &type->der->type;
1021 while (dertype->der) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01001022 if (dertype->parent->flags & LYS_VALID_EXT) {
1023 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01001024 }
1025 dertype = &dertype->der->type;
1026 }
1027
Pavol Vican73e7c992016-02-24 12:18:05 +01001028 return EXIT_SUCCESS;
1029
1030error:
Pavol Vican8bd72e42016-08-29 09:53:05 +02001031 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001032 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001033 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001034 return ret;
1035}
1036
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001037void
1038yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1039{
1040 struct lys_type *stype;
1041 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001042 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001043
1044 for (i = 0; i < type->info.uni.count; ++i) {
1045 stype = &type->info.uni.types[i];
Michal Vasko70bf8e52018-03-26 11:32:33 +02001046 if (stype->base == LY_TYPE_DER) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001047 yang = (struct yang_type *)stype->der;
1048 stype->base = yang->base;
1049 lydict_remove(ctx, yang->name);
1050 free(yang);
1051 } else if (stype->base == LY_TYPE_UNION) {
1052 yang_free_type_union(ctx, stype);
1053 }
1054 }
1055}
1056
Pavol Vican73e7c992016-02-24 12:18:05 +01001057void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001058yang_read_type(struct ly_ctx *ctx, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001059{
1060 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001061 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001062
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001063 typ = calloc(1, sizeof *typ);
Michal Vasko53b7da02018-02-13 15:28:42 +01001064 LY_CHECK_ERR_RETURN(!typ, LOGMEM(ctx), NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001065
1066 typ->flags = LY_YANG_STRUCTURE_FLAG;
1067 switch (type) {
1068 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001069 if (((struct lys_node_leaf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001070 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
Pavol Vican85427f02016-09-26 15:21:05 +02001071 goto error;
1072 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001073 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1074 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1075 typ->type = &((struct lys_node_leaf *)parent)->type;
1076 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001077 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001078 if (((struct lys_node_leaflist *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001079 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
Pavol Vican85427f02016-09-26 15:21:05 +02001080 goto error;
1081 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001082 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1083 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1084 typ->type = &((struct lys_node_leaflist *)parent)->type;
1085 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001086 case UNION_KEYWORD:
1087 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1088 typ->type = (struct lys_type *)parent;
1089 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001090 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001091 if (((struct lys_tpdf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001092 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
Pavol Vican85427f02016-09-26 15:21:05 +02001093 goto error;
1094 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001095 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1096 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001097 break;
1098 case REPLACE_KEYWORD:
1099 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001100 dev = (struct lys_deviate *)parent;
1101 if (dev->type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001102 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001103 goto error;
1104 }
PavolVican75af21d2016-12-29 20:04:07 +01001105 dev->type = calloc(1, sizeof *dev->type);
Michal Vasko53b7da02018-02-13 15:28:42 +01001106 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001107 dev->type->der = (struct lys_tpdf *)typ;
1108 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001109 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001110 case EXTENSION_INSTANCE:
1111 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1112 typ->type = parent;
1113 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001114 default:
1115 goto error;
1116 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001117 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001118 typ->name = lydict_insert_zc(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001119 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001120
1121error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001122 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001123 free(typ);
1124 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001125}
1126
1127void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001128yang_read_length(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001129{
PavolVicaneef1d912017-02-19 00:19:15 +01001130 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001131
PavolVicaneef1d912017-02-19 00:19:15 +01001132 if (is_ext_instance) {
1133 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001134 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001135 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1136 stype->base = LY_TYPE_STRING;
1137 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001138 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001139 goto error;
1140 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001141
PavolVicaneef1d912017-02-19 00:19:15 +01001142 if (stype->type->info.str.length) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001143 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001144 goto error;
1145 }
1146 length = calloc(1, sizeof *length);
Michal Vasko53b7da02018-02-13 15:28:42 +01001147 LY_CHECK_ERR_GOTO(!length, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001148 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001149 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001150 length->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001151 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001152
1153error:
1154 free(value);
1155 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001156}
Pavol Vican1c203db2016-02-24 14:05:23 +01001157
Pavol Vican6eecf302016-08-10 11:09:05 +02001158int
Michal Vasko53b7da02018-02-13 15:28:42 +01001159yang_read_pattern(struct ly_ctx *ctx, struct lys_restr *pattern, void **precomp, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001160{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001161 char *buf;
1162 size_t len;
1163
Michal Vasko53b7da02018-02-13 15:28:42 +01001164 if (precomp && lyp_precompile_pattern(ctx, value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001165 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001166 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001167 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001168
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001169 len = strlen(value);
1170 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Michal Vasko53b7da02018-02-13 15:28:42 +01001171 LY_CHECK_ERR_RETURN(!buf, LOGMEM(ctx); free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001172
1173 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001174 strcpy(&buf[1], value);
1175 free(value);
1176
Michal Vasko53b7da02018-02-13 15:28:42 +01001177 pattern->expr = lydict_insert_zc(ctx, buf);
Pavol Vican6eecf302016-08-10 11:09:05 +02001178 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001179}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001180
1181void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001182yang_read_range(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001183{
PavolVicaneef1d912017-02-19 00:19:15 +01001184 struct lys_restr * range;
1185
1186 if (is_ext_instance) {
1187 range = (struct lys_restr *)stype;
1188 } else {
1189 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001190 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001191 goto error;
1192 }
1193 stype->base = LY_TYPE_DEC64;
1194 if (stype->type->info.dec64.range) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001195 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001196 goto error;
1197 }
1198 range = calloc(1, sizeof *range);
Michal Vasko53b7da02018-02-13 15:28:42 +01001199 LY_CHECK_ERR_GOTO(!range, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001200 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001201 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001202 range->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001203 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001204
1205error:
1206 free(value);
1207 return NULL;
1208}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001209
1210int
Michal Vasko53b7da02018-02-13 15:28:42 +01001211yang_read_fraction(struct ly_ctx *ctx, struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001212{
Michal Vasko27e5e682018-07-23 14:22:57 +02001213 uint32_t i;
1214
Pavol Vican6b072512016-04-04 10:50:21 +02001215 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1216 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001217 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001218 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001219 goto error;
1220 }
1221 if (typ->type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001222 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001223 goto error;
1224 }
1225 /* range check */
1226 if (value < 1 || value > 18) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001227 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001228 goto error;
1229 }
1230 typ->type->info.dec64.dig = value;
Michal Vasko27e5e682018-07-23 14:22:57 +02001231 typ->type->info.dec64.div = 10;
1232 for (i = 1; i < value; i++) {
1233 typ->type->info.dec64.div *= 10;
1234 }
Pavol Vican07ea68d2016-02-25 12:01:37 +01001235 return EXIT_SUCCESS;
1236
1237error:
1238 return EXIT_FAILURE;
1239}
Pavol Vican79a763d2016-02-25 15:41:27 +01001240
Pavol Vican874715f2016-10-25 14:52:08 +02001241int
Michal Vasko53b7da02018-02-13 15:28:42 +01001242yang_read_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001243{
Pavol Vican874715f2016-10-25 14:52:08 +02001244 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001245
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001246 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001247 if (!value[0]) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001248 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1249 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
Pavol Vicanc6662412016-08-30 08:06:28 +02001250 free(value);
1251 goto error;
1252 }
1253
Michal Vasko53b7da02018-02-13 15:28:42 +01001254 enm->name = lydict_insert_zc(ctx, value);
Pavol Vican79a763d2016-02-25 15:41:27 +01001255
1256 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1257 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001258 LOGVAL(ctx, LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001259 goto error;
1260 }
1261
Pavol Vican874715f2016-10-25 14:52:08 +02001262 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001263 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001264 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001265 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001266 LOGVAL(ctx, LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001267 goto error;
1268 }
1269 }
1270
Pavol Vican874715f2016-10-25 14:52:08 +02001271 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001272
1273error:
Pavol Vican874715f2016-10-25 14:52:08 +02001274 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001275}
1276
1277int
Michal Vasko53b7da02018-02-13 15:28:42 +01001278yang_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 +01001279{
1280 int i, j;
1281
1282 if (!assign) {
1283 /* assign value automatically */
1284 if (*value > INT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001285 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001286 goto error;
1287 }
1288 enm->value = *value;
1289 enm->flags |= LYS_AUTOASSIGNED;
1290 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001291 } else if (typ->type->info.enums.enm == enm) {
1292 /* change value, which is assigned automatically, if first enum has value. */
1293 *value = typ->type->info.enums.enm[0].value;
1294 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001295 }
1296
1297 /* check that the value is unique */
1298 j = typ->type->info.enums.count-1;
1299 for (i = 0; i < j; i++) {
1300 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001301 LOGVAL(ctx, LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001302 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1303 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001304 goto error;
1305 }
1306 }
1307
1308 return EXIT_SUCCESS;
1309
1310error:
1311 return EXIT_FAILURE;
1312}
Pavol Vican9887c682016-02-29 11:32:01 +01001313
Pavol Vican59e8dee2016-10-25 15:29:38 +02001314int
Michal Vasko53b7da02018-02-13 15:28:42 +01001315yang_read_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001316{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001317 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001318
PavolVicane87cb932016-12-30 15:36:18 +01001319 typ->base = LY_TYPE_BITS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001320 bit->name = lydict_insert_zc(ctx, value);
1321 if (lyp_check_identifier(ctx, bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001322 goto error;
1323 }
Pavol Vican9887c682016-02-29 11:32:01 +01001324
Pavol Vican59e8dee2016-10-25 15:29:38 +02001325 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001326 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001327 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001328 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001329 LOGVAL(ctx, LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001330 goto error;
1331 }
1332 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001333 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001334
1335error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001336 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001337}
1338
1339int
Michal Vasko53b7da02018-02-13 15:28:42 +01001340yang_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 +01001341{
1342 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001343
1344 if (!assign) {
1345 /* assign value automatically */
1346 if (*value > UINT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001347 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001348 goto error;
1349 }
1350 bit->pos = (uint32_t)*value;
1351 bit->flags |= LYS_AUTOASSIGNED;
1352 (*value)++;
1353 }
1354
1355 j = typ->type->info.bits.count - 1;
1356 /* check that the value is unique */
1357 for (i = 0; i < j; i++) {
1358 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001359 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 +01001360 goto error;
1361 }
1362 }
1363
Pavol Vican9887c682016-02-29 11:32:01 +01001364 return EXIT_SUCCESS;
1365
1366error:
1367 return EXIT_FAILURE;
1368}
Pavol Vican0df02b02016-03-01 10:28:50 +01001369
Pavol Vican3ad50f82016-12-04 15:00:36 +01001370int
1371yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001372{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001373 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001374 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001375 free(value);
1376 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001377 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001378 }
1379 aug->parent = parent;
1380 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001381 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001382}
Pavol Vican220e5a12016-03-03 14:19:43 +01001383
PavolVican6f000922017-02-10 12:56:59 +01001384void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001385yang_read_deviate_unsupported(struct ly_ctx *ctx, struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001386{
PavolVican75af21d2016-12-29 20:04:07 +01001387 if (dev->deviate_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001388 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001389 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001390 }
PavolVican75af21d2016-12-29 20:04:07 +01001391 dev->deviate = calloc(1, sizeof *dev->deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001392 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001393 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1394 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001395 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001396}
1397
1398void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001399yang_read_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001400{
PavolVican75af21d2016-12-29 20:04:07 +01001401 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001402
PavolVican4b80d042017-02-23 14:30:27 +01001403 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001404 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1405 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001406 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001407 }
PavolVican75af21d2016-12-29 20:04:07 +01001408 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1409 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001410 LY_CHECK_ERR_RETURN(!deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001411 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1412 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001413 }
PavolVican75af21d2016-12-29 20:04:07 +01001414 dev->deviate[dev->deviate_size].mod = mod;
1415 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001416}
1417
1418int
PavolVican75af21d2016-12-29 20:04:07 +01001419yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001420{
1421 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001422 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001423
Pavol Vican85f12022016-03-05 16:30:35 +01001424 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001425 if (dev_target->nodetype == LYS_LEAFLIST) {
1426 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1427 } else if (dev_target->nodetype == LYS_LEAF) {
1428 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001429 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001430 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1431 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001432 goto error;
1433 }
1434
PavolVican75af21d2016-12-29 20:04:07 +01001435 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001436 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001437 if (!ly_strequal(*stritem, deviate->units, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001438 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
1439 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001440 goto error;
1441 }
1442 /* remove current units value of the target */
1443 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001444 *stritem = NULL;
1445 /* remove its extensions */
1446 j = -1;
1447 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1448 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1449 --j;
1450 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001451 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001452 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001453 /* check that there is no current value */
1454 if (*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001455 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1456 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001457 goto error;
1458 }
1459 } else { /* replace */
1460 if (!*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001461 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1462 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001463 goto error;
1464 }
1465 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001466 /* remove current units value of the target ... */
1467 lydict_remove(ctx, *stritem);
1468
1469 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001470 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001471 }
1472
Pavol Vican85f12022016-03-05 16:30:35 +01001473 return EXIT_SUCCESS;
1474
1475error:
1476 return EXIT_FAILURE;
1477}
1478
1479int
PavolVican75af21d2016-12-29 20:04:07 +01001480yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001481{
Michal Vasko53b7da02018-02-13 15:28:42 +01001482 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican85f12022016-03-05 16:30:35 +01001483 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001484 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001485
1486 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001487 if (dev_target->nodetype != LYS_LIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001488 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1489 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001490 goto error;
1491 }
1492
PavolVican75af21d2016-12-29 20:04:07 +01001493 list = (struct lys_node_list *)dev_target;
1494 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001495 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001496 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Michal Vasko53b7da02018-02-13 15:28:42 +01001497 LY_CHECK_ERR_GOTO(!unique, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001498 list->unique = unique;
1499 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001500 }
1501
1502 return EXIT_SUCCESS;
1503
1504error:
1505 return EXIT_FAILURE;
1506}
1507
1508int
PavolVican75af21d2016-12-29 20:04:07 +01001509yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1510 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001511{
1512 struct lys_node *node;
1513 struct lys_node_choice *choice;
1514 struct lys_node_leaf *leaf;
1515 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001516 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001517 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001518
Pavol Vican38321d02016-08-16 14:56:02 +02001519 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001520 if (dev_target->nodetype == LYS_CHOICE) {
1521 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001522 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1523 if (rc || !node) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001524 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001525 goto error;
1526 }
PavolVican75af21d2016-12-29 20:04:07 +01001527 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001528 if (!choice->dflt || (choice->dflt != node)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001529 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1530 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001531 goto error;
1532 }
PavolVican6f000922017-02-10 12:56:59 +01001533 choice->dflt = NULL;
1534 /* remove extensions of this default instance from the target node */
1535 j = -1;
1536 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1537 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1538 --j;
1539 }
Pavol Vican38321d02016-08-16 14:56:02 +02001540 } else { /* add or replace */
1541 choice->dflt = node;
1542 if (!choice->dflt) {
1543 /* default branch not found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001544 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001545 goto error;
1546 }
1547 }
PavolVican75af21d2016-12-29 20:04:07 +01001548 } else if (dev_target->nodetype == LYS_LEAF) {
1549 leaf = (struct lys_node_leaf *)dev_target;
1550 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001551 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001552 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1553 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001554 goto error;
1555 }
1556 /* remove value */
1557 lydict_remove(ctx, leaf->dflt);
1558 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001559 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001560 /* remove extensions of this default instance from the target node */
1561 j = -1;
1562 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1563 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1564 --j;
1565 }
Pavol Vican38321d02016-08-16 14:56:02 +02001566 } else { /* add (already checked) and replace */
1567 /* remove value */
1568 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001569 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001570
1571 /* set new value */
1572 leaf->dflt = lydict_insert(ctx, value, u);
1573
1574 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001575 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001576 }
1577 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001578 llist = (struct lys_node_leaflist *)dev_target;
1579 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001580 /* find and remove the value in target list */
1581 for (i = 0; i < llist->dflt_size; i++) {
1582 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1583 /* match, remove the value */
1584 lydict_remove(llist->module->ctx, llist->dflt[i]);
1585 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001586 /* remove extensions of this default instance from the target node */
1587 j = -1;
1588 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1589 if (dev_target->ext[j]->insubstmt_index == i) {
1590 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1591 --j;
1592 } else if (dev_target->ext[j]->insubstmt_index > i) {
1593 /* decrease the substatement index of the extension because of the changed array of defaults */
1594 dev_target->ext[j]->insubstmt_index--;
1595 }
1596 }
Pavol Vican38321d02016-08-16 14:56:02 +02001597 break;
1598 }
1599 }
1600 if (i == llist->dflt_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001601 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1602 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 +02001603 goto error;
1604 }
1605 } else {
1606 /* add or replace, anyway we place items into the deviate's list
1607 which propagates to the target */
1608 /* we just want to check that the value isn't already in the list */
1609 for (i = 0; i < llist->dflt_size; i++) {
1610 if (ly_strequal(llist->dflt[i], value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001611 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1612 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
Pavol Vican38321d02016-08-16 14:56:02 +02001613 goto error;
1614 }
1615 }
1616 /* store it in target node */
1617 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1618
1619 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001620 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001621 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001622 }
1623 }
1624
1625 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001626
Pavol Vican38321d02016-08-16 14:56:02 +02001627error:
1628 return EXIT_FAILURE;
1629}
1630
Pavol Vican38321d02016-08-16 14:56:02 +02001631int
PavolVican75af21d2016-12-29 20:04:07 +01001632yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1633 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001634{
Michal Vasko53b7da02018-02-13 15:28:42 +01001635 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001636 int i;
1637 struct lys_node_leaflist *llist;
1638 const char **dflt;
1639
1640 /* check target node type */
1641 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001642 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1643 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001644 goto error;
1645 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
Michal Vasko53b7da02018-02-13 15:28:42 +01001646 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1647 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
PavolVican75af21d2016-12-29 20:04:07 +01001648 goto error;
1649 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001650 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1651 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001652 goto error;
1653 }
1654
PavolVican75af21d2016-12-29 20:04:07 +01001655 if (deviate->mod == LY_DEVIATE_ADD) {
1656 /* check that there is no current value */
1657 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1658 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001659 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1660 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
PavolVican75af21d2016-12-29 20:04:07 +01001661 goto error;
1662 }
Pavol Vican85f12022016-03-05 16:30:35 +01001663
PavolVican75af21d2016-12-29 20:04:07 +01001664 /* check collision with mandatory/min-elements */
1665 if ((dev_target->flags & LYS_MAND_TRUE) ||
1666 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001667 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1668 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
PavolVican75af21d2016-12-29 20:04:07 +01001669 "Adding the \"default\" statement is forbidden on %s statement.",
1670 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1671 goto error;
1672 }
1673 } else if (deviate->mod == LY_DEVIATE_RPL) {
1674 /* check that there was a value before */
1675 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1676 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001677 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1678 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
PavolVican75af21d2016-12-29 20:04:07 +01001679 goto error;
1680 }
1681 }
Pavol Vican85f12022016-03-05 16:30:35 +01001682
PavolVican75af21d2016-12-29 20:04:07 +01001683 if (dev_target->nodetype == LYS_LEAFLIST) {
1684 /* reallocate default list in the target */
1685 llist = (struct lys_node_leaflist *)dev_target;
1686 if (deviate->mod == LY_DEVIATE_ADD) {
1687 /* reallocate (enlarge) the unique array of the target */
1688 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001689 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001690 llist->dflt = dflt;
1691 } else if (deviate->mod == LY_DEVIATE_RPL) {
1692 /* reallocate (replace) the unique array of the target */
1693 for (i = 0; i < llist->dflt_size; i++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001694 lydict_remove(ctx, llist->dflt[i]);
PavolVican75af21d2016-12-29 20:04:07 +01001695 }
1696 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001697 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001698 llist->dflt = dflt;
1699 llist->dflt_size = 0;
1700 }
1701 }
1702
1703 for (i = 0; i < deviate->dflt_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001704 if (yang_fill_deviate_default(ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
PavolVican75af21d2016-12-29 20:04:07 +01001705 goto error;
1706 }
1707 }
Pavol Vican85f12022016-03-05 16:30:35 +01001708
1709 return EXIT_SUCCESS;
1710
1711error:
1712 return EXIT_FAILURE;
1713}
1714
1715int
PavolVican75af21d2016-12-29 20:04:07 +01001716yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001717{
Michal Vasko53b7da02018-02-13 15:28:42 +01001718 struct ly_ctx *ctx = dev_target->module->ctx;
Radek Krejcie00d2312016-08-12 15:27:49 +02001719 struct lys_node *parent;
1720
Pavol Vican85f12022016-03-05 16:30:35 +01001721 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001722 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001723 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1724 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001725 goto error;
1726 }
1727
PavolVican75af21d2016-12-29 20:04:07 +01001728 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001729 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001730 if (dev_target->flags & LYS_MAND_MASK) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001731 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1732 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001733 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001734 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001735 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001736 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
Michal Vasko53b7da02018-02-13 15:28:42 +01001737 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1738 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001739 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001740 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001741 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1742 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001743 goto error;
1744 }
Pavol Vican85f12022016-03-05 16:30:35 +01001745 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001746 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001747 if (!(dev_target->flags & LYS_MAND_MASK)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001748 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1749 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001750 goto error;
1751 }
Pavol Vican85f12022016-03-05 16:30:35 +01001752 }
1753
Pavol Vican85f12022016-03-05 16:30:35 +01001754 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001755 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001756
1757 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001758 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001759
Radek Krejcie00d2312016-08-12 15:27:49 +02001760 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001761 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001762 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1763 parent = parent->parent) {
1764 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1765 /* stop also on presence containers */
1766 break;
1767 }
1768 }
1769 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1770 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1771 if (lyp_check_mandatory_choice(parent)) {
1772 goto error;
1773 }
1774 }
1775
Pavol Vican85f12022016-03-05 16:30:35 +01001776 return EXIT_SUCCESS;
1777
1778error:
1779 return EXIT_FAILURE;
1780}
1781
1782int
PavolVican75af21d2016-12-29 20:04:07 +01001783yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001784{
Michal Vasko53b7da02018-02-13 15:28:42 +01001785 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican09adcc32016-08-25 10:51:36 +02001786 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001787
1788 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001789 if (dev_target->nodetype == LYS_LEAFLIST) {
1790 max = &((struct lys_node_leaflist *)dev_target)->max;
1791 min = &((struct lys_node_leaflist *)dev_target)->min;
1792 } else if (dev_target->nodetype == LYS_LIST) {
1793 max = &((struct lys_node_list *)dev_target)->max;
1794 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001795 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001796 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1797 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 +01001798 goto error;
1799 }
1800
PavolVican75af21d2016-12-29 20:04:07 +01001801 ui32val = (type) ? max : min;
1802 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001803 /* check that there is no current value */
1804 if (*ui32val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001805 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1806 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001807 goto error;
1808 }
PavolVican75af21d2016-12-29 20:04:07 +01001809 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001810 /* unfortunately, there is no way to check reliably that there
1811 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001812 }
1813
1814 /* add (already checked) and replace */
1815 /* set new value specified in deviation */
1816 *ui32val = value;
1817
Pavol Vican09adcc32016-08-25 10:51:36 +02001818 /* check min-elements is smaller than max-elements */
1819 if (*max && *min > *max) {
1820 if (type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001821 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1822 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001823 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001824 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1825 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001826 }
1827 goto error;
1828 }
1829
Pavol Vican85f12022016-03-05 16:30:35 +01001830 return EXIT_SUCCESS;
1831
1832error:
1833 return EXIT_FAILURE;
1834}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001835
1836int
PavolVican75af21d2016-12-29 20:04:07 +01001837yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1838 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001839{
Michal Vasko53b7da02018-02-13 15:28:42 +01001840 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001841 int i, j, erase_must = 1;
1842 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001843 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001844
PavolVican75af21d2016-12-29 20:04:07 +01001845 /* check target node type */
1846 switch (dev_target->nodetype) {
1847 case LYS_LEAF:
1848 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1849 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001850 break;
PavolVican75af21d2016-12-29 20:04:07 +01001851 case LYS_CONTAINER:
1852 trg_must = &((struct lys_node_container *)dev_target)->must;
1853 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1854 break;
1855 case LYS_LEAFLIST:
1856 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1857 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1858 break;
1859 case LYS_LIST:
1860 trg_must = &((struct lys_node_list *)dev_target)->must;
1861 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1862 break;
1863 case LYS_ANYXML:
1864 case LYS_ANYDATA:
1865 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1866 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1867 break;
1868 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01001869 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1870 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001871 goto error;
1872 }
1873
1874 /* flag will be checked again, clear it for now */
Michal Vaskoc04173b2018-03-09 10:43:22 +01001875 dev_target->flags &= ~(LYS_XPCONF_DEP | LYS_XPSTATE_DEP);
PavolVican75af21d2016-12-29 20:04:07 +01001876
1877 if (deviate->mod == LY_DEVIATE_ADD) {
1878 /* reallocate the must array of the target */
1879 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Michal Vasko53b7da02018-02-13 15:28:42 +01001880 LY_CHECK_ERR_GOTO(!must, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001881 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001882 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001883 free(deviate->must);
1884 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001885 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001886 erase_must = 0;
1887 } else if (deviate->mod == LY_DEVIATE_DEL) {
1888 /* find must to delete, we are ok with just matching conditions */
1889 for (j = 0; j < deviate->must_size; ++j) {
1890 for (i = 0; i < *trg_must_size; i++) {
1891 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1892 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001893 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001894 /* ... and maintain the array */
1895 (*trg_must_size)--;
1896 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001897 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001898 }
1899 if (!(*trg_must_size)) {
1900 free(*trg_must);
1901 *trg_must = NULL;
1902 } else {
PavolVican214408f2017-02-03 11:54:05 +01001903 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001904 }
1905
1906 i = -1; /* set match flag */
1907 break;
1908 }
1909 }
1910 if (i != -1) {
1911 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001912 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1913 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
PavolVican75af21d2016-12-29 20:04:07 +01001914 goto error;
1915 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001916 }
1917 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001918
PavolVican6f000922017-02-10 12:56:59 +01001919 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1920 goto error;
1921 }
PavolVican75af21d2016-12-29 20:04:07 +01001922 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02001923 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1924 && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001925 goto error;
1926 }
1927
PavolVican75af21d2016-12-29 20:04:07 +01001928 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001929
PavolVican75af21d2016-12-29 20:04:07 +01001930error:
1931 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1932 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001933 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001934 }
1935 free(deviate->must);
1936 }
1937 return EXIT_FAILURE;
1938}
1939
1940int
1941yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1942 struct lys_node_list *list, int index, char * value)
1943{
Michal Vasko53b7da02018-02-13 15:28:42 +01001944 struct ly_ctx *ctx = module->ctx;
PavolVican6f000922017-02-10 12:56:59 +01001945 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001946
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001947 /* find unique structures to delete */
1948 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001949 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001950 continue;
1951 }
1952
PavolVican75af21d2016-12-29 20:04:07 +01001953 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1954 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001955 break;
1956 }
1957 }
1958
PavolVican75af21d2016-12-29 20:04:07 +01001959 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001960 /* we have a match, free the unique structure ... */
1961 for (j = 0; j < list->unique[i].expr_size; j++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001962 lydict_remove(ctx, list->unique[i].expr[j]);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001963 }
1964 free(list->unique[i].expr);
1965 /* ... and maintain the array */
1966 list->unique_size--;
1967 if (i != list->unique_size) {
1968 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1969 list->unique[i].expr = list->unique[list->unique_size].expr;
1970 }
1971
1972 if (!list->unique_size) {
1973 free(list->unique);
1974 list->unique = NULL;
1975 } else {
1976 list->unique[list->unique_size].expr_size = 0;
1977 list->unique[list->unique_size].expr = NULL;
1978 }
1979
PavolVican6f000922017-02-10 12:56:59 +01001980 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001981 i = -1; /* set match flag */
1982 break;
1983 }
1984 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001985
1986 if (i != -1) {
1987 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001988 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1989 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001990 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001991 }
1992
PavolVican6f000922017-02-10 12:56:59 +01001993 /* remove extensions of this unique instance from the target node */
1994 j = -1;
1995 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1996 if (list->ext[j]->insubstmt_index == k) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001997 lyp_ext_instance_rm(ctx, &list->ext, &list->ext_size, j);
PavolVican6f000922017-02-10 12:56:59 +01001998 --j;
1999 } else if (list->ext[j]->insubstmt_index > k) {
2000 /* decrease the substatement index of the extension because of the changed array of uniques */
2001 list->ext[j]->insubstmt_index--;
2002 }
2003 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002004 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01002005}
Pavol Vican021488a2016-01-25 23:56:12 +01002006
PavolVican75af21d2016-12-29 20:04:07 +01002007int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01002008{
PavolVican75af21d2016-12-29 20:04:07 +01002009 struct lys_node_list *list;
2010 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01002011 uint i = 0;
2012 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01002013
PavolVican75af21d2016-12-29 20:04:07 +01002014 if (yang_read_deviate_unique(deviate, dev_target)) {
2015 goto error;
2016 }
2017 list = (struct lys_node_list *)dev_target;
2018 last_unique = &list->unique[list->unique_size];
2019 for (i = 0; i < deviate->unique_size; ++i) {
2020 str = (char *) deviate->unique[i].expr;
2021 if (deviate->mod == LY_DEVIATE_ADD) {
2022 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2023 free(str);
2024 goto error;
2025 }
2026 list->unique_size++;
2027 } else if (deviate->mod == LY_DEVIATE_DEL) {
2028 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2029 free(str);
2030 goto error;
2031 }
2032 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2033 free(str);
2034 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002035 }
2036 }
PavolVican75af21d2016-12-29 20:04:07 +01002037 free(str);
2038 }
2039 if (deviate->mod == LY_DEVIATE_ADD) {
2040 free(deviate->unique);
2041 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002042 }
Pavol Vican38321d02016-08-16 14:56:02 +02002043
PavolVican75af21d2016-12-29 20:04:07 +01002044 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01002045
Pavol Vican021488a2016-01-25 23:56:12 +01002046error:
PavolVican75af21d2016-12-29 20:04:07 +01002047 if (deviate->mod == LY_DEVIATE_ADD) {
2048 for (i = i + 1; i < deviate->unique_size; ++i) {
2049 free(deviate->unique[i].expr);
2050 }
2051 free(deviate->unique);
2052 deviate->unique = last_unique;
2053
2054 }
Pavol Vican021488a2016-01-25 23:56:12 +01002055 return EXIT_FAILURE;
2056}
2057
Pavol Vicanec423c92016-10-24 21:33:43 +02002058static int
2059yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2060 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002061{
Pavol Vican55870412016-03-10 12:36:21 +01002062 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002063 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002064 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002065
Pavol Vicanec423c92016-10-24 21:33:43 +02002066 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002067 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002068 if (!rc) {
2069 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002070 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002071 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2072 &trg->inc[trg->inc_size], unres)) {
2073 ret = -1;
2074 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002075 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002076 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002077 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002078 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002079 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002080
Pavol Vicanec423c92016-10-24 21:33:43 +02002081 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002082 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002083}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002084
PavolVicanc1807262017-01-31 18:00:27 +01002085struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002086yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002087{
2088 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2089 LYEXT_PAR parent_type;
2090 uint8_t *size;
2091
2092 switch (type) {
2093 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002094 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002095 ext = &((struct lys_module *)node)->ext;
2096 size = &((struct lys_module *)node)->ext_size;
2097 parent_type = LYEXT_PAR_MODULE;
2098 break;
PavolVican22e88682017-02-14 22:38:18 +01002099 case BELONGS_TO_KEYWORD:
2100 if (is_ext_instance) {
2101 ext = &((struct lys_ext_instance *)node)->ext;
2102 size = &((struct lys_ext_instance *)node)->ext_size;
2103 parent_type = LYEXT_PAR_EXTINST;
2104 } else {
2105 ext = &((struct lys_module *)node)->ext;
2106 size = &((struct lys_module *)node)->ext_size;
2107 parent_type = LYEXT_PAR_MODULE;
2108 }
2109 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002110 case IMPORT_KEYWORD:
2111 ext = &((struct lys_import *)node)->ext;
2112 size = &((struct lys_import *)node)->ext_size;
2113 parent_type = LYEXT_PAR_IMPORT;
2114 break;
2115 case INCLUDE_KEYWORD:
2116 ext = &((struct lys_include *)node)->ext;
2117 size = &((struct lys_include *)node)->ext_size;
2118 parent_type = LYEXT_PAR_INCLUDE;
2119 break;
PavolVican171717d2017-02-01 14:49:55 +01002120 case REVISION_KEYWORD:
2121 ext = &((struct lys_revision *)node)->ext;
2122 size = &((struct lys_revision *)node)->ext_size;
2123 parent_type = LYEXT_PAR_REVISION;
2124 break;
PavolVican70ce7452017-02-01 15:39:39 +01002125 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002126 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002127 case LEAF_KEYWORD:
2128 case LEAF_LIST_KEYWORD:
2129 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002130 case CHOICE_KEYWORD:
2131 case CASE_KEYWORD:
2132 case ANYXML_KEYWORD:
2133 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002134 case USES_KEYWORD:
2135 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002136 case ACTION_KEYWORD:
2137 case RPC_KEYWORD:
2138 case INPUT_KEYWORD:
2139 case OUTPUT_KEYWORD:
2140 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002141 ext = &((struct lys_node *)node)->ext;
2142 size = &((struct lys_node *)node)->ext_size;
2143 parent_type = LYEXT_PAR_NODE;
2144 break;
PavolVican19dc6152017-02-06 12:04:15 +01002145 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002146 if (is_ext_instance) {
2147 ext = &((struct lys_ext_instance *)node)->ext;
2148 size = &((struct lys_ext_instance *)node)->ext_size;
2149 parent_type = LYEXT_PAR_EXTINST;
2150 } else {
2151 ext = &((struct lys_ext *)node)->ext;
2152 size = &((struct lys_ext *)node)->ext_size;
2153 parent_type = LYEXT_PAR_EXT;
2154 }
2155 break;
PavolVican19dc6152017-02-06 12:04:15 +01002156 case EXTENSION_KEYWORD:
2157 ext = &((struct lys_ext *)node)->ext;
2158 size = &((struct lys_ext *)node)->ext_size;
2159 parent_type = LYEXT_PAR_EXT;
2160 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002161 case FEATURE_KEYWORD:
2162 ext = &((struct lys_feature *)node)->ext;
2163 size = &((struct lys_feature *)node)->ext_size;
2164 parent_type = LYEXT_PAR_FEATURE;
2165 break;
PavolVican8fa31242017-02-07 11:04:26 +01002166 case IDENTITY_KEYWORD:
2167 ext = &((struct lys_ident *)node)->ext;
2168 size = &((struct lys_ident *)node)->ext_size;
2169 parent_type = LYEXT_PAR_IDENT;
2170 break;
2171 case IF_FEATURE_KEYWORD:
2172 ext = &((struct lys_iffeature *)node)->ext;
2173 size = &((struct lys_iffeature *)node)->ext_size;
2174 parent_type = LYEXT_PAR_IFFEATURE;
2175 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002176 case TYPEDEF_KEYWORD:
2177 ext = &((struct lys_tpdf *)node)->ext;
2178 size = &((struct lys_tpdf *)node)->ext_size;
2179 parent_type = LYEXT_PAR_TPDF;
2180 break;
PavolVican056fcd12017-02-07 15:36:53 +01002181 case TYPE_KEYWORD:
2182 ext = &((struct yang_type *)node)->type->ext;
2183 size = &((struct yang_type *)node)->type->ext_size;
2184 parent_type = LYEXT_PAR_TYPE;
2185 break;
2186 case LENGTH_KEYWORD:
2187 case PATTERN_KEYWORD:
2188 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002189 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002190 ext = &((struct lys_restr *)node)->ext;
2191 size = &((struct lys_restr *)node)->ext_size;
2192 parent_type = LYEXT_PAR_RESTR;
2193 break;
PavolVican59ba4602017-02-08 11:53:32 +01002194 case WHEN_KEYWORD:
2195 ext = &((struct lys_when *)node)->ext;
2196 size = &((struct lys_when *)node)->ext_size;
2197 parent_type = LYEXT_PAR_RESTR;
2198 break;
PavolVican056fcd12017-02-07 15:36:53 +01002199 case ENUM_KEYWORD:
2200 ext = &((struct lys_type_enum *)node)->ext;
2201 size = &((struct lys_type_enum *)node)->ext_size;
2202 parent_type = LYEXT_PAR_TYPE_ENUM;
2203 break;
2204 case BIT_KEYWORD:
2205 ext = &((struct lys_type_bit *)node)->ext;
2206 size = &((struct lys_type_bit *)node)->ext_size;
2207 parent_type = LYEXT_PAR_TYPE_BIT;
2208 break;
PavolVican77374ee2017-02-08 15:18:45 +01002209 case REFINE_KEYWORD:
2210 ext = &((struct lys_type_bit *)node)->ext;
2211 size = &((struct lys_type_bit *)node)->ext_size;
2212 parent_type = LYEXT_PAR_REFINE;
2213 break;
PavolVican6f000922017-02-10 12:56:59 +01002214 case DEVIATION_KEYWORD:
2215 ext = &((struct lys_deviation *)node)->ext;
2216 size = &((struct lys_deviation *)node)->ext_size;
2217 parent_type = LYEXT_PAR_DEVIATION;
2218 break;
2219 case NOT_SUPPORTED_KEYWORD:
2220 case ADD_KEYWORD:
2221 case DELETE_KEYWORD:
2222 case REPLACE_KEYWORD:
2223 ext = &((struct lys_deviate *)node)->ext;
2224 size = &((struct lys_deviate *)node)->ext_size;
2225 parent_type = LYEXT_PAR_DEVIATE;
2226 break;
PavolVicandefa4852017-02-10 13:13:23 +01002227 case EXTENSION_INSTANCE:
2228 ext = &((struct lys_ext_instance *)node)->ext;
2229 size = &((struct lys_ext_instance *)node)->ext_size;
2230 parent_type = LYEXT_PAR_EXTINST;
2231 break;
PavolVicanc1807262017-01-31 18:00:27 +01002232 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002233 LOGINT(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002234 return NULL;
2235 }
2236
2237 instance = calloc(1, sizeof *instance);
2238 if (!instance) {
2239 goto error;
2240 }
2241 instance->parent_type = parent_type;
2242 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2243 if (!tmp) {
2244 goto error;
2245 }
2246 tmp[*size] = instance;
2247 *ext = tmp;
2248 (*size)++;
2249 return instance;
2250
2251error:
Michal Vasko53b7da02018-02-13 15:28:42 +01002252 LOGMEM(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002253 free(instance);
2254 return NULL;
2255}
2256
2257void *
2258yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002259 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002260{
2261 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002262 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002263
2264 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002265 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002266 if (!instance) {
2267 return NULL;
2268 }
PavolVicanc1807262017-01-31 18:00:27 +01002269 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002270 case YANG_VERSION_KEYWORD:
2271 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002272 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002273 break;
PavolVicanc1807262017-01-31 18:00:27 +01002274 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002275 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002276 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002277 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002278 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002279 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002280 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002281 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002282 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002283 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002284 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002285 break;
2286 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002287 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002288 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002289 break;
2290 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002291 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002292 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002293 break;
PavolVican171717d2017-02-01 14:49:55 +01002294 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002295 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002296 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002297 break;
2298 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002299 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002300 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002301 break;
PavolVican19dc6152017-02-06 12:04:15 +01002302 case YIN_ELEMENT_KEYWORD:
2303 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002304 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002305 break;
2306 case STATUS_KEYWORD:
2307 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002308 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002309 break;
PavolVican8fa31242017-02-07 11:04:26 +01002310 case BASE_KEYWORD:
2311 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002312 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002313 if (backup_type == IDENTITY_KEYWORD) {
2314 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002315 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002316 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2317 }
PavolVican8fa31242017-02-07 11:04:26 +01002318 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002319 case DEFAULT_KEYWORD:
2320 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002321 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002322 switch (backup_type) {
2323 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002324 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002325 break;
2326 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002327 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002328 break;
2329 case ADD_KEYWORD:
2330 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2331 break;
2332 default:
2333 /* nothing changes */
2334 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002335 }
PavolVicandf9e7972017-02-07 11:41:38 +01002336 break;
2337 case UNITS_KEYWORD:
2338 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002339 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002340 break;
PavolVican056fcd12017-02-07 15:36:53 +01002341 case REQUIRE_INSTANCE_KEYWORD:
2342 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002343 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002344 break;
2345 case PATH_KEYWORD:
2346 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002347 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002348 break;
2349 case ERROR_MESSAGE_KEYWORD:
2350 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002351 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002352 break;
2353 case ERROR_APP_TAG_KEYWORD:
2354 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002355 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002356 break;
2357 case MODIFIER_KEYWORD:
2358 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002359 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002360 break;
2361 case FRACTION_DIGITS_KEYWORD:
2362 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002363 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002364 break;
2365 case VALUE_KEYWORD:
2366 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002367 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002368 break;
2369 case POSITION_KEYWORD:
2370 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002371 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002372 break;
PavolVican5b910842017-02-08 13:08:47 +01002373 case PRESENCE_KEYWORD:
2374 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002375 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002376 break;
2377 case CONFIG_KEYWORD:
2378 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002379 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002380 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002381 case MANDATORY_KEYWORD:
2382 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002383 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002384 break;
2385 case MIN_ELEMENTS_KEYWORD:
2386 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002387 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002388 break;
2389 case MAX_ELEMENTS_KEYWORD:
2390 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002391 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002392 break;
2393 case ORDERED_BY_KEYWORD:
2394 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002395 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002396 break;
2397 case KEY_KEYWORD:
2398 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002399 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002400 break;
2401 case UNIQUE_KEYWORD:
2402 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002403 stmt = LY_STMT_UNIQUE;
2404 switch (backup_type) {
2405 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002406 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002407 break;
2408 case ADD_KEYWORD:
2409 case DELETE_KEYWORD:
2410 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002411 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002412 break;
2413 default:
2414 /* nothing changes */
2415 break;
PavolVican6f000922017-02-10 12:56:59 +01002416 }
PavolVican3feb2f92017-02-08 13:44:39 +01002417 break;
PavolVicanc1807262017-01-31 18:00:27 +01002418 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002419 LOGINT(module->ctx);
PavolVicanc1807262017-01-31 18:00:27 +01002420 return NULL;
2421 }
2422 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002423 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002424 if (!instance) {
2425 return NULL;
2426 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002427 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002428 switch (actual_type) {
2429 case ARGUMENT_KEYWORD:
2430 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002431 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002432 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002433 case BELONGS_TO_KEYWORD:
2434 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002435 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002436 break;
PavolVican19dc6152017-02-06 12:04:15 +01002437 default:
2438 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2439 break;
2440 }
PavolVicanc1807262017-01-31 18:00:27 +01002441 }
2442 instance->flags |= LYEXT_OPT_YANG;
2443 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2444 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002445 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2446 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2447 }
PavolVicanc1807262017-01-31 18:00:27 +01002448 return instance;
2449}
2450
PavolVican05c4f9b2017-09-07 13:33:54 +02002451static int
2452check_status_flag(struct lys_node *node, struct lys_node *parent)
2453{
Michal Vasko53b7da02018-02-13 15:28:42 +01002454 struct ly_ctx *ctx = node->module->ctx;
PavolVican05c4f9b2017-09-07 13:33:54 +02002455 char *str;
2456
Radek Krejcie4dce292017-10-30 11:16:47 +01002457 if (node->nodetype & (LYS_OUTPUT | LYS_INPUT)) {
2458 return EXIT_SUCCESS;
2459 }
2460
PavolVican05c4f9b2017-09-07 13:33:54 +02002461 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2462 /* status is not inherited by specification, but it not make sense to have
2463 * current in deprecated or deprecated in obsolete, so we print warning
2464 * and fix the schema by inheriting */
2465 if (!(node->flags & (LYS_STATUS_MASK))) {
2466 /* status not explicitely specified on the current node -> inherit */
Michal Vasko395b0a02018-01-22 09:36:20 +01002467 str = lys_path(node, LYS_PATH_FIRST_PREFIX);
Michal Vasko53b7da02018-02-13 15:28:42 +01002468 LOGWRN(ctx, "Missing status in %s subtree (%s), inheriting.",
PavolVican05c4f9b2017-09-07 13:33:54 +02002469 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2470 free(str);
2471 node->flags |= parent->flags & LYS_STATUS_MASK;
2472 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2473 /* invalid combination of statuses */
2474 switch (node->flags & LYS_STATUS_MASK) {
2475 case 0:
2476 case LYS_STATUS_CURR:
Michal Vasko53b7da02018-02-13 15:28:42 +01002477 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002478 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2479 break;
2480 case LYS_STATUS_DEPRC:
Michal Vasko53b7da02018-02-13 15:28:42 +01002481 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002482 "obsolete", parent->name);
2483 break;
2484 }
2485 return EXIT_FAILURE;
2486 }
2487 }
2488
2489 return EXIT_SUCCESS;
2490}
2491
Pavol Vicanf4717e62016-03-16 11:30:01 +01002492int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002493store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002494{
Pavol Vicanec598812016-11-30 14:13:38 +01002495 switch (node->nodetype) {
2496 case LYS_CONTAINER:
2497 case LYS_LEAF:
2498 case LYS_LEAFLIST:
2499 case LYS_LIST:
2500 case LYS_CHOICE:
2501 case LYS_ANYDATA:
2502 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002503 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002504 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002505 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002506 if (!(node->flags & LYS_CONFIG_MASK)) {
2507 /* get config flag from parent */
2508 if (node->parent) {
2509 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2510 } else {
2511 /* default config is true */
2512 node->flags |= LYS_CONFIG_W;
2513 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002514 }
2515 }
Pavol Vicanec598812016-11-30 14:13:38 +01002516 break;
2517 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002518 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002519 if (!(node->flags & LYS_CONFIG_MASK)) {
2520 /* get config flag from parent */
2521 if (node->parent) {
2522 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2523 } else {
2524 /* default config is true */
2525 node->flags |= LYS_CONFIG_W;
2526 }
2527 }
2528 }
2529 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002530 default:
2531 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002532 }
Pavol Vicanec598812016-11-30 14:13:38 +01002533
Radek Krejci7212e0a2017-03-08 15:58:22 +01002534 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002535}
2536
2537int
Pavol Vican9d50a772016-10-14 22:23:36 +02002538yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2539 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002540{
Pavol Vican974377b2016-03-23 00:38:53 +01002541 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002542 YY_BUFFER_STATE bp;
2543 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002544 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002545 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002546 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002547
Pavol Vican8e7110b2016-03-22 17:00:26 +01002548 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002549 yylex_init(&scanner);
Michal Vasko53b7da02018-02-13 15:28:42 +01002550 yyset_extra(module->ctx, scanner);
Pavol Vican4fb66c92016-03-17 10:32:27 +01002551 bp = yy_scan_buffer((char *)data, size, scanner);
2552 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002553 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002554 param.module = module;
2555 param.submodule = submodule;
2556 param.unres = unres;
2557 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002558 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002559 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002560 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002561 trg = (submodule) ? (struct lys_module *)submodule : module;
2562 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2563 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2564 trg->inc_size = 0;
2565 trg->imp_size = 0;
2566 }
PavolVican22e88682017-02-14 22:38:18 +01002567 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2568 }
2569 yy_delete_buffer(bp, scanner);
2570 yylex_destroy(scanner);
2571 return ret;
2572}
2573
2574int
2575yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2576 char *ext_name, struct lys_ext_instance_complex *ext)
2577{
2578 unsigned int size;
2579 YY_BUFFER_STATE bp;
2580 yyscan_t scanner = NULL;
2581 int ret = 0;
2582 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002583 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002584
PavolVicandb0e8172017-02-20 00:46:09 +01002585 if (!data) {
2586 return EXIT_SUCCESS;
2587 }
PavolVican22e88682017-02-14 22:38:18 +01002588 size = strlen(data) + 2;
2589 yylex_init(&scanner);
2590 bp = yy_scan_buffer((char *)data, size, scanner);
2591 yy_switch_to_buffer(bp, scanner);
2592 memset(&param, 0, sizeof param);
2593 param.module = module;
2594 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002595 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002596 param.actual_node = (void **)ext;
2597 param.data_node = (void **)ext_name;
2598 param.flags |= EXT_INSTANCE_SUBSTMT;
2599 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002600 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002601 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002602 } else {
2603 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002604 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002605 ret = -1;
2606 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002607 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002608 yy_delete_buffer(bp, scanner);
2609 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002610 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002611}
2612
2613struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002614yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002615{
2616
PavolVican9e81c6a2017-02-09 13:09:07 +01002617 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002618 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002619 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002620 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002621
2622 unres = calloc(1, sizeof *unres);
Michal Vasko53b7da02018-02-13 15:28:42 +01002623 LY_CHECK_ERR_GOTO(!unres, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002624
2625 module = calloc(1, sizeof *module);
Michal Vasko53b7da02018-02-13 15:28:42 +01002626 LY_CHECK_ERR_GOTO(!module, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002627
2628 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002629 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002630 module->type = 0;
2631 module->implemented = (implement ? 1 : 0);
2632
Radek Krejci9e757e02017-03-08 17:18:09 +01002633 /* add into the list of processed modules */
2634 if (lyp_check_circmod_add(module)) {
2635 goto error;
2636 }
2637
PavolVican9e81c6a2017-02-09 13:09:07 +01002638 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2639 if (ret == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002640 if (ly_vecode(ctx) == LYVE_SUBMODULE) {
Radek Krejci95e00a42017-11-02 16:29:22 +01002641 free(module);
2642 module = NULL;
2643 } else {
2644 free_yang_common(module, node);
2645 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002646 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002647 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002648 assert(!unres->count);
2649 } else {
2650 if (yang_check_sub_module(module, unres, node)) {
2651 goto error;
2652 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002653
Michal Vasko0f437062018-06-08 15:52:39 +02002654 if (!implement && module->implemented && lys_make_implemented_r(module, unres)) {
2655 goto error;
2656 }
2657
Michal Vasko7b460e52017-02-10 14:50:26 +01002658 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002659 goto error;
2660 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002661 }
2662
PavolVicanfe83b152017-02-19 03:19:29 +01002663 lyp_sort_revisions(module);
2664
Pavol Vican8e7110b2016-03-22 17:00:26 +01002665 if (revision) {
2666 /* check revision of the parsed model */
2667 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2668 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2669 module->name, module->rev[0].date, revision);
2670 goto error;
2671 }
2672 }
2673
PavolVican9e81c6a2017-02-09 13:09:07 +01002674 /* add into context if not already there */
2675 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002676 /* check correctness of includes */
2677 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002678 goto error;
2679 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002680
PavolVican6f000922017-02-10 12:56:59 +01002681 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002682 goto error;
2683 }
2684
PavolVican9e81c6a2017-02-09 13:09:07 +01002685 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002686 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002687 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002688
Michal Vasko10681e82018-01-16 14:54:16 +01002689 /* remove our submodules from the parsed submodules list */
2690 lyp_del_includedup(module, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002691 } else {
2692 tmp_mod = module;
2693
2694 /* get the model from the context */
Radek Krejcidfb00d62017-09-06 09:39:35 +02002695 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002696 assert(module);
2697
2698 /* free what was parsed */
Michal Vasko10681e82018-01-16 14:54:16 +01002699 lys_free(tmp_mod, NULL, 0, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002700 }
2701
Radek Krejci9e757e02017-03-08 17:18:09 +01002702 lyp_check_circmod_pop(ctx);
Michal Vasko181b7672018-04-23 12:03:44 +02002703 unres_schema_free(NULL, &unres, 0);
Michal Vaskobe136f62017-09-21 12:08:39 +02002704 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2705 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002706 return module;
2707
2708error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002709 /* cleanup */
Michal Vasko181b7672018-04-23 12:03:44 +02002710 lyp_check_circmod_pop(ctx);
Michal Vasko44ab1462017-05-18 13:18:36 +02002711 unres_schema_free(module, &unres, 1);
Radek Krejcif505cd12017-06-13 10:32:48 +02002712 if (!module) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002713 if (ly_vecode(ctx) != LYVE_SUBMODULE) {
2714 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002715 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002716 return NULL;
2717 }
2718
Radek Krejcif505cd12017-06-13 10:32:48 +02002719 if (module->name) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002720 LOGERR(ctx, ly_errno, "Module \"%s\" parsing failed.", module->name);
Radek Krejcif505cd12017-06-13 10:32:48 +02002721 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01002722 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejcif505cd12017-06-13 10:32:48 +02002723 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002724
2725 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);
3226 }
3227
3228 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3229 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3230 }
3231 free(dev->deviate[i].dflt);
3232
3233 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003234 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003235 }
3236 free(dev->deviate[i].must);
3237
3238 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3239 free(dev->deviate[i].unique[j].expr);
3240 }
3241 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003242 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003243 }
3244}
3245
PavolVicandb0e8172017-02-20 00:46:09 +01003246void
3247yang_free_ext_data(struct yang_ext_substmt *substmt)
3248{
3249 int i;
3250
3251 if (!substmt) {
3252 return;
3253 }
3254
3255 free(substmt->ext_substmt);
3256 if (substmt->ext_modules) {
3257 for (i = 0; substmt->ext_modules[i]; ++i) {
3258 free(substmt->ext_modules[i]);
3259 }
3260 free(substmt->ext_modules);
3261 }
3262 free(substmt);
3263}
3264
Pavol Vican7313fc02016-11-14 01:10:31 +01003265/* free common item from module and submodule */
3266static void
Pavol Vican05810b62016-11-23 14:07:22 +01003267free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003268{
PavolVican75af21d2016-12-29 20:04:07 +01003269 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003270 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3271 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003272 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003273 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003274 for (i = 0; i < module->augment_size; ++i) {
3275 yang_free_augment(module->ctx, &module->augment[i]);
3276 }
3277 module->augment_size = 0;
3278 for (i = 0; i < module->deviation_size; ++i) {
3279 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3280 free(module->deviation[i].deviate);
David Sedlák437ec402018-08-13 09:07:10 +02003281 lydict_remove(module->ctx, module->deviation[i].target_name);
3282 lydict_remove(module->ctx, module->deviation[i].dsc);
3283 lydict_remove(module->ctx, module->deviation[i].ref);
PavolVican75af21d2016-12-29 20:04:07 +01003284 }
3285 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003286}
3287
Pavol Vican1cc4e192016-10-24 16:38:31 +02003288/* check function*/
3289
3290int
PavolVicanc1807262017-01-31 18:00:27 +01003291yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3292 void *parent, struct unres_schema *unres)
3293{
3294 struct unres_ext *info;
3295 uint i;
3296
3297 for (i = 0; i < size; ++i) {
3298 info = malloc(sizeof *info);
Michal Vasko53b7da02018-02-13 15:28:42 +01003299 LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003300 info->data.yang = (*ext)[i]->parent;
3301 info->datatype = LYS_IN_YANG;
3302 info->parent = parent;
3303 info->mod = module;
3304 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003305 info->substmt = (*ext)[i]->insubstmt;
3306 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003307 info->ext_index = i;
3308 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3309 return EXIT_FAILURE;
3310 }
3311 }
3312
3313 return EXIT_SUCCESS;
3314}
3315
3316int
Pavol Vicanec423c92016-10-24 21:33:43 +02003317yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003318{
3319 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003320 struct lys_include *inc;
3321 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003322 char *s;
3323
3324 imp = module->imp;
3325 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003326 inc = module->inc;
3327 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003328
3329 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003330 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003331 module->imp_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003332 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM(module->ctx), error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003333 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003334
Pavol Vicanec423c92016-10-24 21:33:43 +02003335 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003336 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003337 module->inc_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003338 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM(module->ctx), error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003339 }
3340
3341 for (i = 0; i < imp_size; ++i) {
3342 s = (char *) imp[i].module;
3343 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003344 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003345 ++i;
3346 goto error;
3347 }
3348 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003349 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003350 s = (char *) inc[j].submodule;
3351 inc[j].submodule = NULL;
3352 if (yang_fill_include(module, s, &inc[j], unres)) {
3353 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003354 goto error;
3355 }
3356 }
3357 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003358 free(imp);
3359
3360 return EXIT_SUCCESS;
3361
3362error:
3363 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003364 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003365 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003366 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003367 return EXIT_FAILURE;
3368}
Pavol Vican7313fc02016-11-14 01:10:31 +01003369
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003370static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003371yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003372{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003373 struct lys_iffeature *iffeature;
3374 uint8_t *ptr_size, size, i;
3375 char *s;
3376 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003377
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003378 switch (type) {
3379 case FEATURE_KEYWORD:
3380 iffeature = ((struct lys_feature *)parent)->iffeature;
3381 size = ((struct lys_feature *)parent)->iffeature_size;
3382 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3383 parent_is_feature = 1;
3384 break;
3385 case IDENTITY_KEYWORD:
3386 iffeature = ((struct lys_ident *)parent)->iffeature;
3387 size = ((struct lys_ident *)parent)->iffeature_size;
3388 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3389 break;
3390 case ENUM_KEYWORD:
3391 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3392 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3393 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3394 break;
3395 case BIT_KEYWORD:
3396 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3397 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3398 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3399 break;
3400 case REFINE_KEYWORD:
3401 iffeature = ((struct lys_refine *)ptr)->iffeature;
3402 size = ((struct lys_refine *)ptr)->iffeature_size;
3403 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3404 break;
3405 default:
3406 iffeature = ((struct lys_node *)parent)->iffeature;
3407 size = ((struct lys_node *)parent)->iffeature_size;
3408 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3409 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003410 }
3411
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003412 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003413 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003414 s = (char *)iffeature[i].features;
3415 iffeature[i].features = NULL;
3416 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3417 *ptr_size = size;
3418 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003419 }
PavolVican8fa31242017-02-07 11:04:26 +01003420 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3421 *ptr_size = size;
3422 return EXIT_FAILURE;
3423 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003424 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003425 }
3426
3427 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003428}
3429
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003430static int
3431yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3432{
3433 uint size, i;
3434 int rc;
3435 struct lys_ident **ref;
3436 const char *value;
3437 char *expr;
3438
3439 ref = type->info.ident.ref;
3440 size = type->info.ident.count;
3441 type->info.ident.count = 0;
3442 type->info.ident.ref = NULL;
3443 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3444
3445 for (i = 0; i < size; ++i) {
3446 expr = (char *)ref[i];
3447 /* store in the JSON format */
3448 value = transform_schema2json(module, expr);
3449 free(expr);
3450
3451 if (!value) {
3452 goto error;
3453 }
3454 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3455 lydict_remove(module->ctx, value);
3456
3457 if (rc == -1) {
3458 goto error;
3459 }
3460 }
3461 free(ref);
3462
3463 return EXIT_SUCCESS;
3464error:
3465 for (i = i+1; i < size; ++i) {
3466 free(ref[i]);
3467 }
3468 free(ref);
3469 return EXIT_FAILURE;
3470}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003471
Pavol Vican7313fc02016-11-14 01:10:31 +01003472int
PavolVican056fcd12017-02-07 15:36:53 +01003473yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3474 void *parent, struct unres_schema *unres)
3475{
PavolVican92f23622017-12-12 13:35:56 +01003476 unsigned int i, j;
PavolVican056fcd12017-02-07 15:36:53 +01003477
3478 type->parent = parent;
3479 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3480 return EXIT_FAILURE;
3481 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003482 for (j = 0; j < type->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003483 if (type->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003484 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003485 break;
3486 }
3487 }
3488
PavolVican056fcd12017-02-07 15:36:53 +01003489 switch (stype->base) {
3490 case LY_TYPE_ENUM:
3491 for (i = 0; i < type->info.enums.count; ++i) {
3492 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3493 return EXIT_FAILURE;
3494 }
3495 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3496 &type->info.enums.enm[i], unres)) {
3497 return EXIT_FAILURE;
3498 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003499 for (j = 0; j < type->info.enums.enm[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003500 if (type->info.enums.enm[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003501 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003502 break;
3503 }
3504 }
PavolVican056fcd12017-02-07 15:36:53 +01003505 }
3506 break;
3507 case LY_TYPE_BITS:
3508 for (i = 0; i < type->info.bits.count; ++i) {
3509 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3510 return EXIT_FAILURE;
3511 }
3512 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3513 &type->info.bits.bit[i], unres)) {
3514 return EXIT_FAILURE;
3515 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003516 for (j = 0; j < type->info.bits.bit[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003517 if (type->info.bits.bit[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003518 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003519 break;
3520 }
3521 }
PavolVican056fcd12017-02-07 15:36:53 +01003522 }
3523 break;
3524 case LY_TYPE_IDENT:
3525 if (yang_check_identityref(module, type, unres)) {
3526 return EXIT_FAILURE;
3527 }
3528 break;
3529 case LY_TYPE_STRING:
PavolVican92f23622017-12-12 13:35:56 +01003530 if (type->info.str.length) {
3531 if (yang_check_ext_instance(module, &type->info.str.length->ext,
3532 type->info.str.length->ext_size, type->info.str.length, unres)) {
3533 return EXIT_FAILURE;
3534 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003535 for (j = 0; j < type->info.str.length->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003536 if (type->info.str.length->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003537 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003538 break;
3539 }
3540 }
PavolVican056fcd12017-02-07 15:36:53 +01003541 }
PavolVican92f23622017-12-12 13:35:56 +01003542
PavolVican056fcd12017-02-07 15:36:53 +01003543 for (i = 0; i < type->info.str.pat_count; ++i) {
3544 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3545 &type->info.str.patterns[i], unres)) {
3546 return EXIT_FAILURE;
3547 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003548 for (j = 0; j < type->info.str.patterns[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003549 if (type->info.str.patterns[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003550 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003551 break;
3552 }
3553 }
PavolVican056fcd12017-02-07 15:36:53 +01003554 }
3555 break;
3556 case LY_TYPE_DEC64:
PavolVican92f23622017-12-12 13:35:56 +01003557 if (type->info.dec64.range) {
3558 if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
3559 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3560 return EXIT_FAILURE;
3561 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003562 for (j = 0; j < type->info.dec64.range->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003563 if (type->info.dec64.range->ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003564 type->parent->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003565 break;
3566 }
3567 }
PavolVican056fcd12017-02-07 15:36:53 +01003568 }
3569 break;
3570 case LY_TYPE_UNION:
3571 for (i = 0; i < type->info.uni.count; ++i) {
3572 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3573 parent, unres)) {
3574 return EXIT_FAILURE;
3575 }
3576 }
Radek Krejci57b41682017-03-07 12:33:24 +01003577 break;
PavolVican056fcd12017-02-07 15:36:53 +01003578 default:
3579 /* nothing checks */
3580 break;
3581 }
3582 return EXIT_SUCCESS;
3583}
3584
3585int
Pavol Vican7313fc02016-11-14 01:10:31 +01003586yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3587{
3588 struct lys_tpdf *tpdf;
Radek Krejcidaa547a2017-09-22 15:56:27 +02003589 uint8_t *ptr_tpdf_size = NULL;
PavolVican92f23622017-12-12 13:35:56 +01003590 uint16_t j, i, tpdf_size, *ptr_tpdf_size16 = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01003591
3592 if (!parent) {
3593 tpdf = module->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003594 //ptr_tpdf_size = &module->tpdf_size;
3595 ptr_tpdf_size16 = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003596 } else {
3597 switch (parent->nodetype) {
3598 case LYS_GROUPING:
3599 tpdf = ((struct lys_node_grp *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003600 ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003601 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003602 case LYS_CONTAINER:
3603 tpdf = ((struct lys_node_container *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003604 ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003605 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003606 case LYS_LIST:
3607 tpdf = ((struct lys_node_list *)parent)->tpdf;
3608 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3609 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003610 case LYS_RPC:
3611 case LYS_ACTION:
3612 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003613 ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003614 break;
Pavol Vican78729392016-11-28 17:18:22 +01003615 case LYS_INPUT:
3616 case LYS_OUTPUT:
3617 tpdf = ((struct lys_node_inout *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003618 ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
Pavol Vican78729392016-11-28 17:18:22 +01003619 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003620 case LYS_NOTIF:
3621 tpdf = ((struct lys_node_notif *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003622 ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
Pavol Vican29bf8802016-11-28 20:44:57 +01003623 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003624 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01003625 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01003626 return EXIT_FAILURE;
3627 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003628 }
3629
Radek Krejcia2ac9262017-09-12 16:39:04 +02003630 if (ptr_tpdf_size16) {
3631 tpdf_size = *ptr_tpdf_size16;
3632 *ptr_tpdf_size16 = 0;
3633 } else {
3634 tpdf_size = *ptr_tpdf_size;
3635 *ptr_tpdf_size = 0;
3636 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003637
3638 for (i = 0; i < tpdf_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003639 if (lyp_check_identifier(module->ctx, tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003640 goto error;
3641 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003642
PavolVican056fcd12017-02-07 15:36:53 +01003643 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3644 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003645 }
PavolVicandf9e7972017-02-07 11:41:38 +01003646 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3647 goto error;
3648 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003649 for (j = 0; j < tpdf[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003650 if (tpdf[i].ext[j]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01003651 tpdf[i].flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01003652 break;
3653 }
3654 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003655 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003656 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003657 }
3658
Radek Krejcia2ac9262017-09-12 16:39:04 +02003659 if (ptr_tpdf_size16) {
3660 (*ptr_tpdf_size16)++;
3661 } else {
3662 (*ptr_tpdf_size)++;
3663 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003664 /* check default value*/
Michal Vasko15a43372017-09-25 14:12:42 +02003665 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3666 && 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 +01003667 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003668 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003669 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003670 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003671
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003672 return EXIT_SUCCESS;
3673
3674error:
3675 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3676 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003677}
3678
3679static int
Pavol Vican36e27272016-11-22 15:47:28 +01003680yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3681{
3682 uint32_t i, size, base_size;
3683 uint8_t j;
3684
3685 size = module->ident_size;
3686 module->ident_size = 0;
3687 for (i = 0; i < size; ++i) {
3688 base_size = module->ident[i].base_size;
3689 module->ident[i].base_size = 0;
3690 for (j = 0; j < base_size; ++j) {
3691 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3692 ++j;
3693 module->ident_size = size;
3694 goto error;
3695 }
3696 }
3697 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003698 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3699 goto error;
3700 }
PavolVican8fa31242017-02-07 11:04:26 +01003701 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3702 goto error;
3703 }
Pavol Vican36e27272016-11-22 15:47:28 +01003704 }
3705
3706 return EXIT_SUCCESS;
3707
3708error:
3709 for (; j< module->ident[i].base_size; ++j) {
3710 free(module->ident[i].base[j]);
3711 }
3712 yang_free_ident_base(module->ident, i + 1, size);
3713 return EXIT_FAILURE;
3714}
3715
3716static int
PavolVican38104a32017-02-08 12:25:23 +01003717yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3718{
3719 uint i;
3720
3721 for (i = 0; i < size; ++i) {
3722 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3723 return EXIT_FAILURE;
3724 }
3725 }
3726 return EXIT_SUCCESS;
3727}
3728
3729static int
PavolVicane87cb932016-12-30 15:36:18 +01003730yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003731 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003732{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003733 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003734 goto error;
3735 }
3736
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003737 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003738 goto error;
3739 }
3740
Radek Krejci7212e0a2017-03-08 15:58:22 +01003741 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003742 *child = NULL;
3743 goto error;
3744 }
3745 *child = NULL;
3746
PavolVican59ba4602017-02-08 11:53:32 +01003747 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3748 goto error;
3749 }
PavolVican38104a32017-02-08 12:25:23 +01003750 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3751 goto error;
3752 }
3753
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003754 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003755 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003756 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003757 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003758 goto error;
3759 }
3760 } else {
3761 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3762 goto error;
3763 }
3764 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003765 }
3766
3767 return EXIT_SUCCESS;
3768error:
Michal Vasko53b7da02018-02-13 15:28:42 +01003769
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003770 return EXIT_FAILURE;
3771}
3772
3773static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003774yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003775{
PavolVican056fcd12017-02-07 15:36:53 +01003776 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003777 yang_type_free(module->ctx, &leaf->type);
3778 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003779 }
PavolVicana08d3652016-12-29 21:07:47 +01003780 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3781 yang_type_free(module->ctx, &leaf->type);
3782 goto error;
3783 }
3784
Pavol Vicanfda8c802016-12-03 02:00:42 +01003785 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003786 yang_type_free(module->ctx, &leaf->type);
3787 goto error;
3788 }
3789
Michal Vasko6a057782018-03-09 13:24:33 +01003790 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003791 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003792 goto error;
3793 }
3794
PavolVican59ba4602017-02-08 11:53:32 +01003795 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3796 goto error;
3797 }
PavolVican38104a32017-02-08 12:25:23 +01003798 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3799 goto error;
3800 }
Michal Vasko89afc112017-03-16 13:57:28 +01003801
Pavol Vicana69aff22016-11-24 18:23:50 +01003802 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003803 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003804 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003805 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003806 goto error;
3807 }
3808 } else {
3809 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3810 goto error;
3811 }
3812 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003813 }
3814
3815 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003816
Pavol Vicana69aff22016-11-24 18:23:50 +01003817error:
3818 return EXIT_FAILURE;
3819}
3820
3821static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003822yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3823 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003824{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003825 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003826
PavolVican056fcd12017-02-07 15:36:53 +01003827 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003828 yang_type_free(module->ctx, &leaflist->type);
3829 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003830 }
PavolVicana08d3652016-12-29 21:07:47 +01003831 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3832 yang_type_free(module->ctx, &leaflist->type);
3833 goto error;
3834 }
3835
Pavol Vicanfda8c802016-12-03 02:00:42 +01003836 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003837 yang_type_free(module->ctx, &leaflist->type);
3838 goto error;
3839 }
3840
Pavol Vican36aff862016-11-26 17:07:05 +01003841 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003842 /* check for duplicity in case of configuration data,
3843 * in case of status data duplicities are allowed */
3844 if (leaflist->flags & LYS_CONFIG_W) {
3845 for (j = i +1; j < leaflist->dflt_size; ++j) {
3846 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003847 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3848 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003849 goto error;
3850 }
3851 }
3852 }
3853 /* check default value (if not defined, there still could be some restrictions
3854 * that need to be checked against a default value from a derived type) */
Michal Vasko6a057782018-03-09 13:24:33 +01003855 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003856 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3857 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003858 goto error;
3859 }
3860 }
3861
PavolVican59ba4602017-02-08 11:53:32 +01003862 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3863 goto error;
3864 }
PavolVican38104a32017-02-08 12:25:23 +01003865 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3866 goto error;
3867 }
PavolVican59ba4602017-02-08 11:53:32 +01003868
Pavol Vican36aff862016-11-26 17:07:05 +01003869 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003870 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003871 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003872 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003873 goto error;
3874 }
3875 } else {
3876 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3877 goto error;
3878 }
3879 }
Pavol Vican36aff862016-11-26 17:07:05 +01003880 }
3881
3882 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003883
Pavol Vican36aff862016-11-26 17:07:05 +01003884error:
3885 return EXIT_FAILURE;
3886}
3887
3888static int
PavolVicane87cb932016-12-30 15:36:18 +01003889yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003890 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003891{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003892 struct lys_node *node;
3893
Pavol Vicand8136a42016-11-27 13:28:04 +01003894 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3895 goto error;
3896 }
3897
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003898 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3899 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003900 }
3901
Pavol Vicanfda8c802016-12-03 02:00:42 +01003902 if (list->flags & LYS_CONFIG_R) {
3903 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3904 * ignore oredering MASK - 0x7F
3905 */
3906 list->flags &= 0x7F;
3907 }
3908 /* check - if list is configuration, key statement is mandatory
3909 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003910 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 +01003911 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003912 LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
Pavol Vicanfda8c802016-12-03 02:00:42 +01003913 goto error;
3914 }
3915
Radek Krejci7212e0a2017-03-08 15:58:22 +01003916 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003917 *child = NULL;
3918 goto error;
3919 }
3920 *child = NULL;
3921
Pavol Vicand8136a42016-11-27 13:28:04 +01003922 if (list->keys && yang_read_key(module, list, unres)) {
3923 goto error;
3924 }
3925
3926 if (yang_read_unique(module, list, unres)) {
3927 goto error;
3928 }
3929
PavolVican59ba4602017-02-08 11:53:32 +01003930 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3931 goto error;
3932 }
PavolVican38104a32017-02-08 12:25:23 +01003933 if (yang_check_must(module, list->must, list->must_size, unres)) {
3934 goto error;
3935 }
Michal Vasko89afc112017-03-16 13:57:28 +01003936
Pavol Vicand8136a42016-11-27 13:28:04 +01003937 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003938 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003939 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003940 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003941 goto error;
3942 }
3943 } else {
3944 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3945 goto error;
3946 }
3947 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003948 }
3949
3950 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003951
Pavol Vicand8136a42016-11-27 13:28:04 +01003952error:
3953 return EXIT_FAILURE;
3954}
3955
3956static int
PavolVicane87cb932016-12-30 15:36:18 +01003957yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003958 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003959{
3960 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003961
PavolVicana08d3652016-12-29 21:07:47 +01003962 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3963 free(choice->dflt);
3964 choice->dflt = NULL;
3965 goto error;
3966 }
3967
Radek Krejci7212e0a2017-03-08 15:58:22 +01003968 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003969 *child = NULL;
3970 free(choice->dflt);
3971 choice->dflt = NULL;
3972 goto error;
3973 }
3974 *child = NULL;
3975
Pavol Vican36ace102016-11-28 11:46:59 +01003976 if (choice->dflt) {
3977 value = (char *)choice->dflt;
3978 choice->dflt = NULL;
3979 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3980 free(value);
3981 goto error;
3982 }
3983 free(value);
3984 }
3985
PavolVican59ba4602017-02-08 11:53:32 +01003986 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3987 goto error;
3988 }
3989
Pavol Vican36ace102016-11-28 11:46:59 +01003990 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003991 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01003992 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003993 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003994 goto error;
3995 }
3996 } else {
3997 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3998 goto error;
3999 }
4000 }
Pavol Vican36ace102016-11-28 11:46:59 +01004001 }
4002
4003 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004004
Pavol Vican36ace102016-11-28 11:46:59 +01004005error:
4006 return EXIT_FAILURE;
4007}
4008
4009static int
PavolVicane87cb932016-12-30 15:36:18 +01004010yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004011 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004012{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004013 struct lys_node *node;
4014
4015 if (rpc->nodetype == LYS_ACTION) {
4016 for (node = rpc->parent; node; node = lys_parent(node)) {
4017 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01004018 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004019 LOGVAL(module->ctx, LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004020 goto error;
4021 }
4022 }
4023 }
4024 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
4025 goto error;
4026 }
4027
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004028 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
4029 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004030 }
4031
Radek Krejci7212e0a2017-03-08 15:58:22 +01004032 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004033 *child = NULL;
4034 goto error;
4035 }
4036 *child = NULL;
4037
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004038 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004039
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004040error:
4041 return EXIT_FAILURE;
4042}
4043
4044static int
PavolVicane87cb932016-12-30 15:36:18 +01004045yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004046 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01004047{
Pavol Vican29bf8802016-11-28 20:44:57 +01004048 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
4049 goto error;
4050 }
4051
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004052 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
4053 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01004054 }
4055
Radek Krejci7212e0a2017-03-08 15:58:22 +01004056 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004057 *child = NULL;
4058 goto error;
4059 }
4060 *child = NULL;
4061
Michal Vasko89afc112017-03-16 13:57:28 +01004062 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
4063 goto error;
4064 }
4065
4066 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004067 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01004068 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004069 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004070 goto error;
4071 }
4072 } else {
4073 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
4074 goto error;
4075 }
PavolVican38104a32017-02-08 12:25:23 +01004076 }
Pavol Vican29bf8802016-11-28 20:44:57 +01004077 }
4078
4079 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004080
Pavol Vican29bf8802016-11-28 20:44:57 +01004081error:
4082 return EXIT_FAILURE;
4083}
4084
4085static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004086yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004087{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004088 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004089
Pavol Vican3ad50f82016-12-04 15:00:36 +01004090 child = augment->child;
4091 augment->child = NULL;
4092
PavolVicana08d3652016-12-29 21:07:47 +01004093 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4094 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004095 goto error;
4096 }
4097
Radek Krejci7212e0a2017-03-08 15:58:22 +01004098 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004099 goto error;
4100 }
4101
PavolVicanfa9510e2017-02-08 17:20:46 +01004102 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4103 goto error;
4104 }
4105
PavolVican59ba4602017-02-08 11:53:32 +01004106 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4107 goto error;
4108 }
4109
Pavol Vican3ad50f82016-12-04 15:00:36 +01004110 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004111 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004112 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004113 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004114 goto error;
4115 }
4116 } else {
4117 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4118 goto error;
4119 }
4120 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004121 }
4122
4123 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004124
Pavol Vican3ad50f82016-12-04 15:00:36 +01004125error:
4126 return EXIT_FAILURE;
4127}
4128
4129static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004130yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004131{
4132 uint i, size;
4133
4134 size = uses->augment_size;
4135 uses->augment_size = 0;
4136
4137 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004138 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004139 }
4140
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004141 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004142 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4143 goto error;
4144 }
4145 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4146 goto error;
4147 }
4148 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 +01004149 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004150 }
4151 }
4152
Pavol Vican3ad50f82016-12-04 15:00:36 +01004153 for (i = 0; i < size; ++i) {
4154 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004155 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004156 goto error;
4157 }
4158 }
4159
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004160 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4161 goto error;
4162 }
4163
PavolVican59ba4602017-02-08 11:53:32 +01004164 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4165 goto error;
4166 }
4167
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004168 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004169 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004170 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004171 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004172 goto error;
4173 }
4174 } else {
4175 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4176 goto error;
4177 }
4178 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004179 }
4180
4181 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004182
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004183error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004184 for (i = uses->augment_size; i < size; ++i) {
4185 yang_free_augment(module->ctx, &uses->augment[i]);
4186 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004187 return EXIT_FAILURE;
4188}
4189
4190static int
PavolVican59ba4602017-02-08 11:53:32 +01004191yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004192 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004193{
4194 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4195 goto error;
4196 }
4197
Radek Krejci7212e0a2017-03-08 15:58:22 +01004198 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004199 *child = NULL;
4200 goto error;
4201 }
4202 *child = NULL;
4203
4204 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4205 goto error;
4206 }
PavolVican38104a32017-02-08 12:25:23 +01004207 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4208 goto error;
4209 }
PavolVican59ba4602017-02-08 11:53:32 +01004210
4211 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004212 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004213 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004214 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004215 goto error;
4216 }
4217 } else {
4218 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4219 goto error;
4220 }
4221 }
PavolVican59ba4602017-02-08 11:53:32 +01004222 }
Michal Vasko89afc112017-03-16 13:57:28 +01004223
PavolVican59ba4602017-02-08 11:53:32 +01004224 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004225
PavolVican59ba4602017-02-08 11:53:32 +01004226error:
4227 return EXIT_FAILURE;
4228}
4229
4230static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004231yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004232 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004233{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004234 struct lys_node *node = nodes, *sibling, *child;
PavolVican92f23622017-12-12 13:35:56 +01004235 int i;
Pavol Vican05810b62016-11-23 14:07:22 +01004236
4237 while (node) {
4238 sibling = node->next;
4239 child = node->child;
4240 node->next = NULL;
4241 node->child = NULL;
PavolVicanbd1d1ae2017-07-20 00:06:00 +02004242 node->parent = NULL;
Pavol Vican05810b62016-11-23 14:07:22 +01004243 node->prev = node;
4244
PavolVican05c4f9b2017-09-07 13:33:54 +02004245 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node) ||
4246 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004247 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004248 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004249 goto error;
4250 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004251 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004252 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4253 goto error;
4254 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01004255 for (i = 0; i < node->ext_size; ++i) {
PavolVican92f23622017-12-12 13:35:56 +01004256 if (node->ext[i]->flags & LYEXT_OPT_VALID) {
Michal Vasko1bdfd432018-03-09 09:30:19 +01004257 node->flags |= LYS_VALID_EXT;
PavolVican92f23622017-12-12 13:35:56 +01004258 break;
4259 }
4260 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004261
Pavol Vican05810b62016-11-23 14:07:22 +01004262 switch (node->nodetype) {
4263 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004264 if (yang_check_typedef(module, node, unres)) {
4265 goto error;
4266 }
4267 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004268 goto error;
4269 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004270 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004271 child = NULL;
4272 goto error;
4273 }
Pavol Vican05810b62016-11-23 14:07:22 +01004274 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004275 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004276 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004277 goto error;
4278 }
4279 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004280 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004281 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004282 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004283 goto error;
4284 }
4285 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004286 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004287 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004288 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004289 goto error;
4290 }
4291 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004292 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004293 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004294 goto error;
4295 }
4296 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004297 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004298 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004299 goto error;
4300 }
4301 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004302 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004303 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004304 goto error;
4305 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004306 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004307 child = NULL;
4308 goto error;
4309 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004310 if (((struct lys_node_case *)node)->when) {
4311 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4312 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4313 goto error;
4314 }
4315 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004316 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004317 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004318 goto error;
4319 }
4320 } else {
4321 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4322 goto error;
4323 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004324 }
4325 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004326 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004327 case LYS_ANYDATA:
4328 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004329 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004330 goto error;
4331 }
4332 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004333 case LYS_RPC:
4334 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004335 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004336 goto error;
4337 }
4338 break;
Pavol Vican78729392016-11-28 17:18:22 +01004339 case LYS_INPUT:
4340 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004341 if (yang_check_typedef(module, node, unres)) {
4342 goto error;
4343 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004344 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004345 child = NULL;
4346 goto error;
4347 }
PavolVican38104a32017-02-08 12:25:23 +01004348 if (((struct lys_node_inout *)node)->must_size) {
4349 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4350 goto error;
4351 }
4352 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004353 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004354 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004355 goto error;
4356 }
4357 } else {
4358 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4359 goto error;
4360 }
PavolVican38104a32017-02-08 12:25:23 +01004361 }
Pavol Vican78729392016-11-28 17:18:22 +01004362 }
Pavol Vican78729392016-11-28 17:18:22 +01004363 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004364 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004365 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004366 goto error;
4367 }
4368 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004369 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004370 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004371 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004372 goto error;
4373 }
4374 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004375 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01004376 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01004377 goto error;
4378 }
Pavol Vican05810b62016-11-23 14:07:22 +01004379 node = sibling;
4380 }
4381
4382 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004383
Pavol Vican05810b62016-11-23 14:07:22 +01004384error:
4385 yang_free_nodes(module->ctx, sibling);
4386 yang_free_nodes(module->ctx, child);
4387 return EXIT_FAILURE;
4388}
4389
4390static int
PavolVican75af21d2016-12-29 20:04:07 +01004391yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4392 struct lys_node *dev_target, struct ly_set *dflt_check)
4393{
4394 struct lys_node_leaflist *llist;
4395 struct lys_type *type;
4396 struct lys_tpdf *tmp_parent;
4397 int i, j;
4398
PavolVican6f000922017-02-10 12:56:59 +01004399 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4400 goto error;
4401 }
PavolVican75af21d2016-12-29 20:04:07 +01004402 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4403 goto error;
4404 }
4405 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4406 goto error;
4407 }
4408 if (deviate->dflt_size) {
4409 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4410 goto error;
4411 }
4412 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4413 /* consolidate the final list in the target after removing items from it */
4414 llist = (struct lys_node_leaflist *)dev_target;
4415 for (i = j = 0; j < llist->dflt_size; j++) {
4416 llist->dflt[i] = llist->dflt[j];
4417 if (llist->dflt[i]) {
4418 i++;
4419 }
4420 }
4421 llist->dflt_size = i + 1;
4422 }
4423 }
4424
4425 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4426 goto error;
4427 }
4428
4429 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4430 goto error;
4431 }
4432
4433 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4434 goto error;
4435 }
4436
4437 if ((deviate->flags & LYS_CONFIG_MASK)) {
4438 /* add and replace are the same in this case */
4439 /* remove current config value of the target ... */
4440 dev_target->flags &= ~LYS_CONFIG_MASK;
4441
4442 /* ... and replace it with the value specified in deviation */
4443 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4444 }
4445
4446 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4447 goto error;
4448 }
4449
4450 if (deviate->type) {
4451 /* check target node type */
4452 if (dev_target->nodetype == LYS_LEAF) {
4453 type = &((struct lys_node_leaf *)dev_target)->type;
4454 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4455 type = &((struct lys_node_leaflist *)dev_target)->type;
4456 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01004457 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4458 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01004459 goto error;
4460 }
4461 /* remove type and initialize it */
4462 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004463 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004464 memcpy(type, deviate->type, sizeof *deviate->type);
4465 free(deviate->type);
4466 deviate->type = type;
4467 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004468 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4469 goto error;
4470 }
4471
PavolVican75af21d2016-12-29 20:04:07 +01004472 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4473 goto error;
4474 }
4475 }
4476
4477 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004478
PavolVican75af21d2016-12-29 20:04:07 +01004479error:
4480 if (deviate->type) {
4481 yang_type_free(module->ctx, deviate->type);
4482 deviate->type = NULL;
4483 }
4484 return EXIT_FAILURE;
4485}
4486
4487static int
4488yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4489{
4490 int rc;
4491 uint i;
4492 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004493 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004494 unsigned int u;
4495 const char *value, *target_name;
4496 struct lys_node_leaflist *llist;
4497 struct lys_node_leaf *leaf;
4498 struct unres_schema tmp_unres;
4499 struct lys_module *mod;
4500
4501 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004502 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4503 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004504 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004505 ly_set_free(set);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004506 i = 0;
4507 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004508 }
Michal Vasko50576712017-07-28 12:28:33 +02004509 dev_target = set->set.s[0];
4510 ly_set_free(set);
4511
PavolVican75af21d2016-12-29 20:04:07 +01004512 if (dev_target->module == lys_main_module(module)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004513 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4514 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004515 i = 0;
4516 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004517 }
4518
4519 if (!dflt_check) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004520 LOGMEM(module->ctx);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004521 i = 0;
4522 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004523 }
4524
4525 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4526 /* you cannot remove a key leaf */
4527 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4528 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4529 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004530 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4531 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004532 i = 0;
4533 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004534 }
4535 }
4536 }
4537 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004538 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004539 lys_node_unlink(dev_target);
Michal Vaskoa1074a52018-01-03 12:18:53 +01004540 if (parent && (parent->nodetype & (LYS_AUGMENT | LYS_USES))) {
Radek Krejci9cf034c2017-08-24 17:10:35 +02004541 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4542 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4543 * path), so we need to remember the augment as an addition */
Michal Vaskoa1074a52018-01-03 12:18:53 +01004544 /* remember uses parent so we can reconnect to it */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004545 dev_target->parent = parent;
4546 }
PavolVican75af21d2016-12-29 20:04:07 +01004547 dev->orig_node = dev_target;
4548 } else {
4549 /* store a shallow copy of the original node */
4550 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004551 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004552 /* just to be safe */
4553 if (tmp_unres.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004554 LOGINT(module->ctx);
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004555 i = 0;
4556 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004557 }
4558 }
4559
PavolVican6f000922017-02-10 12:56:59 +01004560 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004561 i = 0;
4562 goto free_type_error;
PavolVican6f000922017-02-10 12:56:59 +01004563 }
4564
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004565 for (i = 0; i < dev->deviate_size; ++i) {
4566 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4567 yang_free_deviate(module->ctx, dev, i + 1);
4568 dev->deviate_size = i + 1;
4569 goto free_type_error;
PavolVican75af21d2016-12-29 20:04:07 +01004570 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004571 }
4572 /* now check whether default value, if any, matches the type */
4573 for (u = 0; u < dflt_check->number; ++u) {
4574 value = NULL;
4575 rc = EXIT_SUCCESS;
4576 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4577 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4578 target_name = leaf->name;
4579 value = leaf->dflt;
4580 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4581 } else { /* LYS_LEAFLIST */
4582 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4583 target_name = llist->name;
4584 for (i = 0; i < llist->dflt_size; i++) {
4585 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4586 (struct lys_node *)(&llist->dflt[i]));
4587 if (rc == -1) {
4588 value = llist->dflt[i];
4589 break;
Michal Vasko15a43372017-09-25 14:12:42 +02004590 }
4591 }
PavolVican75af21d2016-12-29 20:04:07 +01004592 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004593 if (rc == -1) {
4594 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4595 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
4596 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4597 target_name);
4598 goto error;
4599 }
PavolVican75af21d2016-12-29 20:04:07 +01004600 }
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004601 ly_set_free(dflt_check);
4602 dflt_check = NULL;
PavolVican75af21d2016-12-29 20:04:07 +01004603
Radek Krejci29eac3d2017-06-01 16:50:02 +02004604 /* mark all the affected modules as deviated and implemented */
4605 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004606 mod = lys_node_module(parent);
4607 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004608 mod->deviated = 1; /* main module */
4609 parent->module->deviated = 1; /* possible submodule */
Michal Vasko0f437062018-06-08 15:52:39 +02004610 if (!mod->implemented) {
4611 mod->implemented = 1;
4612 if (unres_schema_add_node(mod, unres, NULL, UNRES_MOD_IMPLEMENT, NULL) == -1) {
4613 goto error;
4614 }
Radek Krejci29eac3d2017-06-01 16:50:02 +02004615 }
4616 }
PavolVican75af21d2016-12-29 20:04:07 +01004617 }
PavolVican75af21d2016-12-29 20:04:07 +01004618
4619 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004620
Michal Vasko9b7a33b2018-05-14 15:23:10 +02004621free_type_error:
4622 /* we need to free types because they are for now allocated dynamically (use i as it is now, is set correctly) */
4623 for (; i < dev->deviate_size; ++i) {
4624 if (dev->deviate[i].type) {
4625 yang_type_free(module->ctx, dev->deviate[i].type);
4626 free(dev->deviate[i].type);
4627 dev->deviate[i].type = NULL;
4628 }
4629 }
PavolVican75af21d2016-12-29 20:04:07 +01004630error:
4631 ly_set_free(dflt_check);
4632 return EXIT_FAILURE;
4633}
4634
4635static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004636yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4637{
PavolVican75af21d2016-12-29 20:04:07 +01004638 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004639
4640 aug_size = module->augment_size;
4641 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004642 dev_size = module->deviation_size;
4643 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004644
PavolVican6f87bf92017-02-15 19:38:55 +01004645 if (yang_check_typedef(module, NULL, unres)) {
4646 goto error;
4647 }
4648
PavolVicanc1807262017-01-31 18:00:27 +01004649 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4650 goto error;
4651 }
4652
PavolVican171717d2017-02-01 14:49:55 +01004653 /* check extension in revision */
4654 for (i = 0; i < module->rev_size; ++i) {
4655 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4656 goto error;
4657 }
4658 }
4659
PavolVican19dc6152017-02-06 12:04:15 +01004660 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004661 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004662 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4663 goto error;
4664 }
4665 }
4666
Pavol Vican7a7916f2016-11-21 23:38:30 +01004667 /* check features */
4668 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004669 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4670 goto error;
4671 }
PavolVican5393d3f2017-02-06 23:30:55 +01004672 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4673 goto error;
4674 }
4675
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004676 /* check for circular dependencies */
4677 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4678 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004679 }
4680 }
Pavol Vican36e27272016-11-22 15:47:28 +01004681 erase_identities = 0;
4682 if (yang_check_identities(module, unres)) {
4683 goto error;
4684 }
Pavol Vican05810b62016-11-23 14:07:22 +01004685 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004686 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004687 goto error;
4688 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004689
PavolVican75af21d2016-12-29 20:04:07 +01004690 /* check deviation */
4691 for (i = 0; i < dev_size; ++i) {
4692 module->deviation_size++;
4693 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4694 goto error;
4695 }
4696 }
4697
Pavol Vican3ad50f82016-12-04 15:00:36 +01004698 /* check augments */
4699 for (i = 0; i < aug_size; ++i) {
4700 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004701 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004702 goto error;
4703 }
4704 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4705 goto error;
4706 }
4707 }
4708
Pavol Vican7313fc02016-11-14 01:10:31 +01004709 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004710
Pavol Vican7313fc02016-11-14 01:10:31 +01004711error:
Pavol Vican36e27272016-11-22 15:47:28 +01004712 if (erase_identities) {
4713 yang_free_ident_base(module->ident, 0, module->ident_size);
4714 }
Pavol Vican05810b62016-11-23 14:07:22 +01004715 if (erase_nodes) {
4716 yang_free_nodes(module->ctx, node);
4717 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004718 for (i = module->augment_size; i < aug_size; ++i) {
4719 yang_free_augment(module->ctx, &module->augment[i]);
4720 }
PavolVican75af21d2016-12-29 20:04:07 +01004721 for (i = module->deviation_size; i < dev_size; ++i) {
4722 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4723 free(module->deviation[i].deviate);
4724 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004725 return EXIT_FAILURE;
4726}
PavolVican22e88682017-02-14 22:38:18 +01004727
4728int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004729yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004730 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4731{
4732 int c;
4733 const char **str, ***p = NULL;
4734 void *reallocated;
4735 struct lyext_substmt *info;
4736
4737 c = 0;
4738 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004739 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004740 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4741 if (info->cardinality < LY_STMT_CARD_SOME) {
4742 str++;
4743 } else {
4744 /* get the index in the array to add new item */
4745 p = (const char ***)str;
4746 for (c = 0; p[0][c + 1]; c++);
4747 str = p[1];
4748 }
4749 str[c] = lydict_insert_zc(module->ctx, value);
4750 } else {
4751 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4752 if (!str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004753 LOGVAL(module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004754 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004755 }
4756 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004757 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004758 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004759 }
4760
4761 if (info->cardinality >= LY_STMT_CARD_SOME) {
4762 /* there can be multiple instances, str is actually const char *** */
4763 p = (const char ***)str;
4764 if (!p[0]) {
4765 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004766 p[0] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004767 LY_CHECK_ERR_GOTO(!p[0], LOGMEM(module->ctx), error);
PavolVican22e88682017-02-14 22:38:18 +01004768 if (stmt == LY_STMT_BELONGSTO) {
4769 /* allocate another array for the belongs-to's prefixes */
4770 p[1] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004771 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004772 } else if (stmt == LY_STMT_ARGUMENT) {
4773 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004774 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Michal Vasko53b7da02018-02-13 15:28:42 +01004775 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004776 /* default value of yin element */
4777 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004778 }
4779 } else {
4780 /* get the index in the array to add new item */
4781 for (c = 0; p[0][c]; c++);
4782 }
4783 str = p[0];
4784 }
4785
4786 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004787 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004788
PavolVican50809742017-02-18 21:22:54 +01004789 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004790 /* enlarge the array(s) */
4791 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4792 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004793 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004794 lydict_remove(module->ctx, p[0][c]);
4795 p[0][c] = NULL;
4796 return EXIT_FAILURE;
4797 }
4798 p[0] = reallocated;
4799 p[0][c + 1] = NULL;
4800
4801 if (stmt == LY_STMT_BELONGSTO) {
4802 /* enlarge the second belongs-to's array with prefixes */
4803 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4804 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004805 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004806 lydict_remove(module->ctx, p[1][c]);
4807 p[1][c] = NULL;
4808 return EXIT_FAILURE;
4809 }
4810 p[1] = reallocated;
4811 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004812 } else if (stmt == LY_STMT_ARGUMENT) {
4813 /* enlarge the second argument's array with yin element */
4814 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4815 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004816 LOGMEM(module->ctx);
PavolVican50809742017-02-18 21:22:54 +01004817 ((uint8_t *)p[1])[c] = 0;
4818 return EXIT_FAILURE;
4819 }
4820 p[1] = reallocated;
4821 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004822 }
4823 }
4824 }
4825
4826 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004827
4828error:
4829 free(value);
4830 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004831}
PavolVican5334c892017-02-15 16:29:09 +01004832
4833static int
4834yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4835{
4836 int c = 0, decrement = 0;
4837 const char **str, ***p = NULL;
4838 struct lyext_substmt *info;
4839
4840
4841 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4842 stmt = LY_STMT_BELONGSTO;
4843 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004844 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4845 stmt = LY_STMT_ARGUMENT;
4846 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004847 }
4848
4849 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4850 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4851 return 0;
4852 } else {
4853 p = (const char ***)str;
4854 /* get the index in the array */
4855 for (c = 0; p[0][c]; c++);
4856 return c + decrement;
4857 }
4858}
PavolVicana0fdbf32017-02-15 17:59:02 +01004859
4860void **
PavolVicanfe83b152017-02-19 03:19:29 +01004861yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4862 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004863{
Michal Vasko53b7da02018-02-13 15:28:42 +01004864 struct ly_ctx *ctx = ext->module->ctx;
PavolVicana0fdbf32017-02-15 17:59:02 +01004865 int c;
4866 void **data, ***p = NULL;
4867 void *reallocated;
4868 struct lyext_substmt *info;
4869
4870 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4871 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004872 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004873 return NULL;
4874 }
4875 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004876 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004877 return NULL;
4878 }
4879
4880 c = 0;
4881 if (info->cardinality >= LY_STMT_CARD_SOME) {
4882 /* there can be multiple instances, so instead of pointer to array,
4883 * we have in data pointer to pointer to array */
4884 p = (void ***)data;
4885 data = *p;
4886 if (!data) {
4887 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004888 *p = data = calloc(2, sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004889 LY_CHECK_ERR_RETURN(!data, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004890 } else {
4891 for (c = 0; *data; data++, c++);
4892 }
4893 }
4894
PavolVicaneef1d912017-02-19 00:19:15 +01004895 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004896 /* enlarge the array */
4897 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004898 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004899 *p = reallocated;
4900 data = *p;
4901 data[c + 1] = NULL;
4902 }
4903
PavolVicanfe83b152017-02-19 03:19:29 +01004904 if (index) {
4905 *index = c;
4906 return data;
4907 } else {
4908 return &data[c];
4909 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004910}
PavolVicanff0f7f42017-02-16 11:35:42 +01004911
4912int
4913yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4914 LY_STMT stmt, uint16_t value, uint16_t mask)
4915{
4916 uint16_t *data;
4917 struct lyext_substmt *info;
4918
4919 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4920 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004921 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004922 return EXIT_FAILURE;
4923 }
4924 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004925 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004926 return EXIT_FAILURE;
4927 }
4928
4929 *data |= value;
4930 return EXIT_SUCCESS;
4931}
PavolVican8e8dfd12017-02-16 13:51:41 +01004932
4933int
PavolVican6a852a62017-02-16 15:36:01 +01004934yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4935 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004936{
Michal Vasko53b7da02018-02-13 15:28:42 +01004937 struct ly_ctx *ctx = ext->module->ctx;
PavolVican6a852a62017-02-16 15:36:01 +01004938 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004939 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004940 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004941
4942 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4943 if (!val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004944 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican8e8dfd12017-02-16 13:51:41 +01004945 return EXIT_FAILURE;
4946 }
PavolVican6a852a62017-02-16 15:36:01 +01004947 if (stmt == LY_STMT_DIGITS) {
4948 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004949 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01004950 return EXIT_FAILURE;
4951 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004952
PavolVican6a852a62017-02-16 15:36:01 +01004953 if (info->cardinality >= LY_STMT_CARD_SOME) {
4954 /* there can be multiple instances */
4955 pp = (uint8_t**)val;
4956 if (!(*pp)) {
4957 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Michal Vasko53b7da02018-02-13 15:28:42 +01004958 LY_CHECK_ERR_RETURN(!*pp, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004959 } else {
4960 for (i = 0; (*pp)[i]; i++);
4961 }
4962 val = &(*pp)[i];
4963 }
4964
4965 /* stored value */
4966 *val = value;
4967
4968 if (i) {
4969 /* enlarge the array */
4970 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Michal Vasko53b7da02018-02-13 15:28:42 +01004971 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004972 *pp = reallocated;
4973 (*pp)[i + 1] = 0;
4974 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004975 } else {
PavolVican6a852a62017-02-16 15:36:01 +01004976 if (*val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004977 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01004978 return EXIT_FAILURE;
4979 }
4980
4981 if (stmt == LY_STMT_REQINSTANCE) {
4982 *val = (value == 1) ? 1 : 2;
4983 } else if (stmt == LY_STMT_MODIFIER) {
4984 *val = 1;
4985 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01004986 LOGINT(ctx);
PavolVican6a852a62017-02-16 15:36:01 +01004987 return EXIT_FAILURE;
4988 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004989 }
4990
4991 return EXIT_SUCCESS;
4992}
PavolVican3f47b292017-02-16 20:38:16 +01004993
PavolVicanf3091bf2017-02-19 18:27:01 +01004994int
4995yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4996 struct lys_node *node, LY_STMT stmt)
4997{
4998 struct lyext_substmt *info;
4999 struct lys_node **snode, *siter;
5000
5001 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
5002 if (!snode) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005003 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01005004 return EXIT_FAILURE;
5005 }
5006 if (info->cardinality < LY_STMT_CARD_SOME) {
5007 LY_TREE_FOR(node, siter) {
5008 if (stmt == lys_snode2stmt(siter->nodetype)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005009 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01005010 return EXIT_FAILURE;
5011 }
5012 }
5013 }
5014
5015 return EXIT_SUCCESS;
5016}
PavolVicandb0e8172017-02-20 00:46:09 +01005017
5018int
5019yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
5020 char *parent_name, char **values, int implemented)
5021{
5022 int c, i;
5023 struct lys_module **modules, ***p, *reallocated, **pp;
5024 struct lyext_substmt *info;
5025
5026 if (!values) {
5027 return EXIT_SUCCESS;
5028 }
5029 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
5030 if (!modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005031 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005032 return EXIT_FAILURE;
5033 }
5034
5035 for (i = 0; values[i]; ++i) {
5036 c = 0;
5037 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005038 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005039 return EXIT_FAILURE;
5040 }
5041 if (info->cardinality >= LY_STMT_CARD_SOME) {
5042 /* there can be multiple instances, so instead of pointer to array,
5043 * we have in modules pointer to pointer to array */
5044 p = (struct lys_module ***)pp;
5045 modules = *p;
5046 if (!modules) {
5047 /* allocate initial array */
5048 *p = modules = calloc(2, sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005049 LY_CHECK_ERR_RETURN(!*p, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005050 } else {
5051 for (c = 0; *modules; modules++, c++);
5052 }
5053 }
5054
5055 if (c) {
5056 /* enlarge the array */
5057 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005058 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005059 *p = (struct lys_module **)reallocated;
5060 modules = *p;
5061 modules[c + 1] = NULL;
5062 }
5063
5064 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
5065 if (!modules[c]) {
5066 return EXIT_FAILURE;
5067 }
5068 }
5069
5070 return EXIT_SUCCESS;
5071}