blob: f9ec0fbf1df82bad1dda78471613c14d8de34655 [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) {
PavolVican196694c2017-01-27 10:33:09 +010039 LOGVAL(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);
68 LOGINT;
69 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 Vasko3767fb22016-07-21 12:10:57 +020082 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
83 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) {
88 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
89 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) {
98 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
99 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 {
106 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
107 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
Pavol Vican1cc4e192016-10-24 16:38:31 +0200119 if (!imp && lyp_check_identifier(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) {
Pavol Vicane024ab72016-07-27 14:27:43 +0200141 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 goto error;
143 } else {
144 if (lyp_check_identifier(imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
145 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);
Radek Krejci5138e9f2017-04-12 13:10:46 +0200163 lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200164 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100165}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100166
167int
PavolVican196694c2017-01-27 10:33:09 +0100168yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100169{
170 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100171 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100172
PavolVican196694c2017-01-27 10:33:09 +0100173 switch (type) {
174 case MODULE_KEYWORD:
175 ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
176 break;
177 case REVISION_KEYWORD:
178 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
179 break;
180 case IMPORT_KEYWORD:
181 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
182 break;
183 case INCLUDE_KEYWORD:
184 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
185 break;
186 case NODE_PRINT:
187 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
188 break;
189 default:
190 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
191 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100192 }
193 return ret;
194}
195
196int
PavolVican196694c2017-01-27 10:33:09 +0100197yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100198{
199 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100200 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100201
PavolVican196694c2017-01-27 10:33:09 +0100202 switch (type) {
203 case MODULE_KEYWORD:
204 ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
205 break;
206 case REVISION_KEYWORD:
207 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
208 break;
209 case IMPORT_KEYWORD:
210 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
211 break;
212 case INCLUDE_KEYWORD:
213 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
214 break;
215 case NODE_PRINT:
216 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
217 break;
218 default:
219 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
220 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100221 }
222 return ret;
223}
Pavol Vicanbedff692016-02-03 14:29:17 +0100224
Pavol Vican1eeb1992016-02-09 11:10:45 +0100225int
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100226yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
227 char *value, struct unres_schema *unres, int parent_is_feature)
Pavol Vicane1354e92016-02-09 14:02:09 +0100228{
229 const char *exp;
230 int ret;
231
Michal Vasko97b32be2016-07-25 10:59:53 +0200232 if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
233 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
234 free(value);
235 return EXIT_FAILURE;
236 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100237
Michal Vasko56d082c2016-10-25 14:00:42 +0200238 if (!(exp = transform_iffeat_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100239 free(value);
240 return EXIT_FAILURE;
241 }
242 free(value);
243
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100244 ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
Pavol Vicane1354e92016-02-09 14:02:09 +0100245 lydict_remove(module->ctx, exp);
Pavol Vicane1354e92016-02-09 14:02:09 +0100246
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100247 return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
Pavol Vicane1354e92016-02-09 14:02:09 +0100248}
249
Pavol Vican4fb66c92016-03-17 10:32:27 +0100250int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100251yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100252{
253 const char *exp;
254
Pavol Vican0adf01d2016-03-22 12:29:33 +0100255 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100256 free(value);
257 if (!exp) {
258 return EXIT_FAILURE;
259 }
Pavol Vican4ffd0ab2016-08-27 16:35:04 +0200260
Pavol Vican0adf01d2016-03-22 12:29:33 +0100261 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100262 lydict_remove(module->ctx, exp);
263 return EXIT_FAILURE;
264 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100265
Pavol Vicanbbdef532016-02-09 14:52:12 +0100266 lydict_remove(module->ctx, exp);
267 return EXIT_SUCCESS;
268}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100269
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100270int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100271yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100272{
273 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100274
Pavol Vicandde090a2016-08-30 15:12:14 +0200275 if (message == ERROR_APP_TAG_KEYWORD) {
PavolVican196694c2017-01-27 10:33:09 +0100276 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100277 } else {
PavolVican196694c2017-01-27 10:33:09 +0100278 ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100279 }
280 return ret;
281}
Pavol Vicanb5687112016-02-09 22:35:59 +0100282
283int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100284yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100285{
286 if (cont->presence) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100287 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100288 free(value);
289 return EXIT_FAILURE;
290 } else {
291 cont->presence = lydict_insert_zc(module->ctx, value);
292 return EXIT_SUCCESS;
293 }
294}
295
Pavol Vican235dbd42016-02-10 10:34:19 +0100296void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200297yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100298{
299 struct lys_when *retval;
300
301 retval = calloc(1, sizeof *retval);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200302 LY_CHECK_ERR_RETURN(!retval, LOGMEM; free(value), NULL);
Pavol Vican0adf01d2016-03-22 12:29:33 +0100303 retval->cond = transform_schema2json(module, value);
Michal Vasko508a50d2016-09-07 14:50:33 +0200304 if (!retval->cond) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100305 goto error;
306 }
307 switch (type) {
308 case CONTAINER_KEYWORD:
309 if (((struct lys_node_container *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100310 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100311 goto error;
312 }
313 ((struct lys_node_container *)node)->when = retval;
314 break;
Pavol Vicandb7489e2016-08-23 17:23:39 +0200315 case ANYDATA_KEYWORD:
Pavol Vican1f06ba82016-02-10 17:39:50 +0100316 case ANYXML_KEYWORD:
Radek Krejcibf2abff2016-08-23 15:51:52 +0200317 if (((struct lys_node_anydata *)node)->when) {
Pavol Vicandb7489e2016-08-23 17:23:39 +0200318 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100319 goto error;
320 }
Radek Krejcibf2abff2016-08-23 15:51:52 +0200321 ((struct lys_node_anydata *)node)->when = retval;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100322 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100323 case CHOICE_KEYWORD:
324 if (((struct lys_node_choice *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100325 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100326 goto error;
327 }
328 ((struct lys_node_choice *)node)->when = retval;
329 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100330 case CASE_KEYWORD:
331 if (((struct lys_node_case *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100332 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100333 goto error;
334 }
335 ((struct lys_node_case *)node)->when = retval;
336 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100337 case LEAF_KEYWORD:
338 if (((struct lys_node_leaf *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100339 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100340 goto error;
341 }
342 ((struct lys_node_leaf *)node)->when = retval;
343 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100344 case LEAF_LIST_KEYWORD:
345 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100346 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100347 goto error;
348 }
349 ((struct lys_node_leaflist *)node)->when = retval;
350 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100351 case LIST_KEYWORD:
352 if (((struct lys_node_list *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100353 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100354 goto error;
355 }
356 ((struct lys_node_list *)node)->when = retval;
357 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100358 case USES_KEYWORD:
359 if (((struct lys_node_uses *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100360 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100361 goto error;
362 }
363 ((struct lys_node_uses *)node)->when = retval;
364 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100365 case AUGMENT_KEYWORD:
366 if (((struct lys_node_augment *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100367 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100368 goto error;
369 }
370 ((struct lys_node_augment *)node)->when = retval;
371 break;
PavolVicanb0317082017-02-19 01:29:22 +0100372 case EXTENSION_INSTANCE:
373 *(struct lys_when **)node = retval;
374 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200375 default:
376 goto error;
377 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100378 }
379 free(value);
380 return retval;
381
382error:
383 free(value);
PavolVicanb0317082017-02-19 01:29:22 +0100384 lydict_remove(module->ctx, retval->cond);
385 free(retval);
Pavol Vican235dbd42016-02-10 10:34:19 +0100386 return NULL;
387}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100388
389void *
Pavol Vican05810b62016-11-23 14:07:22 +0100390yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
391 char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100392{
Pavol Vican05810b62016-11-23 14:07:22 +0100393 struct lys_node *node, **child;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100394
Pavol Vican7cadfe72016-02-11 12:33:34 +0100395 node = calloc(1, sizeof_struct);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200396 LY_CHECK_ERR_RETURN(!node, LOGMEM; free(value), NULL);
397
Michal Vasko3e3228d2017-02-24 14:55:32 +0100398 LOGDBG(LY_LDGYANG, "parsing %s statement \"%s\"", strnodetype(nodetype), value);
PavolVican196694c2017-01-27 10:33:09 +0100399 node->name = lydict_insert_zc(module->ctx, value);
Pavol Vican7cadfe72016-02-11 12:33:34 +0100400 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100401 node->nodetype = nodetype;
PavolVicanbd1d1ae2017-07-20 00:06:00 +0200402 node->parent = parent;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100403
404 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100405 child = (parent) ? &parent->child : root;
406 if (*child) {
407 (*child)->prev->next = node;
408 (*child)->prev = node;
409 } else {
410 *child = node;
411 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100412 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100413 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100414}
415
416int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200417yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100418{
419 int ret;
420
421 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100422 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100423 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100424 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100425 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100426 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100427 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200428 default:
429 free(value);
430 LOGINT;
431 ret = EXIT_FAILURE;
432 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100433 }
434 return ret;
435}
436
437int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200438yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100439{
440 int ret;
441
442 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100443 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100444 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100445 break;
446 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100447 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100448 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100449 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100450 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100451 break;
PavolVican75af21d2016-12-29 20:04:07 +0100452 case ADD_KEYWORD:
453 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +0100454 case DELETE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100455 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100456 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200457 default:
458 free(value);
459 LOGINT;
460 ret = EXIT_FAILURE;
461 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100462 }
463 return ret;
464}
Pavol Vican5de33492016-02-22 14:03:24 +0100465
466int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100467yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100468{
469 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100470 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100471
472 exp = value = (char *) list->keys;
473 while ((value = strpbrk(value, " \t\n"))) {
474 list->keys_size++;
475 while (isspace(*value)) {
476 value++;
477 }
478 }
479 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100480
481 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100482 list->keys = calloc(list->keys_size, sizeof *list->keys);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200483 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM, EXIT_FAILURE);
484
Radek Krejci5c08a992016-11-02 13:30:04 +0100485 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
486 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
487 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100488 }
Pavol Vican5de33492016-02-22 14:03:24 +0100489 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100490}
491
492int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100493yang_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 +0100494{
495 int i, j;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200496 char *vaux, c;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200497 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100498
499 /* count the number of unique leafs in the value */
500 vaux = value;
501 while ((vaux = strpbrk(vaux, " \t\n"))) {
502 unique->expr_size++;
503 while (isspace(*vaux)) {
504 vaux++;
505 }
506 }
507 unique->expr_size++;
508 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200509 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM, error);
Pavol Vican85f12022016-03-05 16:30:35 +0100510
511 for (i = 0; i < unique->expr_size; i++) {
512 vaux = strpbrk(value, " \t\n");
Radek Krejci1a9c3612017-04-24 14:49:43 +0200513 if (vaux) {
514 c = *vaux;
515 *vaux = '\0';
Pavol Vican85f12022016-03-05 16:30:35 +0100516 }
517
Radek Krejci1a9c3612017-04-24 14:49:43 +0200518 /* store token into unique structure (includes converting prefix to the module name) */
519 unique->expr[i] = transform_schema2json(module, value);
520 if (vaux) {
521 *vaux = c;
522 }
Pavol Vican85f12022016-03-05 16:30:35 +0100523
524 /* check that the expression does not repeat */
525 for (j = 0; j < i; j++) {
526 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100527 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
PavolVican196694c2017-01-27 10:33:09 +0100528 LOGVAL(LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100529 goto error;
530 }
531 }
532 /* try to resolve leaf */
533 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200534 unique_info = malloc(sizeof *unique_info);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200535 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM, error);
Radek Krejcid09d1a52016-08-11 14:05:45 +0200536 unique_info->list = (struct lys_node *)list;
537 unique_info->expr = unique->expr[i];
538 unique_info->trg_type = &unique->trg_type;
539 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200540 goto error;
541 }
Pavol Vican85f12022016-03-05 16:30:35 +0100542 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200543 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100544 goto error;
545 }
546 }
547
548 /* move to next token */
549 value = vaux;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200550 while(value && isspace(*value)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100551 value++;
552 }
553 }
554
555 return EXIT_SUCCESS;
556
557error:
558 return EXIT_FAILURE;
559}
560
561int
Pavol Vican5de33492016-02-22 14:03:24 +0100562yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
563{
564 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100565 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100566
567 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100568 str = (char *)list->unique[k].expr;
569 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100570 goto error;
571 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100572 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100573 }
574 return EXIT_SUCCESS;
575
576error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100577 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100578 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100579}
580
Pavol Vican07f220f2016-09-02 13:04:37 +0200581int
Pavol Vican81344ac2016-09-02 14:23:06 +0200582yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100583{
Pavol Vican81344ac2016-09-02 14:23:06 +0200584 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
585 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
586 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100587 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200588 if (stype->type->info.lref.path) {
589 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
590 goto error;
591 }
592 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
593 stype->base = LY_TYPE_LEAFREF;
594 return EXIT_SUCCESS;
595
596error:
597 free(value);
598 return EXIT_FAILURE;
599}
600
601int
602yang_read_require_instance(struct yang_type *stype, int req)
603{
604 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
605 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
606 return EXIT_FAILURE;
607 }
608 if (stype->type->info.lref.req) {
609 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
610 return EXIT_FAILURE;
611 }
612 stype->type->info.lref.req = req;
613 stype->base = LY_TYPE_LEAFREF;
614 return EXIT_SUCCESS;
615}
616
617int
Pavol Vican7313fc02016-11-14 01:10:31 +0100618yang_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 +0100619{
Radek Krejcidce5f972017-09-12 15:47:49 +0200620 int rc, ret = -1;
621 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200622 int8_t req;
Michal Vasko568b1952018-01-30 15:53:30 +0100623 const char *name, *value, *module_name = NULL;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100624 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200625 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200626 struct lys_type *dertype;
627 struct lys_type_enum *enms_sc = NULL;
628 struct lys_type_bit *bits_sc = NULL;
629 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100630 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100631
Pavol Vican0adf01d2016-03-22 12:29:33 +0100632 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100633 if (!value) {
634 goto error;
635 }
636
637 i = parse_identifier(value);
638 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100639 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100640 lydict_remove(module->ctx, value);
641 goto error;
642 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200643 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100644 name = value;
645 if (value[i]) {
Michal Vasko568b1952018-01-30 15:53:30 +0100646 module_name = lydict_insert(module->ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100647 name += i;
648 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100649 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Michal Vasko568b1952018-01-30 15:53:30 +0100650 lydict_remove(module->ctx, module_name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100651 lydict_remove(module->ctx, value);
652 goto error;
653 }
654 ++name;
655 }
656
Michal Vasko568b1952018-01-30 15:53:30 +0100657 rc = resolve_superior_type(name, module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100658 if (rc == -1) {
Michal Vasko568b1952018-01-30 15:53:30 +0100659 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, module_name);
660 lydict_remove(module->ctx, module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200661 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100662 goto error;
663
Michal Vasko01c6fd22016-05-20 11:43:05 +0200664 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100665 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200666 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Michal Vasko568b1952018-01-30 15:53:30 +0100667 lydict_remove(module->ctx, module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200668 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100669 ret = EXIT_FAILURE;
670 goto error;
671 }
Michal Vasko568b1952018-01-30 15:53:30 +0100672 lydict_remove(module->ctx, module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200673 lydict_remove(module->ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200674
Pavol Vican7313fc02016-11-14 01:10:31 +0100675 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200676 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200677 * unresolved item left inside the grouping, LY_TYPE_ERR used as a flag for types inside a grouping. */
Radek Krejcic13db382016-08-16 10:52:42 +0200678 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
679 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200680 assert(((struct lys_node_grp *)siter)->unres_count);
681 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200682 } else {
683 LOGINT;
684 goto error;
685 }
686 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200687
688 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100689 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
690 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200691 goto error;
692 }
693
Pavol Vican8bd72e42016-08-29 09:53:05 +0200694 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100695 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100696 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100697 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100698 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100699 }
700 switch (base) {
701 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100702 if (type->base == LY_TYPE_BINARY) {
703 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100704 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100705 goto error;
706 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100707 type->info.binary.length = type->info.str.length;
708 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
709 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100710 goto error;
711 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100712 } else if (type->base == LY_TYPE_STRING) {
713 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
714 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100715 goto error;
716 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100717 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100718 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100719 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100720 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100721 break;
722 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100723 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100724 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100725 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100726 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100727 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100728 goto error;
729 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100730 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100731 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100732 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100733 goto error;
734 }
Radek Krejci4800f652016-09-08 14:02:52 +0200735
736 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100737 if (type->der->type.der) {
738 type->info.dec64.dig = type->der->type.info.dec64.dig;
739 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200740 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100741 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
742 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200743 goto error;
744 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100745 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
746 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100747 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100748 goto error;
749 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100750 type->info.num.range = type->info.dec64.range;
751 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
752 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100753 goto error;
754 }
755 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100756 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100757 goto error;
758 }
759 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100760 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100761 if (type->base != LY_TYPE_ENUM) {
762 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100763 goto error;
764 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100765 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200766
767 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100768 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200769 /* type is derived directly from buit-in enumeartion type and enum statement is required */
770 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
771 goto error;
772 }
773 } else {
774 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100775 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200776 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
777 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
778 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
779 goto error;
780 }
781
782 /* restricted enumeration type - the name MUST be used in the base type */
783 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100784 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200785 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100786 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200787 break;
788 }
789 }
790 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100791 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200792 goto error;
793 }
794
Pavol Vican7313fc02016-11-14 01:10:31 +0100795 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200796 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100797 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200798 } else {
799 /* check that the assigned value corresponds to the original
800 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100801 if (type->info.enums.enm[i].value != enms_sc[j].value) {
802 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200803 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100804 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
805 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200806 goto error;
807 }
808 }
809 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100810 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100811 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100812 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100813 if (type->base != LY_TYPE_BITS) {
814 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100815 goto error;
816 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100817 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200818
819 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100820 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200821 /* type is derived directly from buit-in bits type and bit statement is required */
822 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
823 goto error;
824 }
825 } else {
826 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100827 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200828 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
829 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
830 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
831 goto error;
832 }
833
834 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100835 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200836 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100837 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200838 break;
839 }
840 }
841 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100842 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200843 goto error;
844 }
845
846 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100847 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200848 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100849 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200850 } else {
851 /* check that the assigned position corresponds to the original
852 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100853 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
854 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200855 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100856 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
857 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200858 goto error;
859 }
860 }
861 }
Pavol Vican03a59442016-03-21 15:23:45 +0100862 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200863
Radek Krejcidce5f972017-09-12 15:47:49 +0200864 for (i = type->info.bits.count; i > 0; i--) {
865 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200866
867 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100868 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200869 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100870 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
871 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
872 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200873 j--;
874 }
Pavol Vican03a59442016-03-21 15:23:45 +0100875 }
876 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100877 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100878 if (type->base == LY_TYPE_INST) {
879 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200880 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100881 goto error;
882 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100883 if ((req = type->info.lref.req)) {
884 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200885 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100886 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200887 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100888 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200889 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
890 goto error;
891 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200892 /* flag resolving for later use */
893 if (!tpdftype) {
894 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
895 if (siter) {
896 /* just a flag - do not resolve */
897 tpdftype = 1;
898 }
899 }
900
Pavol Vican7313fc02016-11-14 01:10:31 +0100901 if (type->info.lref.path) {
902 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200903 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
904 goto error;
905 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100906 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100907 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100908 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100909 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100910 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100911 goto error;
912 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200913 /* try to resolve leafref path only when this is instantiated
914 * leaf, so it is not:
915 * - typedef's type,
916 * - in grouping definition,
917 * - just instantiated in a grouping definition,
918 * because in those cases the nodes referenced in path might not be present
919 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100920 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100921 goto error;
922 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100923 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100924 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100925 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200926 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200927 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100928 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200929 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100930 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200931 goto error;
932 }
Pavol Vican191613a2016-02-26 16:21:32 +0100933 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100934 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100935 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100936 goto error;
937 }
938 break;
939 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100940 if (type->base != LY_TYPE_IDENT) {
941 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100942 goto error;
943 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100944 if (type->der->type.der) {
945 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200946 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
947 goto error;
948 }
949 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100950 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200951 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
952 goto error;
953 }
954 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100955 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100956 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100957 if (type->base != LY_TYPE_UNION) {
958 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100959 goto error;
960 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100961 if (!type->info.uni.types) {
962 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100963 /* this is just a derived type with no additional type specified/required */
964 break;
965 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100966 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100967 goto error;
968 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100969 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100970 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100971 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
972 yang = (struct yang_type *)dertype->der;
973 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100974 dertype->parent = type->parent;
975 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100976 dertype->der = (struct lys_tpdf *)yang;
977 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100978 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100979 base = 0;
980 goto error;
981 } else {
982 lydict_remove(module->ctx, yang->name);
983 free(yang);
984 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100985 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200986 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100987 if (dertype->base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200988 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
989 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100990 } else if (dertype->base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200991 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
992 goto error;
993 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100994 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100995 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
996 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +0100997 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100998 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100999 }
1000 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001001
1002 default:
1003 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001004 if (type->base != base) {
1005 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001006 goto error;
1007 }
1008 } else {
1009 LOGINT;
1010 goto error;
1011 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001012 }
PavolVican92f23622017-12-12 13:35:56 +01001013
1014 /* if derived type has extension, which need validate data */
1015 dertype = &type->der->type;
1016 while (dertype->der) {
1017 if (dertype->parent->flags & LYS_VALID_DATA) {
1018 type->parent->flags |= LYS_VALID_DATA;
1019 }
1020 dertype = &dertype->der->type;
1021 }
1022
Pavol Vican73e7c992016-02-24 12:18:05 +01001023 return EXIT_SUCCESS;
1024
1025error:
Pavol Vican8bd72e42016-08-29 09:53:05 +02001026 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001027 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001028 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001029 return ret;
1030}
1031
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001032void
1033yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1034{
1035 struct lys_type *stype;
1036 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001037 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001038
1039 for (i = 0; i < type->info.uni.count; ++i) {
1040 stype = &type->info.uni.types[i];
1041 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1042 yang = (struct yang_type *)stype->der;
1043 stype->base = yang->base;
1044 lydict_remove(ctx, yang->name);
1045 free(yang);
1046 } else if (stype->base == LY_TYPE_UNION) {
1047 yang_free_type_union(ctx, stype);
1048 }
1049 }
1050}
1051
Pavol Vican73e7c992016-02-24 12:18:05 +01001052void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001053yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001054{
1055 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001056 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001057
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001058 typ = calloc(1, sizeof *typ);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001059 LY_CHECK_ERR_RETURN(!typ, LOGMEM, NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001060
1061 typ->flags = LY_YANG_STRUCTURE_FLAG;
1062 switch (type) {
1063 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001064 if (((struct lys_node_leaf *)parent)->type.der) {
1065 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1066 goto error;
1067 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001068 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1069 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1070 typ->type = &((struct lys_node_leaf *)parent)->type;
1071 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001072 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001073 if (((struct lys_node_leaflist *)parent)->type.der) {
1074 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1075 goto error;
1076 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001077 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1078 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1079 typ->type = &((struct lys_node_leaflist *)parent)->type;
1080 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001081 case UNION_KEYWORD:
1082 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1083 typ->type = (struct lys_type *)parent;
1084 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001085 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001086 if (((struct lys_tpdf *)parent)->type.der) {
1087 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1088 goto error;
1089 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001090 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1091 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001092 break;
1093 case REPLACE_KEYWORD:
1094 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001095 dev = (struct lys_deviate *)parent;
1096 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001097 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001098 goto error;
1099 }
PavolVican75af21d2016-12-29 20:04:07 +01001100 dev->type = calloc(1, sizeof *dev->type);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001101 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001102 dev->type->der = (struct lys_tpdf *)typ;
1103 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001104 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001105 case EXTENSION_INSTANCE:
1106 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1107 typ->type = parent;
1108 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001109 default:
1110 goto error;
1111 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001112 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001113 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001114 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001115
1116error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001117 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001118 free(typ);
1119 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001120}
1121
1122void *
PavolVicaneef1d912017-02-19 00:19:15 +01001123yang_read_length(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001124{
PavolVicaneef1d912017-02-19 00:19:15 +01001125 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001126
PavolVicaneef1d912017-02-19 00:19:15 +01001127 if (is_ext_instance) {
1128 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001129 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001130 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1131 stype->base = LY_TYPE_STRING;
1132 } else {
1133 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
1134 goto error;
1135 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001136
PavolVicaneef1d912017-02-19 00:19:15 +01001137 if (stype->type->info.str.length) {
1138 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
1139 goto error;
1140 }
1141 length = calloc(1, sizeof *length);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001142 LY_CHECK_ERR_GOTO(!length, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001143 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001144 }
PavolVicaneef1d912017-02-19 00:19:15 +01001145 length->expr = lydict_insert_zc(module->ctx, value);
1146 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001147
1148error:
1149 free(value);
1150 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001151}
Pavol Vican1c203db2016-02-24 14:05:23 +01001152
Pavol Vican6eecf302016-08-10 11:09:05 +02001153int
Radek Krejcib53154b2017-07-19 09:14:13 +02001154yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, void **precomp, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001155{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001156 char *buf;
1157 size_t len;
1158
PavolVicanbd1d1ae2017-07-20 00:06:00 +02001159 if (precomp && lyp_precompile_pattern(value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001160 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001161 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001162 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001163
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001164 len = strlen(value);
1165 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Radek Krejcia8d111f2017-05-31 13:57:37 +02001166 LY_CHECK_ERR_RETURN(!buf, LOGMEM; free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001167
1168 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001169 strcpy(&buf[1], value);
1170 free(value);
1171
Pavol Vican6eecf302016-08-10 11:09:05 +02001172 pattern->expr = lydict_insert_zc(module->ctx, buf);
1173 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001174}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001175
1176void *
PavolVicaneef1d912017-02-19 00:19:15 +01001177yang_read_range(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001178{
PavolVicaneef1d912017-02-19 00:19:15 +01001179 struct lys_restr * range;
1180
1181 if (is_ext_instance) {
1182 range = (struct lys_restr *)stype;
1183 } else {
1184 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
1185 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
1186 goto error;
1187 }
1188 stype->base = LY_TYPE_DEC64;
1189 if (stype->type->info.dec64.range) {
1190 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
1191 goto error;
1192 }
1193 range = calloc(1, sizeof *range);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001194 LY_CHECK_ERR_GOTO(!range, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001195 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001196 }
PavolVicaneef1d912017-02-19 00:19:15 +01001197 range->expr = lydict_insert_zc(module->ctx, value);
1198 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001199
1200error:
1201 free(value);
1202 return NULL;
1203}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001204
1205int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001206yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001207{
Pavol Vican6b072512016-04-04 10:50:21 +02001208 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1209 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001210 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001211 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001212 goto error;
1213 }
1214 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001215 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001216 goto error;
1217 }
1218 /* range check */
1219 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001220 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001221 goto error;
1222 }
1223 typ->type->info.dec64.dig = value;
1224 return EXIT_SUCCESS;
1225
1226error:
1227 return EXIT_FAILURE;
1228}
Pavol Vican79a763d2016-02-25 15:41:27 +01001229
Pavol Vican874715f2016-10-25 14:52:08 +02001230int
1231yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001232{
Pavol Vican874715f2016-10-25 14:52:08 +02001233 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001234
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001235 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001236 if (!value[0]) {
1237 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1238 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1239 free(value);
1240 goto error;
1241 }
1242
Pavol Vican79a763d2016-02-25 15:41:27 +01001243 enm->name = lydict_insert_zc(module->ctx, value);
1244
1245 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1246 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001247 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001248 goto error;
1249 }
1250
Pavol Vican874715f2016-10-25 14:52:08 +02001251 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001252 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001253 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001254 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
1255 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001256 goto error;
1257 }
1258 }
1259
Pavol Vican874715f2016-10-25 14:52:08 +02001260 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001261
1262error:
Pavol Vican874715f2016-10-25 14:52:08 +02001263 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001264}
1265
1266int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001267yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001268{
1269 int i, j;
1270
1271 if (!assign) {
1272 /* assign value automatically */
1273 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001274 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001275 goto error;
1276 }
1277 enm->value = *value;
1278 enm->flags |= LYS_AUTOASSIGNED;
1279 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001280 } else if (typ->type->info.enums.enm == enm) {
1281 /* change value, which is assigned automatically, if first enum has value. */
1282 *value = typ->type->info.enums.enm[0].value;
1283 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001284 }
1285
1286 /* check that the value is unique */
1287 j = typ->type->info.enums.count-1;
1288 for (i = 0; i < j; i++) {
1289 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001290 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001291 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1292 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001293 goto error;
1294 }
1295 }
1296
1297 return EXIT_SUCCESS;
1298
1299error:
1300 return EXIT_FAILURE;
1301}
Pavol Vican9887c682016-02-29 11:32:01 +01001302
Pavol Vican59e8dee2016-10-25 15:29:38 +02001303int
1304yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001305{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001306 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001307
PavolVicane87cb932016-12-30 15:36:18 +01001308 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001309 bit->name = lydict_insert_zc(module->ctx, value);
1310 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001311 goto error;
1312 }
Pavol Vican9887c682016-02-29 11:32:01 +01001313
Pavol Vican59e8dee2016-10-25 15:29:38 +02001314 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001315 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001316 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001317 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001318 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001319 goto error;
1320 }
1321 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001322 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001323
1324error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001325 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001326}
1327
1328int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001329yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001330{
1331 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001332
1333 if (!assign) {
1334 /* assign value automatically */
1335 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001336 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001337 goto error;
1338 }
1339 bit->pos = (uint32_t)*value;
1340 bit->flags |= LYS_AUTOASSIGNED;
1341 (*value)++;
1342 }
1343
1344 j = typ->type->info.bits.count - 1;
1345 /* check that the value is unique */
1346 for (i = 0; i < j; i++) {
1347 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001348 LOGVAL(LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
Pavol Vican9887c682016-02-29 11:32:01 +01001349 goto error;
1350 }
1351 }
1352
Pavol Vican9887c682016-02-29 11:32:01 +01001353 return EXIT_SUCCESS;
1354
1355error:
1356 return EXIT_FAILURE;
1357}
Pavol Vican0df02b02016-03-01 10:28:50 +01001358
Pavol Vican3ad50f82016-12-04 15:00:36 +01001359int
1360yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001361{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001362 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001363 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001364 free(value);
1365 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001366 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001367 }
1368 aug->parent = parent;
1369 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001370 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001371}
Pavol Vican220e5a12016-03-03 14:19:43 +01001372
PavolVican6f000922017-02-10 12:56:59 +01001373void *
PavolVican75af21d2016-12-29 20:04:07 +01001374yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001375{
PavolVican75af21d2016-12-29 20:04:07 +01001376 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001377 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001378 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001379 }
PavolVican75af21d2016-12-29 20:04:07 +01001380 dev->deviate = calloc(1, sizeof *dev->deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001381 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001382 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1383 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001384 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001385}
1386
1387void *
PavolVican75af21d2016-12-29 20:04:07 +01001388yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001389{
PavolVican75af21d2016-12-29 20:04:07 +01001390 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001391
PavolVican4b80d042017-02-23 14:30:27 +01001392 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001393 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1394 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001395 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001396 }
PavolVican75af21d2016-12-29 20:04:07 +01001397 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1398 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001399 LY_CHECK_ERR_RETURN(!deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001400 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1401 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001402 }
PavolVican75af21d2016-12-29 20:04:07 +01001403 dev->deviate[dev->deviate_size].mod = mod;
1404 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001405}
1406
1407int
PavolVican75af21d2016-12-29 20:04:07 +01001408yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001409{
1410 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001411 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001412
Pavol Vican85f12022016-03-05 16:30:35 +01001413 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001414 if (dev_target->nodetype == LYS_LEAFLIST) {
1415 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1416 } else if (dev_target->nodetype == LYS_LEAF) {
1417 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001418 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001419 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1420 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001421 goto error;
1422 }
1423
PavolVican75af21d2016-12-29 20:04:07 +01001424 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001425 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001426 if (!ly_strequal(*stritem, deviate->units, 1)) {
1427 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001428 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001429 goto error;
1430 }
1431 /* remove current units value of the target */
1432 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001433 *stritem = NULL;
1434 /* remove its extensions */
1435 j = -1;
1436 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1437 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1438 --j;
1439 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001440 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001441 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001442 /* check that there is no current value */
1443 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001444 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1445 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001446 goto error;
1447 }
1448 } else { /* replace */
1449 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001450 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1451 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001452 goto error;
1453 }
1454 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001455 /* remove current units value of the target ... */
1456 lydict_remove(ctx, *stritem);
1457
1458 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001459 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001460 }
1461
Pavol Vican85f12022016-03-05 16:30:35 +01001462 return EXIT_SUCCESS;
1463
1464error:
1465 return EXIT_FAILURE;
1466}
1467
1468int
PavolVican75af21d2016-12-29 20:04:07 +01001469yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001470{
Pavol Vican85f12022016-03-05 16:30:35 +01001471 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001472 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001473
1474 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001475 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001476 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1477 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001478 goto error;
1479 }
1480
PavolVican75af21d2016-12-29 20:04:07 +01001481 list = (struct lys_node_list *)dev_target;
1482 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001483 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001484 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001485 LY_CHECK_ERR_GOTO(!unique, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001486 list->unique = unique;
1487 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001488 }
1489
1490 return EXIT_SUCCESS;
1491
1492error:
1493 return EXIT_FAILURE;
1494}
1495
1496int
PavolVican75af21d2016-12-29 20:04:07 +01001497yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1498 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001499{
1500 struct lys_node *node;
1501 struct lys_node_choice *choice;
1502 struct lys_node_leaf *leaf;
1503 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001504 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001505 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001506
Pavol Vican38321d02016-08-16 14:56:02 +02001507 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001508 if (dev_target->nodetype == LYS_CHOICE) {
1509 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001510 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1511 if (rc || !node) {
1512 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1513 goto error;
1514 }
PavolVican75af21d2016-12-29 20:04:07 +01001515 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001516 if (!choice->dflt || (choice->dflt != node)) {
1517 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1518 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1519 goto error;
1520 }
PavolVican6f000922017-02-10 12:56:59 +01001521 choice->dflt = NULL;
1522 /* remove extensions of this default instance from the target node */
1523 j = -1;
1524 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1525 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1526 --j;
1527 }
Pavol Vican38321d02016-08-16 14:56:02 +02001528 } else { /* add or replace */
1529 choice->dflt = node;
1530 if (!choice->dflt) {
1531 /* default branch not found */
1532 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1533 goto error;
1534 }
1535 }
PavolVican75af21d2016-12-29 20:04:07 +01001536 } else if (dev_target->nodetype == LYS_LEAF) {
1537 leaf = (struct lys_node_leaf *)dev_target;
1538 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001539 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1540 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1541 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1542 goto error;
1543 }
1544 /* remove value */
1545 lydict_remove(ctx, leaf->dflt);
1546 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001547 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001548 /* remove extensions of this default instance from the target node */
1549 j = -1;
1550 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1551 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1552 --j;
1553 }
Pavol Vican38321d02016-08-16 14:56:02 +02001554 } else { /* add (already checked) and replace */
1555 /* remove value */
1556 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001557 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001558
1559 /* set new value */
1560 leaf->dflt = lydict_insert(ctx, value, u);
1561
1562 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001563 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001564 }
1565 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001566 llist = (struct lys_node_leaflist *)dev_target;
1567 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001568 /* find and remove the value in target list */
1569 for (i = 0; i < llist->dflt_size; i++) {
1570 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1571 /* match, remove the value */
1572 lydict_remove(llist->module->ctx, llist->dflt[i]);
1573 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001574 /* remove extensions of this default instance from the target node */
1575 j = -1;
1576 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1577 if (dev_target->ext[j]->insubstmt_index == i) {
1578 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1579 --j;
1580 } else if (dev_target->ext[j]->insubstmt_index > i) {
1581 /* decrease the substatement index of the extension because of the changed array of defaults */
1582 dev_target->ext[j]->insubstmt_index--;
1583 }
1584 }
Pavol Vican38321d02016-08-16 14:56:02 +02001585 break;
1586 }
1587 }
1588 if (i == llist->dflt_size) {
1589 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1590 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1591 goto error;
1592 }
1593 } else {
1594 /* add or replace, anyway we place items into the deviate's list
1595 which propagates to the target */
1596 /* we just want to check that the value isn't already in the list */
1597 for (i = 0; i < llist->dflt_size; i++) {
1598 if (ly_strequal(llist->dflt[i], value, 1)) {
1599 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1600 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1601 goto error;
1602 }
1603 }
1604 /* store it in target node */
1605 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1606
1607 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001608 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001609 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001610 }
1611 }
1612
1613 return EXIT_SUCCESS;
1614error:
1615 return EXIT_FAILURE;
1616}
1617
Pavol Vican38321d02016-08-16 14:56:02 +02001618int
PavolVican75af21d2016-12-29 20:04:07 +01001619yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1620 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001621{
PavolVican75af21d2016-12-29 20:04:07 +01001622 int i;
1623 struct lys_node_leaflist *llist;
1624 const char **dflt;
1625
1626 /* check target node type */
1627 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1628 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1629 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1630 goto error;
1631 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1632 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1633 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1634 goto error;
1635 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1636 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1637 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001638 goto error;
1639 }
1640
PavolVican75af21d2016-12-29 20:04:07 +01001641 if (deviate->mod == LY_DEVIATE_ADD) {
1642 /* check that there is no current value */
1643 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1644 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1645 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1646 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1647 goto error;
1648 }
Pavol Vican85f12022016-03-05 16:30:35 +01001649
PavolVican75af21d2016-12-29 20:04:07 +01001650 /* check collision with mandatory/min-elements */
1651 if ((dev_target->flags & LYS_MAND_TRUE) ||
1652 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1653 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1654 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1655 "Adding the \"default\" statement is forbidden on %s statement.",
1656 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1657 goto error;
1658 }
1659 } else if (deviate->mod == LY_DEVIATE_RPL) {
1660 /* check that there was a value before */
1661 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1662 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1663 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1664 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1665 goto error;
1666 }
1667 }
Pavol Vican85f12022016-03-05 16:30:35 +01001668
PavolVican75af21d2016-12-29 20:04:07 +01001669 if (dev_target->nodetype == LYS_LEAFLIST) {
1670 /* reallocate default list in the target */
1671 llist = (struct lys_node_leaflist *)dev_target;
1672 if (deviate->mod == LY_DEVIATE_ADD) {
1673 /* reallocate (enlarge) the unique array of the target */
1674 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001675 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001676 llist->dflt = dflt;
1677 } else if (deviate->mod == LY_DEVIATE_RPL) {
1678 /* reallocate (replace) the unique array of the target */
1679 for (i = 0; i < llist->dflt_size; i++) {
1680 lydict_remove(llist->module->ctx, llist->dflt[i]);
1681 }
1682 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001683 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001684 llist->dflt = dflt;
1685 llist->dflt_size = 0;
1686 }
1687 }
1688
1689 for (i = 0; i < deviate->dflt_size; ++i) {
1690 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1691 goto error;
1692 }
1693 }
Pavol Vican85f12022016-03-05 16:30:35 +01001694
1695 return EXIT_SUCCESS;
1696
1697error:
1698 return EXIT_FAILURE;
1699}
1700
1701int
PavolVican75af21d2016-12-29 20:04:07 +01001702yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001703{
Radek Krejcie00d2312016-08-12 15:27:49 +02001704 struct lys_node *parent;
1705
Pavol Vican85f12022016-03-05 16:30:35 +01001706 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001707 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001708 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1709 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001710 goto error;
1711 }
1712
PavolVican75af21d2016-12-29 20:04:07 +01001713 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001714 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001715 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001716 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1717 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001718 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001719 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001720 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001721 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1722 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1723 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1724 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001725 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001726 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1727 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1728 goto error;
1729 }
Pavol Vican85f12022016-03-05 16:30:35 +01001730 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001731 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001732 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001733 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1734 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001735 goto error;
1736 }
Pavol Vican85f12022016-03-05 16:30:35 +01001737 }
1738
Pavol Vican85f12022016-03-05 16:30:35 +01001739 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001740 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001741
1742 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001743 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001744
Radek Krejcie00d2312016-08-12 15:27:49 +02001745 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001746 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001747 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1748 parent = parent->parent) {
1749 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1750 /* stop also on presence containers */
1751 break;
1752 }
1753 }
1754 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1755 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1756 if (lyp_check_mandatory_choice(parent)) {
1757 goto error;
1758 }
1759 }
1760
Pavol Vican85f12022016-03-05 16:30:35 +01001761 return EXIT_SUCCESS;
1762
1763error:
1764 return EXIT_FAILURE;
1765}
1766
1767int
PavolVican75af21d2016-12-29 20:04:07 +01001768yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001769{
Pavol Vican09adcc32016-08-25 10:51:36 +02001770 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001771
1772 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001773 if (dev_target->nodetype == LYS_LEAFLIST) {
1774 max = &((struct lys_node_leaflist *)dev_target)->max;
1775 min = &((struct lys_node_leaflist *)dev_target)->min;
1776 } else if (dev_target->nodetype == LYS_LIST) {
1777 max = &((struct lys_node_list *)dev_target)->max;
1778 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001779 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001780 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1781 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"%s\" property.", (type) ? "max-elements" : "min-elements");
Pavol Vican85f12022016-03-05 16:30:35 +01001782 goto error;
1783 }
1784
PavolVican75af21d2016-12-29 20:04:07 +01001785 ui32val = (type) ? max : min;
1786 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001787 /* check that there is no current value */
1788 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001789 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1790 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001791 goto error;
1792 }
PavolVican75af21d2016-12-29 20:04:07 +01001793 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001794 /* unfortunately, there is no way to check reliably that there
1795 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001796 }
1797
1798 /* add (already checked) and replace */
1799 /* set new value specified in deviation */
1800 *ui32val = value;
1801
Pavol Vican09adcc32016-08-25 10:51:36 +02001802 /* check min-elements is smaller than max-elements */
1803 if (*max && *min > *max) {
1804 if (type) {
1805 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1806 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1807 } else {
1808 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1809 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1810 }
1811 goto error;
1812 }
1813
Pavol Vican85f12022016-03-05 16:30:35 +01001814 return EXIT_SUCCESS;
1815
1816error:
1817 return EXIT_FAILURE;
1818}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001819
1820int
PavolVican75af21d2016-12-29 20:04:07 +01001821yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1822 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001823{
PavolVican75af21d2016-12-29 20:04:07 +01001824 int i, j, erase_must = 1;
1825 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001826 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001827
PavolVican75af21d2016-12-29 20:04:07 +01001828 /* check target node type */
1829 switch (dev_target->nodetype) {
1830 case LYS_LEAF:
1831 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1832 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001833 break;
PavolVican75af21d2016-12-29 20:04:07 +01001834 case LYS_CONTAINER:
1835 trg_must = &((struct lys_node_container *)dev_target)->must;
1836 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1837 break;
1838 case LYS_LEAFLIST:
1839 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1840 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1841 break;
1842 case LYS_LIST:
1843 trg_must = &((struct lys_node_list *)dev_target)->must;
1844 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1845 break;
1846 case LYS_ANYXML:
1847 case LYS_ANYDATA:
1848 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1849 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1850 break;
1851 default:
1852 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1853 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1854 goto error;
1855 }
1856
1857 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001858 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001859
1860 if (deviate->mod == LY_DEVIATE_ADD) {
1861 /* reallocate the must array of the target */
1862 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001863 LY_CHECK_ERR_GOTO(!must, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001864 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001865 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001866 free(deviate->must);
1867 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001868 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001869 erase_must = 0;
1870 } else if (deviate->mod == LY_DEVIATE_DEL) {
1871 /* find must to delete, we are ok with just matching conditions */
1872 for (j = 0; j < deviate->must_size; ++j) {
1873 for (i = 0; i < *trg_must_size; i++) {
1874 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1875 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001876 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001877 /* ... and maintain the array */
1878 (*trg_must_size)--;
1879 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001880 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001881 }
1882 if (!(*trg_must_size)) {
1883 free(*trg_must);
1884 *trg_must = NULL;
1885 } else {
PavolVican214408f2017-02-03 11:54:05 +01001886 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001887 }
1888
1889 i = -1; /* set match flag */
1890 break;
1891 }
1892 }
1893 if (i != -1) {
1894 /* no match found */
1895 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1896 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1897 goto error;
1898 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001899 }
1900 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001901
PavolVican6f000922017-02-10 12:56:59 +01001902 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1903 goto error;
1904 }
PavolVican75af21d2016-12-29 20:04:07 +01001905 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02001906 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1907 && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001908 goto error;
1909 }
1910
PavolVican75af21d2016-12-29 20:04:07 +01001911 return EXIT_SUCCESS;
1912error:
1913 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1914 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001915 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001916 }
1917 free(deviate->must);
1918 }
1919 return EXIT_FAILURE;
1920}
1921
1922int
1923yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1924 struct lys_node_list *list, int index, char * value)
1925{
PavolVican6f000922017-02-10 12:56:59 +01001926 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001927
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001928 /* find unique structures to delete */
1929 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001930 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001931 continue;
1932 }
1933
PavolVican75af21d2016-12-29 20:04:07 +01001934 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1935 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001936 break;
1937 }
1938 }
1939
PavolVican75af21d2016-12-29 20:04:07 +01001940 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001941 /* we have a match, free the unique structure ... */
1942 for (j = 0; j < list->unique[i].expr_size; j++) {
1943 lydict_remove(module->ctx, list->unique[i].expr[j]);
1944 }
1945 free(list->unique[i].expr);
1946 /* ... and maintain the array */
1947 list->unique_size--;
1948 if (i != list->unique_size) {
1949 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1950 list->unique[i].expr = list->unique[list->unique_size].expr;
1951 }
1952
1953 if (!list->unique_size) {
1954 free(list->unique);
1955 list->unique = NULL;
1956 } else {
1957 list->unique[list->unique_size].expr_size = 0;
1958 list->unique[list->unique_size].expr = NULL;
1959 }
1960
PavolVican6f000922017-02-10 12:56:59 +01001961 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001962 i = -1; /* set match flag */
1963 break;
1964 }
1965 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001966
1967 if (i != -1) {
1968 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001969 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1970 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001971 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001972 }
1973
PavolVican6f000922017-02-10 12:56:59 +01001974 /* remove extensions of this unique instance from the target node */
1975 j = -1;
1976 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1977 if (list->ext[j]->insubstmt_index == k) {
1978 lyp_ext_instance_rm(module->ctx, &list->ext, &list->ext_size, j);
1979 --j;
1980 } else if (list->ext[j]->insubstmt_index > k) {
1981 /* decrease the substatement index of the extension because of the changed array of uniques */
1982 list->ext[j]->insubstmt_index--;
1983 }
1984 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001985 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001986}
Pavol Vican021488a2016-01-25 23:56:12 +01001987
PavolVican75af21d2016-12-29 20:04:07 +01001988int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01001989{
PavolVican75af21d2016-12-29 20:04:07 +01001990 struct lys_node_list *list;
1991 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01001992 uint i = 0;
1993 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01001994
PavolVican75af21d2016-12-29 20:04:07 +01001995 if (yang_read_deviate_unique(deviate, dev_target)) {
1996 goto error;
1997 }
1998 list = (struct lys_node_list *)dev_target;
1999 last_unique = &list->unique[list->unique_size];
2000 for (i = 0; i < deviate->unique_size; ++i) {
2001 str = (char *) deviate->unique[i].expr;
2002 if (deviate->mod == LY_DEVIATE_ADD) {
2003 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2004 free(str);
2005 goto error;
2006 }
2007 list->unique_size++;
2008 } else if (deviate->mod == LY_DEVIATE_DEL) {
2009 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2010 free(str);
2011 goto error;
2012 }
2013 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2014 free(str);
2015 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002016 }
2017 }
PavolVican75af21d2016-12-29 20:04:07 +01002018 free(str);
2019 }
2020 if (deviate->mod == LY_DEVIATE_ADD) {
2021 free(deviate->unique);
2022 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002023 }
Pavol Vican38321d02016-08-16 14:56:02 +02002024
Pavol Vican38321d02016-08-16 14:56:02 +02002025
PavolVican75af21d2016-12-29 20:04:07 +01002026 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002027error:
PavolVican75af21d2016-12-29 20:04:07 +01002028 if (deviate->mod == LY_DEVIATE_ADD) {
2029 for (i = i + 1; i < deviate->unique_size; ++i) {
2030 free(deviate->unique[i].expr);
2031 }
2032 free(deviate->unique);
2033 deviate->unique = last_unique;
2034
2035 }
Pavol Vican021488a2016-01-25 23:56:12 +01002036 return EXIT_FAILURE;
2037}
2038
Pavol Vicanec423c92016-10-24 21:33:43 +02002039static int
2040yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2041 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002042{
Pavol Vican55870412016-03-10 12:36:21 +01002043 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002044 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002045 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002046
Pavol Vicanec423c92016-10-24 21:33:43 +02002047 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002048 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002049 if (!rc) {
2050 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002051 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002052 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2053 &trg->inc[trg->inc_size], unres)) {
2054 ret = -1;
2055 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002056 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002057 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002058 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002059 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002060 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002061
Pavol Vicanec423c92016-10-24 21:33:43 +02002062 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002063 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002064}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002065
PavolVicanc1807262017-01-31 18:00:27 +01002066struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002067yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002068{
2069 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2070 LYEXT_PAR parent_type;
2071 uint8_t *size;
2072
2073 switch (type) {
2074 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002075 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002076 ext = &((struct lys_module *)node)->ext;
2077 size = &((struct lys_module *)node)->ext_size;
2078 parent_type = LYEXT_PAR_MODULE;
2079 break;
PavolVican22e88682017-02-14 22:38:18 +01002080 case BELONGS_TO_KEYWORD:
2081 if (is_ext_instance) {
2082 ext = &((struct lys_ext_instance *)node)->ext;
2083 size = &((struct lys_ext_instance *)node)->ext_size;
2084 parent_type = LYEXT_PAR_EXTINST;
2085 } else {
2086 ext = &((struct lys_module *)node)->ext;
2087 size = &((struct lys_module *)node)->ext_size;
2088 parent_type = LYEXT_PAR_MODULE;
2089 }
2090 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002091 case IMPORT_KEYWORD:
2092 ext = &((struct lys_import *)node)->ext;
2093 size = &((struct lys_import *)node)->ext_size;
2094 parent_type = LYEXT_PAR_IMPORT;
2095 break;
2096 case INCLUDE_KEYWORD:
2097 ext = &((struct lys_include *)node)->ext;
2098 size = &((struct lys_include *)node)->ext_size;
2099 parent_type = LYEXT_PAR_INCLUDE;
2100 break;
PavolVican171717d2017-02-01 14:49:55 +01002101 case REVISION_KEYWORD:
2102 ext = &((struct lys_revision *)node)->ext;
2103 size = &((struct lys_revision *)node)->ext_size;
2104 parent_type = LYEXT_PAR_REVISION;
2105 break;
PavolVican70ce7452017-02-01 15:39:39 +01002106 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002107 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002108 case LEAF_KEYWORD:
2109 case LEAF_LIST_KEYWORD:
2110 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002111 case CHOICE_KEYWORD:
2112 case CASE_KEYWORD:
2113 case ANYXML_KEYWORD:
2114 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002115 case USES_KEYWORD:
2116 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002117 case ACTION_KEYWORD:
2118 case RPC_KEYWORD:
2119 case INPUT_KEYWORD:
2120 case OUTPUT_KEYWORD:
2121 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002122 ext = &((struct lys_node *)node)->ext;
2123 size = &((struct lys_node *)node)->ext_size;
2124 parent_type = LYEXT_PAR_NODE;
2125 break;
PavolVican19dc6152017-02-06 12:04:15 +01002126 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002127 if (is_ext_instance) {
2128 ext = &((struct lys_ext_instance *)node)->ext;
2129 size = &((struct lys_ext_instance *)node)->ext_size;
2130 parent_type = LYEXT_PAR_EXTINST;
2131 } else {
2132 ext = &((struct lys_ext *)node)->ext;
2133 size = &((struct lys_ext *)node)->ext_size;
2134 parent_type = LYEXT_PAR_EXT;
2135 }
2136 break;
PavolVican19dc6152017-02-06 12:04:15 +01002137 case EXTENSION_KEYWORD:
2138 ext = &((struct lys_ext *)node)->ext;
2139 size = &((struct lys_ext *)node)->ext_size;
2140 parent_type = LYEXT_PAR_EXT;
2141 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002142 case FEATURE_KEYWORD:
2143 ext = &((struct lys_feature *)node)->ext;
2144 size = &((struct lys_feature *)node)->ext_size;
2145 parent_type = LYEXT_PAR_FEATURE;
2146 break;
PavolVican8fa31242017-02-07 11:04:26 +01002147 case IDENTITY_KEYWORD:
2148 ext = &((struct lys_ident *)node)->ext;
2149 size = &((struct lys_ident *)node)->ext_size;
2150 parent_type = LYEXT_PAR_IDENT;
2151 break;
2152 case IF_FEATURE_KEYWORD:
2153 ext = &((struct lys_iffeature *)node)->ext;
2154 size = &((struct lys_iffeature *)node)->ext_size;
2155 parent_type = LYEXT_PAR_IFFEATURE;
2156 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002157 case TYPEDEF_KEYWORD:
2158 ext = &((struct lys_tpdf *)node)->ext;
2159 size = &((struct lys_tpdf *)node)->ext_size;
2160 parent_type = LYEXT_PAR_TPDF;
2161 break;
PavolVican056fcd12017-02-07 15:36:53 +01002162 case TYPE_KEYWORD:
2163 ext = &((struct yang_type *)node)->type->ext;
2164 size = &((struct yang_type *)node)->type->ext_size;
2165 parent_type = LYEXT_PAR_TYPE;
2166 break;
2167 case LENGTH_KEYWORD:
2168 case PATTERN_KEYWORD:
2169 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002170 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002171 ext = &((struct lys_restr *)node)->ext;
2172 size = &((struct lys_restr *)node)->ext_size;
2173 parent_type = LYEXT_PAR_RESTR;
2174 break;
PavolVican59ba4602017-02-08 11:53:32 +01002175 case WHEN_KEYWORD:
2176 ext = &((struct lys_when *)node)->ext;
2177 size = &((struct lys_when *)node)->ext_size;
2178 parent_type = LYEXT_PAR_RESTR;
2179 break;
PavolVican056fcd12017-02-07 15:36:53 +01002180 case ENUM_KEYWORD:
2181 ext = &((struct lys_type_enum *)node)->ext;
2182 size = &((struct lys_type_enum *)node)->ext_size;
2183 parent_type = LYEXT_PAR_TYPE_ENUM;
2184 break;
2185 case BIT_KEYWORD:
2186 ext = &((struct lys_type_bit *)node)->ext;
2187 size = &((struct lys_type_bit *)node)->ext_size;
2188 parent_type = LYEXT_PAR_TYPE_BIT;
2189 break;
PavolVican77374ee2017-02-08 15:18:45 +01002190 case REFINE_KEYWORD:
2191 ext = &((struct lys_type_bit *)node)->ext;
2192 size = &((struct lys_type_bit *)node)->ext_size;
2193 parent_type = LYEXT_PAR_REFINE;
2194 break;
PavolVican6f000922017-02-10 12:56:59 +01002195 case DEVIATION_KEYWORD:
2196 ext = &((struct lys_deviation *)node)->ext;
2197 size = &((struct lys_deviation *)node)->ext_size;
2198 parent_type = LYEXT_PAR_DEVIATION;
2199 break;
2200 case NOT_SUPPORTED_KEYWORD:
2201 case ADD_KEYWORD:
2202 case DELETE_KEYWORD:
2203 case REPLACE_KEYWORD:
2204 ext = &((struct lys_deviate *)node)->ext;
2205 size = &((struct lys_deviate *)node)->ext_size;
2206 parent_type = LYEXT_PAR_DEVIATE;
2207 break;
PavolVicandefa4852017-02-10 13:13:23 +01002208 case EXTENSION_INSTANCE:
2209 ext = &((struct lys_ext_instance *)node)->ext;
2210 size = &((struct lys_ext_instance *)node)->ext_size;
2211 parent_type = LYEXT_PAR_EXTINST;
2212 break;
PavolVicanc1807262017-01-31 18:00:27 +01002213 default:
2214 LOGINT;
2215 return NULL;
2216 }
2217
2218 instance = calloc(1, sizeof *instance);
2219 if (!instance) {
2220 goto error;
2221 }
2222 instance->parent_type = parent_type;
2223 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2224 if (!tmp) {
2225 goto error;
2226 }
2227 tmp[*size] = instance;
2228 *ext = tmp;
2229 (*size)++;
2230 return instance;
2231
2232error:
2233 LOGMEM;
2234 free(instance);
2235 return NULL;
2236}
2237
2238void *
2239yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002240 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002241{
2242 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002243 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002244
2245 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002246 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002247 if (!instance) {
2248 return NULL;
2249 }
PavolVicanc1807262017-01-31 18:00:27 +01002250 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002251 case YANG_VERSION_KEYWORD:
2252 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002253 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002254 break;
PavolVicanc1807262017-01-31 18:00:27 +01002255 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002256 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002257 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002258 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002259 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002260 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002261 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002262 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002263 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002264 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002265 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002266 break;
2267 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002268 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002269 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002270 break;
2271 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002272 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002273 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002274 break;
PavolVican171717d2017-02-01 14:49:55 +01002275 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002276 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002277 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002278 break;
2279 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002280 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002281 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002282 break;
PavolVican19dc6152017-02-06 12:04:15 +01002283 case YIN_ELEMENT_KEYWORD:
2284 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002285 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002286 break;
2287 case STATUS_KEYWORD:
2288 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002289 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002290 break;
PavolVican8fa31242017-02-07 11:04:26 +01002291 case BASE_KEYWORD:
2292 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002293 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002294 if (backup_type == IDENTITY_KEYWORD) {
2295 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002296 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002297 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2298 }
PavolVican8fa31242017-02-07 11:04:26 +01002299 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002300 case DEFAULT_KEYWORD:
2301 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002302 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002303 switch (backup_type) {
2304 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002305 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002306 break;
2307 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002308 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002309 break;
2310 case ADD_KEYWORD:
2311 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2312 break;
2313 default:
2314 /* nothing changes */
2315 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002316 }
PavolVicandf9e7972017-02-07 11:41:38 +01002317 break;
2318 case UNITS_KEYWORD:
2319 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002320 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002321 break;
PavolVican056fcd12017-02-07 15:36:53 +01002322 case REQUIRE_INSTANCE_KEYWORD:
2323 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002324 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002325 break;
2326 case PATH_KEYWORD:
2327 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002328 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002329 break;
2330 case ERROR_MESSAGE_KEYWORD:
2331 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002332 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002333 break;
2334 case ERROR_APP_TAG_KEYWORD:
2335 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002336 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002337 break;
2338 case MODIFIER_KEYWORD:
2339 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002340 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002341 break;
2342 case FRACTION_DIGITS_KEYWORD:
2343 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002344 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002345 break;
2346 case VALUE_KEYWORD:
2347 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002348 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002349 break;
2350 case POSITION_KEYWORD:
2351 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002352 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002353 break;
PavolVican5b910842017-02-08 13:08:47 +01002354 case PRESENCE_KEYWORD:
2355 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002356 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002357 break;
2358 case CONFIG_KEYWORD:
2359 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002360 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002361 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002362 case MANDATORY_KEYWORD:
2363 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002364 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002365 break;
2366 case MIN_ELEMENTS_KEYWORD:
2367 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002368 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002369 break;
2370 case MAX_ELEMENTS_KEYWORD:
2371 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002372 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002373 break;
2374 case ORDERED_BY_KEYWORD:
2375 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002376 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002377 break;
2378 case KEY_KEYWORD:
2379 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002380 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002381 break;
2382 case UNIQUE_KEYWORD:
2383 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002384 stmt = LY_STMT_UNIQUE;
2385 switch (backup_type) {
2386 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002387 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002388 break;
2389 case ADD_KEYWORD:
2390 case DELETE_KEYWORD:
2391 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002392 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002393 break;
2394 default:
2395 /* nothing changes */
2396 break;
PavolVican6f000922017-02-10 12:56:59 +01002397 }
PavolVican3feb2f92017-02-08 13:44:39 +01002398 break;
PavolVicanc1807262017-01-31 18:00:27 +01002399 default:
2400 LOGINT;
2401 return NULL;
2402 }
2403 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002404 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002405 if (!instance) {
2406 return NULL;
2407 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002408 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002409 switch (actual_type) {
2410 case ARGUMENT_KEYWORD:
2411 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002412 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002413 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002414 case BELONGS_TO_KEYWORD:
2415 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002416 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002417 break;
PavolVican19dc6152017-02-06 12:04:15 +01002418 default:
2419 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2420 break;
2421 }
PavolVicanc1807262017-01-31 18:00:27 +01002422 }
2423 instance->flags |= LYEXT_OPT_YANG;
2424 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2425 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002426 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2427 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2428 }
PavolVicanc1807262017-01-31 18:00:27 +01002429 return instance;
2430}
2431
PavolVican05c4f9b2017-09-07 13:33:54 +02002432static int
2433check_status_flag(struct lys_node *node, struct lys_node *parent)
2434{
2435 char *str;
2436
Radek Krejcie4dce292017-10-30 11:16:47 +01002437 if (node->nodetype & (LYS_OUTPUT | LYS_INPUT)) {
2438 return EXIT_SUCCESS;
2439 }
2440
PavolVican05c4f9b2017-09-07 13:33:54 +02002441 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2442 /* status is not inherited by specification, but it not make sense to have
2443 * current in deprecated or deprecated in obsolete, so we print warning
2444 * and fix the schema by inheriting */
2445 if (!(node->flags & (LYS_STATUS_MASK))) {
2446 /* status not explicitely specified on the current node -> inherit */
Michal Vasko395b0a02018-01-22 09:36:20 +01002447 str = lys_path(node, LYS_PATH_FIRST_PREFIX);
PavolVican05c4f9b2017-09-07 13:33:54 +02002448 LOGWRN("Missing status in %s subtree (%s), inheriting.",
2449 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2450 free(str);
2451 node->flags |= parent->flags & LYS_STATUS_MASK;
2452 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2453 /* invalid combination of statuses */
2454 switch (node->flags & LYS_STATUS_MASK) {
2455 case 0:
2456 case LYS_STATUS_CURR:
2457 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
2458 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2459 break;
2460 case LYS_STATUS_DEPRC:
2461 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
2462 "obsolete", parent->name);
2463 break;
2464 }
2465 return EXIT_FAILURE;
2466 }
2467 }
2468
2469 return EXIT_SUCCESS;
2470}
2471
Pavol Vicanf4717e62016-03-16 11:30:01 +01002472int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002473store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002474{
Pavol Vicanec598812016-11-30 14:13:38 +01002475 switch (node->nodetype) {
2476 case LYS_CONTAINER:
2477 case LYS_LEAF:
2478 case LYS_LEAFLIST:
2479 case LYS_LIST:
2480 case LYS_CHOICE:
2481 case LYS_ANYDATA:
2482 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002483 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002484 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002485 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002486 if (!(node->flags & LYS_CONFIG_MASK)) {
2487 /* get config flag from parent */
2488 if (node->parent) {
2489 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2490 } else {
2491 /* default config is true */
2492 node->flags |= LYS_CONFIG_W;
2493 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002494 }
2495 }
Pavol Vicanec598812016-11-30 14:13:38 +01002496 break;
2497 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002498 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002499 if (!(node->flags & LYS_CONFIG_MASK)) {
2500 /* get config flag from parent */
2501 if (node->parent) {
2502 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2503 } else {
2504 /* default config is true */
2505 node->flags |= LYS_CONFIG_W;
2506 }
2507 }
2508 }
2509 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002510 default:
2511 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002512 }
Pavol Vicanec598812016-11-30 14:13:38 +01002513
Radek Krejci7212e0a2017-03-08 15:58:22 +01002514 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002515}
2516
2517int
Pavol Vican9d50a772016-10-14 22:23:36 +02002518yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2519 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002520{
Pavol Vican974377b2016-03-23 00:38:53 +01002521 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002522 YY_BUFFER_STATE bp;
2523 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002524 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002525 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002526 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002527
Pavol Vican8e7110b2016-03-22 17:00:26 +01002528 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002529 yylex_init(&scanner);
2530 bp = yy_scan_buffer((char *)data, size, scanner);
2531 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002532 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002533 param.module = module;
2534 param.submodule = submodule;
2535 param.unres = unres;
2536 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002537 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002538 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002539 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002540 trg = (submodule) ? (struct lys_module *)submodule : module;
2541 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2542 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2543 trg->inc_size = 0;
2544 trg->imp_size = 0;
2545 }
PavolVican22e88682017-02-14 22:38:18 +01002546 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2547 }
2548 yy_delete_buffer(bp, scanner);
2549 yylex_destroy(scanner);
2550 return ret;
2551}
2552
2553int
2554yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2555 char *ext_name, struct lys_ext_instance_complex *ext)
2556{
2557 unsigned int size;
2558 YY_BUFFER_STATE bp;
2559 yyscan_t scanner = NULL;
2560 int ret = 0;
2561 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002562 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002563
PavolVicandb0e8172017-02-20 00:46:09 +01002564 if (!data) {
2565 return EXIT_SUCCESS;
2566 }
PavolVican22e88682017-02-14 22:38:18 +01002567 size = strlen(data) + 2;
2568 yylex_init(&scanner);
2569 bp = yy_scan_buffer((char *)data, size, scanner);
2570 yy_switch_to_buffer(bp, scanner);
2571 memset(&param, 0, sizeof param);
2572 param.module = module;
2573 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002574 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002575 param.actual_node = (void **)ext;
2576 param.data_node = (void **)ext_name;
2577 param.flags |= EXT_INSTANCE_SUBSTMT;
2578 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002579 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002580 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002581 } else {
2582 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002583 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002584 ret = -1;
2585 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002586 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002587 yy_delete_buffer(bp, scanner);
2588 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002589 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002590}
2591
2592struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002593yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002594{
2595
PavolVican9e81c6a2017-02-09 13:09:07 +01002596 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002597 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002598 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002599 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002600
2601 unres = calloc(1, sizeof *unres);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002602 LY_CHECK_ERR_GOTO(!unres, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002603
2604 module = calloc(1, sizeof *module);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002605 LY_CHECK_ERR_GOTO(!module, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002606
2607 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002608 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002609 module->type = 0;
2610 module->implemented = (implement ? 1 : 0);
2611
Radek Krejci9e757e02017-03-08 17:18:09 +01002612 /* add into the list of processed modules */
2613 if (lyp_check_circmod_add(module)) {
2614 goto error;
2615 }
2616
PavolVican9e81c6a2017-02-09 13:09:07 +01002617 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2618 if (ret == -1) {
Radek Krejci95e00a42017-11-02 16:29:22 +01002619 if (ly_vecode == LYVE_SUBMODULE) {
2620 free(module);
2621 module = NULL;
2622 } else {
2623 free_yang_common(module, node);
2624 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002625 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002626 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002627 assert(!unres->count);
2628 } else {
2629 if (yang_check_sub_module(module, unres, node)) {
2630 goto error;
2631 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002632
Michal Vasko7b460e52017-02-10 14:50:26 +01002633 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002634 goto error;
2635 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002636 }
2637
PavolVicanfe83b152017-02-19 03:19:29 +01002638 lyp_sort_revisions(module);
2639
Pavol Vican8e7110b2016-03-22 17:00:26 +01002640 if (revision) {
2641 /* check revision of the parsed model */
2642 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2643 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2644 module->name, module->rev[0].date, revision);
2645 goto error;
2646 }
2647 }
2648
PavolVican9e81c6a2017-02-09 13:09:07 +01002649 /* add into context if not already there */
2650 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002651 /* check correctness of includes */
2652 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002653 goto error;
2654 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002655
PavolVican6f000922017-02-10 12:56:59 +01002656 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002657 goto error;
2658 }
2659
PavolVican9e81c6a2017-02-09 13:09:07 +01002660 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002661 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002662 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002663
2664 if (module->deviation_size && !module->implemented) {
2665 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2666 /* deviations always causes target to be made implemented,
2667 * but augents and leafrefs not, so we have to apply them now */
2668 if (lys_set_implemented(module)) {
2669 goto error;
2670 }
2671 }
Michal Vasko10681e82018-01-16 14:54:16 +01002672
2673 /* remove our submodules from the parsed submodules list */
2674 lyp_del_includedup(module, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002675 } else {
2676 tmp_mod = module;
2677
2678 /* get the model from the context */
Radek Krejcidfb00d62017-09-06 09:39:35 +02002679 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002680 assert(module);
2681
2682 /* free what was parsed */
Michal Vasko10681e82018-01-16 14:54:16 +01002683 lys_free(tmp_mod, NULL, 0, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002684 }
2685
Michal Vasko44ab1462017-05-18 13:18:36 +02002686 unres_schema_free(NULL, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002687 lyp_check_circmod_pop(ctx);
Michal Vaskobe136f62017-09-21 12:08:39 +02002688 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2689 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002690 return module;
2691
2692error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002693 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002694 unres_schema_free(module, &unres, 1);
Radek Krejcif505cd12017-06-13 10:32:48 +02002695 if (!module) {
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002696 if (ly_vecode != LYVE_SUBMODULE) {
2697 LOGERR(ly_errno, "Module parsing failed.");
2698 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002699 return NULL;
2700 }
2701
Radek Krejcif505cd12017-06-13 10:32:48 +02002702 if (module->name) {
2703 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
2704 } else {
2705 LOGERR(ly_errno, "Module parsing failed.");
2706 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002707
Radek Krejci9e757e02017-03-08 17:18:09 +01002708 lyp_check_circmod_pop(ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002709 lys_sub_module_remove_devs_augs(module);
Michal Vasko10681e82018-01-16 14:54:16 +01002710 lyp_del_includedup(module, 1);
2711 lys_free(module, NULL, 0, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002712 return NULL;
2713}
2714
2715struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002716yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002717{
2718 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002719 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002720
2721 submodule = calloc(1, sizeof *submodule);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002722 LY_CHECK_ERR_GOTO(!submodule, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002723
2724 submodule->ctx = module->ctx;
2725 submodule->type = 1;
Radek Krejci29eac3d2017-06-01 16:50:02 +02002726 submodule->implemented = module->implemented;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002727 submodule->belongsto = module;
2728
Radek Krejci9e757e02017-03-08 17:18:09 +01002729 /* add into the list of processed modules */
2730 if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2731 goto error;
2732 }
2733
PavolVican9e81c6a2017-02-09 13:09:07 +01002734 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002735 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002736 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002737 goto error;
2738 }
2739
PavolVicanfe83b152017-02-19 03:19:29 +01002740 lyp_sort_revisions((struct lys_module *)submodule);
2741
Pavol Vican7313fc02016-11-14 01:10:31 +01002742 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002743 goto error;
2744 }
2745
Radek Krejci9e757e02017-03-08 17:18:09 +01002746 lyp_check_circmod_pop(module->ctx);
2747
Pavol Vican8e7110b2016-03-22 17:00:26 +01002748 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002749 return submodule;
2750
2751error:
2752 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002753 if (!submodule || !submodule->name) {
2754 free(submodule);
2755 LOGERR(ly_errno, "Submodule parsing failed.");
2756 return NULL;
2757 }
2758
2759 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2760
Michal Vaskoa9728122018-01-16 14:00:13 +01002761 unres_schema_free((struct lys_module *)submodule, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002762 lyp_check_circmod_pop(module->ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002763 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2764 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002765 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002766 return NULL;
2767}
Pavol Vican8760bb72016-04-07 09:44:01 +02002768
2769static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002770read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2771{
2772 int k = 0, j;
2773
2774 while (in_index < size) {
2775 if (input[in_index] == ' ') {
2776 k++;
2777 } else if (input[in_index] == '\t') {
2778 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2779 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002780 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2781 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2782 k += 8;
2783 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002784 } else {
2785 break;
2786 }
2787 ++in_index;
2788 if (k >= indent) {
2789 for (j = k - indent; j > 0; --j) {
2790 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002791 if (j > 1) {
2792 ++(*out_index);
2793 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002794 }
2795 break;
2796 }
2797 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002798 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002799}
2800
2801char *
PavolVican1bc22062017-01-19 15:09:04 +01002802yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002803 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002804
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002805 while (i < size) {
2806 switch (input[i]) {
2807 case '\n':
2808 out_index -= space;
2809 output[out_index] = '\n';
2810 space = 0;
2811 i = read_indent(input, indent, size, i + 1, &out_index, output);
2812 break;
2813 case ' ':
2814 case '\t':
2815 output[out_index] = input[i];
2816 ++space;
2817 break;
2818 case '\\':
2819 if (input[i + 1] == 'n') {
2820 out_index -= space;
2821 output[out_index] = '\n';
2822 space = 0;
2823 i = read_indent(input, indent, size, i + 2, &out_index, output);
2824 } else if (input[i + 1] == 't') {
2825 output[out_index] = '\t';
2826 ++i;
2827 ++space;
2828 } else if (input[i + 1] == '\\') {
2829 output[out_index] = '\\';
2830 ++i;
2831 } else if ((i + 1) != size && input[i + 1] == '"') {
2832 output[out_index] = '"';
2833 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002834 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002835 /* backslash must not be followed by any other character */
2836 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2837 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002838 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002839 break;
2840 default:
2841 output[out_index] = input[i];
2842 space = 0;
2843 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002844 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002845 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002846 ++out_index;
2847 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002848 output[out_index] = '\0';
2849 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002850 output = realloc(output, out_index + 1);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002851 LY_CHECK_ERR_RETURN(!output, LOGMEM, NULL);
Pavol Vican8760bb72016-04-07 09:44:01 +02002852 }
Pavol Vican3f598892016-09-28 15:41:07 +02002853 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002854}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002855
2856/* free function */
2857
PavolVicana0fdbf32017-02-15 17:59:02 +01002858void
2859yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002860{
2861 struct yang_type *stype = (struct yang_type *)type->der;
Radek Krejcidce5f972017-09-12 15:47:49 +02002862 unsigned int i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002863
2864 if (!stype) {
2865 return ;
2866 }
PavolVicane87cb932016-12-30 15:36:18 +01002867 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2868 lydict_remove(ctx, stype->name);
2869 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2870 for (i = 0; i < type->info.ident.count; ++i) {
2871 free(type->info.ident.ref[i]);
2872 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002873 }
PavolVicane87cb932016-12-30 15:36:18 +01002874 if (stype->base == LY_TYPE_UNION) {
2875 for (i = 0; i < type->info.uni.count; ++i) {
2876 yang_type_free(ctx, &type->info.uni.types[i]);
2877 }
2878 free(type->info.uni.types);
2879 type->base = LY_TYPE_DER;
2880 } else {
2881 type->base = stype->base;
2882 }
2883 free(stype);
2884 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002885 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02002886 lys_type_free(ctx, type, NULL);
Radek Krejci0ec2cc52017-11-09 16:30:12 +01002887 memset(type, 0, sizeof (struct lys_type));
Pavol Vican7313fc02016-11-14 01:10:31 +01002888}
2889
2890static void
Radek Krejcia2ac9262017-09-12 16:39:04 +02002891yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint16_t start, uint16_t size)
Pavol Vican7313fc02016-11-14 01:10:31 +01002892{
2893 uint8_t i;
2894
2895 assert(ctx);
2896 if (!tpdf) {
2897 return;
2898 }
2899
2900 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002901 lydict_remove(ctx, tpdf[i].name);
2902 lydict_remove(ctx, tpdf[i].dsc);
2903 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002904
Pavol Vicancee10802016-11-22 15:48:35 +01002905 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002906
Pavol Vicancee10802016-11-22 15:48:35 +01002907 lydict_remove(ctx, tpdf[i].units);
2908 lydict_remove(ctx, tpdf[i].dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002909 lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
Pavol Vican7313fc02016-11-14 01:10:31 +01002910 }
2911}
2912
Pavol Vican1cc4e192016-10-24 16:38:31 +02002913static void
2914yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2915{
2916 uint8_t i;
2917
2918 for (i = start; i < size; ++i){
2919 free((char *)imp[i].module);
2920 lydict_remove(ctx, imp[i].prefix);
2921 lydict_remove(ctx, imp[i].dsc);
2922 lydict_remove(ctx, imp[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002923 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002924 }
2925}
2926
Pavol Vicanec423c92016-10-24 21:33:43 +02002927static void
2928yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2929{
2930 uint8_t i;
2931
2932 for (i = start; i < size; ++i){
2933 free((char *)inc[i].submodule);
2934 lydict_remove(ctx, inc[i].dsc);
2935 lydict_remove(ctx, inc[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002936 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
Pavol Vicanec423c92016-10-24 21:33:43 +02002937 }
2938}
2939
Pavol Vican36e27272016-11-22 15:47:28 +01002940static void
2941yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2942{
2943 uint32_t i;
2944 uint8_t j;
2945
2946 /* free base name */
2947 for (i = start; i < size; ++i) {
2948 for (j = 0; j < ident[i].base_size; ++j) {
2949 free(ident[i].base[j]);
2950 }
2951 }
2952}
2953
Pavol Vican05810b62016-11-23 14:07:22 +01002954static void
2955yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2956{
2957 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2958 free(grp->tpdf);
2959}
2960
2961static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002962yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2963{
2964 uint8_t i;
2965
2966 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2967 free(cont->tpdf);
2968 lydict_remove(ctx, cont->presence);
2969
Pavol Vicanfda8c802016-12-03 02:00:42 +01002970 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002971 lys_restr_free(ctx, &cont->must[i], NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002972 }
2973 free(cont->must);
2974
Radek Krejci5138e9f2017-04-12 13:10:46 +02002975 lys_when_free(ctx, cont->when, NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002976}
2977
2978static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002979yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2980{
2981 uint8_t i;
2982
2983 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002984 lys_restr_free(ctx, &leaf->must[i], NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002985 }
2986 free(leaf->must);
2987
Radek Krejci5138e9f2017-04-12 13:10:46 +02002988 lys_when_free(ctx, leaf->when, NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002989
2990 yang_type_free(ctx, &leaf->type);
2991 lydict_remove(ctx, leaf->units);
2992 lydict_remove(ctx, leaf->dflt);
2993}
2994
2995static void
Pavol Vican36aff862016-11-26 17:07:05 +01002996yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2997{
2998 uint8_t i;
2999
3000 for (i = 0; i < leaflist->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003001 lys_restr_free(ctx, &leaflist->must[i], NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003002 }
3003 free(leaflist->must);
3004
3005 for (i = 0; i < leaflist->dflt_size; i++) {
3006 lydict_remove(ctx, leaflist->dflt[i]);
3007 }
3008 free(leaflist->dflt);
3009
Radek Krejci5138e9f2017-04-12 13:10:46 +02003010 lys_when_free(ctx, leaflist->when, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003011
3012 yang_type_free(ctx, &leaflist->type);
3013 lydict_remove(ctx, leaflist->units);
3014}
3015
3016static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003017yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3018{
3019 uint8_t i;
3020
3021 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3022 free(list->tpdf);
3023
3024 for (i = 0; i < list->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003025 lys_restr_free(ctx, &list->must[i], NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003026 }
3027 free(list->must);
3028
Radek Krejci5138e9f2017-04-12 13:10:46 +02003029 lys_when_free(ctx, list->when, NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003030
3031 for (i = 0; i < list->unique_size; ++i) {
3032 free(list->unique[i].expr);
3033 }
3034 free(list->unique);
3035
3036 free(list->keys);
3037}
3038
3039static void
Pavol Vican36ace102016-11-28 11:46:59 +01003040yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3041{
3042 free(choice->dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003043 lys_when_free(ctx, choice->when, NULL);
Pavol Vican36ace102016-11-28 11:46:59 +01003044}
3045
3046static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003047yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3048{
3049 uint8_t i;
3050
3051 for (i = 0; i < anydata->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003052 lys_restr_free(ctx, &anydata->must[i], NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003053 }
3054 free(anydata->must);
3055
Radek Krejci5138e9f2017-04-12 13:10:46 +02003056 lys_when_free(ctx, anydata->when, NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003057}
3058
3059static void
Pavol Vican78729392016-11-28 17:18:22 +01003060yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3061{
3062 uint8_t i;
3063
3064 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3065 free(inout->tpdf);
3066
3067 for (i = 0; i < inout->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003068 lys_restr_free(ctx, &inout->must[i], NULL);
Pavol Vican78729392016-11-28 17:18:22 +01003069 }
3070 free(inout->must);
3071}
3072
3073static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003074yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3075{
3076 uint8_t i;
3077
3078 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3079 free(notif->tpdf);
3080
3081 for (i = 0; i < notif->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003082 lys_restr_free(ctx, &notif->must[i], NULL);
Pavol Vican29bf8802016-11-28 20:44:57 +01003083 }
3084 free(notif->must);
3085}
3086
3087static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003088yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3089{
3090 int i, j;
3091
3092 for (i = 0; i < uses->refine_size; i++) {
3093 lydict_remove(ctx, uses->refine[i].target_name);
3094 lydict_remove(ctx, uses->refine[i].dsc);
3095 lydict_remove(ctx, uses->refine[i].ref);
3096
3097 for (j = 0; j < uses->refine[i].must_size; j++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003098 lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003099 }
3100 free(uses->refine[i].must);
3101
3102 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3103 lydict_remove(ctx, uses->refine[i].dflt[j]);
3104 }
3105 free(uses->refine[i].dflt);
3106
3107 if (uses->refine[i].target_type & LYS_CONTAINER) {
3108 lydict_remove(ctx, uses->refine[i].mod.presence);
3109 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003110 lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003111 }
3112 free(uses->refine);
3113
Radek Krejci5138e9f2017-04-12 13:10:46 +02003114 lys_when_free(ctx, uses->when, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003115}
3116
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003117static void
Pavol Vican05810b62016-11-23 14:07:22 +01003118yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3119{
3120 struct lys_node *tmp, *child, *sibling;
3121
3122 if (!node) {
3123 return;
3124 }
3125 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003126
3127 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003128 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003129 sibling = tmp->next;
3130 /* common part */
3131 lydict_remove(ctx, tmp->name);
3132 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003133 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003134 lydict_remove(ctx, tmp->dsc);
3135 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003136 }
3137
3138 switch (tmp->nodetype) {
3139 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003140 case LYS_RPC:
3141 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003142 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3143 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003144 case LYS_CONTAINER:
3145 yang_free_container(ctx, (struct lys_node_container *)tmp);
3146 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003147 case LYS_LEAF:
3148 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3149 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003150 case LYS_LEAFLIST:
3151 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3152 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003153 case LYS_LIST:
3154 yang_free_list(ctx, (struct lys_node_list *)tmp);
3155 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003156 case LYS_CHOICE:
3157 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3158 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003159 case LYS_CASE:
Radek Krejci5138e9f2017-04-12 13:10:46 +02003160 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
Pavol Vicana420bac2016-11-28 14:51:54 +01003161 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003162 case LYS_ANYXML:
3163 case LYS_ANYDATA:
3164 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3165 break;
Pavol Vican78729392016-11-28 17:18:22 +01003166 case LYS_INPUT:
3167 case LYS_OUTPUT:
3168 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3169 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003170 case LYS_NOTIF:
3171 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3172 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003173 case LYS_USES:
3174 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3175 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003176 default:
3177 break;
3178 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003179 lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
Pavol Vican05810b62016-11-23 14:07:22 +01003180 yang_free_nodes(ctx, child);
3181 free(tmp);
3182 tmp = sibling;
3183 }
3184}
3185
Pavol Vican3ad50f82016-12-04 15:00:36 +01003186static void
3187yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3188{
3189 lydict_remove(ctx, aug->target_name);
3190 lydict_remove(ctx, aug->dsc);
3191 lydict_remove(ctx, aug->ref);
3192
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003193 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003194 lys_when_free(ctx, aug->when, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003195 yang_free_nodes(ctx, aug->child);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003196 lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003197}
3198
PavolVican75af21d2016-12-29 20:04:07 +01003199static void
3200yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3201{
3202 uint i, j;
3203
3204 for (i = index; i < dev->deviate_size; ++i) {
3205 lydict_remove(ctx, dev->deviate[i].units);
3206
3207 if (dev->deviate[i].type) {
3208 yang_type_free(ctx, dev->deviate[i].type);
3209 }
3210
3211 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3212 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3213 }
3214 free(dev->deviate[i].dflt);
3215
3216 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003217 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003218 }
3219 free(dev->deviate[i].must);
3220
3221 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3222 free(dev->deviate[i].unique[j].expr);
3223 }
3224 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003225 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003226 }
3227}
3228
PavolVicandb0e8172017-02-20 00:46:09 +01003229void
3230yang_free_ext_data(struct yang_ext_substmt *substmt)
3231{
3232 int i;
3233
3234 if (!substmt) {
3235 return;
3236 }
3237
3238 free(substmt->ext_substmt);
3239 if (substmt->ext_modules) {
3240 for (i = 0; substmt->ext_modules[i]; ++i) {
3241 free(substmt->ext_modules[i]);
3242 }
3243 free(substmt->ext_modules);
3244 }
3245 free(substmt);
3246}
3247
Pavol Vican7313fc02016-11-14 01:10:31 +01003248/* free common item from module and submodule */
3249static void
Pavol Vican05810b62016-11-23 14:07:22 +01003250free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003251{
PavolVican75af21d2016-12-29 20:04:07 +01003252 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003253 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3254 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003255 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003256 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003257 for (i = 0; i < module->augment_size; ++i) {
3258 yang_free_augment(module->ctx, &module->augment[i]);
3259 }
3260 module->augment_size = 0;
3261 for (i = 0; i < module->deviation_size; ++i) {
3262 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3263 free(module->deviation[i].deviate);
3264 }
3265 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003266}
3267
Pavol Vican1cc4e192016-10-24 16:38:31 +02003268/* check function*/
3269
3270int
PavolVicanc1807262017-01-31 18:00:27 +01003271yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3272 void *parent, struct unres_schema *unres)
3273{
3274 struct unres_ext *info;
3275 uint i;
3276
3277 for (i = 0; i < size; ++i) {
3278 info = malloc(sizeof *info);
Radek Krejcia8d111f2017-05-31 13:57:37 +02003279 LY_CHECK_ERR_RETURN(!info, LOGMEM, EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003280 info->data.yang = (*ext)[i]->parent;
3281 info->datatype = LYS_IN_YANG;
3282 info->parent = parent;
3283 info->mod = module;
3284 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003285 info->substmt = (*ext)[i]->insubstmt;
3286 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003287 info->ext_index = i;
3288 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3289 return EXIT_FAILURE;
3290 }
3291 }
3292
3293 return EXIT_SUCCESS;
3294}
3295
3296int
Pavol Vicanec423c92016-10-24 21:33:43 +02003297yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003298{
3299 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003300 struct lys_include *inc;
3301 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003302 char *s;
3303
3304 imp = module->imp;
3305 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003306 inc = module->inc;
3307 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003308
3309 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003310 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003311 module->imp_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003312 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM, error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003313 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003314
Pavol Vicanec423c92016-10-24 21:33:43 +02003315 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003316 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003317 module->inc_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003318 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM, error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003319 }
3320
3321 for (i = 0; i < imp_size; ++i) {
3322 s = (char *) imp[i].module;
3323 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003324 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003325 ++i;
3326 goto error;
3327 }
3328 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003329 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003330 s = (char *) inc[j].submodule;
3331 inc[j].submodule = NULL;
3332 if (yang_fill_include(module, s, &inc[j], unres)) {
3333 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003334 goto error;
3335 }
3336 }
3337 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003338 free(imp);
3339
3340 return EXIT_SUCCESS;
3341
3342error:
3343 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003344 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003345 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003346 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003347 return EXIT_FAILURE;
3348}
Pavol Vican7313fc02016-11-14 01:10:31 +01003349
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003350static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003351yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003352{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003353 struct lys_iffeature *iffeature;
3354 uint8_t *ptr_size, size, i;
3355 char *s;
3356 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003357
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003358 switch (type) {
3359 case FEATURE_KEYWORD:
3360 iffeature = ((struct lys_feature *)parent)->iffeature;
3361 size = ((struct lys_feature *)parent)->iffeature_size;
3362 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3363 parent_is_feature = 1;
3364 break;
3365 case IDENTITY_KEYWORD:
3366 iffeature = ((struct lys_ident *)parent)->iffeature;
3367 size = ((struct lys_ident *)parent)->iffeature_size;
3368 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3369 break;
3370 case ENUM_KEYWORD:
3371 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3372 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3373 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3374 break;
3375 case BIT_KEYWORD:
3376 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3377 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3378 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3379 break;
3380 case REFINE_KEYWORD:
3381 iffeature = ((struct lys_refine *)ptr)->iffeature;
3382 size = ((struct lys_refine *)ptr)->iffeature_size;
3383 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3384 break;
3385 default:
3386 iffeature = ((struct lys_node *)parent)->iffeature;
3387 size = ((struct lys_node *)parent)->iffeature_size;
3388 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3389 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003390 }
3391
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003392 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003393 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003394 s = (char *)iffeature[i].features;
3395 iffeature[i].features = NULL;
3396 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3397 *ptr_size = size;
3398 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003399 }
PavolVican8fa31242017-02-07 11:04:26 +01003400 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3401 *ptr_size = size;
3402 return EXIT_FAILURE;
3403 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003404 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003405 }
3406
3407 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003408}
3409
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003410static int
3411yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3412{
3413 uint size, i;
3414 int rc;
3415 struct lys_ident **ref;
3416 const char *value;
3417 char *expr;
3418
3419 ref = type->info.ident.ref;
3420 size = type->info.ident.count;
3421 type->info.ident.count = 0;
3422 type->info.ident.ref = NULL;
3423 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3424
3425 for (i = 0; i < size; ++i) {
3426 expr = (char *)ref[i];
3427 /* store in the JSON format */
3428 value = transform_schema2json(module, expr);
3429 free(expr);
3430
3431 if (!value) {
3432 goto error;
3433 }
3434 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3435 lydict_remove(module->ctx, value);
3436
3437 if (rc == -1) {
3438 goto error;
3439 }
3440 }
3441 free(ref);
3442
3443 return EXIT_SUCCESS;
3444error:
3445 for (i = i+1; i < size; ++i) {
3446 free(ref[i]);
3447 }
3448 free(ref);
3449 return EXIT_FAILURE;
3450}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003451
Pavol Vican7313fc02016-11-14 01:10:31 +01003452int
PavolVican056fcd12017-02-07 15:36:53 +01003453yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3454 void *parent, struct unres_schema *unres)
3455{
PavolVican92f23622017-12-12 13:35:56 +01003456 unsigned int i, j;
PavolVican056fcd12017-02-07 15:36:53 +01003457
3458 type->parent = parent;
3459 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3460 return EXIT_FAILURE;
3461 }
PavolVican92f23622017-12-12 13:35:56 +01003462 for(j = 0; j < type->ext_size; ++j) {
3463 if (type->ext[j]->flags & LYEXT_OPT_VALID) {
3464 type->parent->flags |= LYS_VALID_DATA;
3465 break;
3466 }
3467 }
3468
PavolVican056fcd12017-02-07 15:36:53 +01003469 switch (stype->base) {
3470 case LY_TYPE_ENUM:
3471 for (i = 0; i < type->info.enums.count; ++i) {
3472 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3473 return EXIT_FAILURE;
3474 }
3475 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3476 &type->info.enums.enm[i], unres)) {
3477 return EXIT_FAILURE;
3478 }
PavolVican92f23622017-12-12 13:35:56 +01003479 for(j = 0; j < type->info.enums.enm[i].ext_size; ++j) {
3480 if (type->info.enums.enm[i].ext[j]->flags & LYEXT_OPT_VALID) {
3481 type->parent->flags |= LYS_VALID_DATA;
3482 break;
3483 }
3484 }
PavolVican056fcd12017-02-07 15:36:53 +01003485 }
3486 break;
3487 case LY_TYPE_BITS:
3488 for (i = 0; i < type->info.bits.count; ++i) {
3489 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3490 return EXIT_FAILURE;
3491 }
3492 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3493 &type->info.bits.bit[i], unres)) {
3494 return EXIT_FAILURE;
3495 }
PavolVican92f23622017-12-12 13:35:56 +01003496 for(j = 0; j < type->info.bits.bit[i].ext_size; ++j) {
3497 if (type->info.bits.bit[i].ext[j]->flags & LYEXT_OPT_VALID) {
3498 type->parent->flags |= LYS_VALID_DATA;
3499 break;
3500 }
3501 }
PavolVican056fcd12017-02-07 15:36:53 +01003502 }
3503 break;
3504 case LY_TYPE_IDENT:
3505 if (yang_check_identityref(module, type, unres)) {
3506 return EXIT_FAILURE;
3507 }
3508 break;
3509 case LY_TYPE_STRING:
PavolVican92f23622017-12-12 13:35:56 +01003510 if (type->info.str.length) {
3511 if (yang_check_ext_instance(module, &type->info.str.length->ext,
3512 type->info.str.length->ext_size, type->info.str.length, unres)) {
3513 return EXIT_FAILURE;
3514 }
3515 for(j = 0; j < type->info.str.length->ext_size; ++j) {
3516 if (type->info.str.length->ext[j]->flags & LYEXT_OPT_VALID) {
3517 type->parent->flags |= LYS_VALID_DATA;
3518 break;
3519 }
3520 }
PavolVican056fcd12017-02-07 15:36:53 +01003521 }
PavolVican92f23622017-12-12 13:35:56 +01003522
PavolVican056fcd12017-02-07 15:36:53 +01003523 for (i = 0; i < type->info.str.pat_count; ++i) {
3524 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3525 &type->info.str.patterns[i], unres)) {
3526 return EXIT_FAILURE;
3527 }
PavolVican92f23622017-12-12 13:35:56 +01003528 for(j = 0; j < type->info.str.patterns[i].ext_size; ++j) {
3529 if (type->info.str.patterns[i].ext[j]->flags & LYEXT_OPT_VALID) {
3530 type->parent->flags |= LYS_VALID_DATA;
3531 break;
3532 }
3533 }
PavolVican056fcd12017-02-07 15:36:53 +01003534 }
3535 break;
3536 case LY_TYPE_DEC64:
PavolVican92f23622017-12-12 13:35:56 +01003537 if (type->info.dec64.range) {
3538 if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
3539 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3540 return EXIT_FAILURE;
3541 }
3542 for(j = 0; j < type->info.dec64.range->ext_size; ++j) {
3543 if (type->info.dec64.range->ext[j]->flags & LYEXT_OPT_VALID) {
3544 type->parent->flags |= LYS_VALID_DATA;
3545 break;
3546 }
3547 }
PavolVican056fcd12017-02-07 15:36:53 +01003548 }
3549 break;
3550 case LY_TYPE_UNION:
3551 for (i = 0; i < type->info.uni.count; ++i) {
3552 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3553 parent, unres)) {
3554 return EXIT_FAILURE;
3555 }
3556 }
Radek Krejci57b41682017-03-07 12:33:24 +01003557 break;
PavolVican056fcd12017-02-07 15:36:53 +01003558 default:
3559 /* nothing checks */
3560 break;
3561 }
3562 return EXIT_SUCCESS;
3563}
3564
3565int
Pavol Vican7313fc02016-11-14 01:10:31 +01003566yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3567{
3568 struct lys_tpdf *tpdf;
Radek Krejcidaa547a2017-09-22 15:56:27 +02003569 uint8_t *ptr_tpdf_size = NULL;
PavolVican92f23622017-12-12 13:35:56 +01003570 uint16_t j, i, tpdf_size, *ptr_tpdf_size16 = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01003571
3572 if (!parent) {
3573 tpdf = module->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003574 //ptr_tpdf_size = &module->tpdf_size;
3575 ptr_tpdf_size16 = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003576 } else {
3577 switch (parent->nodetype) {
3578 case LYS_GROUPING:
3579 tpdf = ((struct lys_node_grp *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003580 ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003581 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003582 case LYS_CONTAINER:
3583 tpdf = ((struct lys_node_container *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003584 ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003585 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003586 case LYS_LIST:
3587 tpdf = ((struct lys_node_list *)parent)->tpdf;
3588 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3589 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003590 case LYS_RPC:
3591 case LYS_ACTION:
3592 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003593 ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003594 break;
Pavol Vican78729392016-11-28 17:18:22 +01003595 case LYS_INPUT:
3596 case LYS_OUTPUT:
3597 tpdf = ((struct lys_node_inout *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003598 ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
Pavol Vican78729392016-11-28 17:18:22 +01003599 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003600 case LYS_NOTIF:
3601 tpdf = ((struct lys_node_notif *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003602 ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
Pavol Vican29bf8802016-11-28 20:44:57 +01003603 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003604 default:
3605 LOGINT;
3606 return EXIT_FAILURE;
3607 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003608 }
3609
Radek Krejcia2ac9262017-09-12 16:39:04 +02003610 if (ptr_tpdf_size16) {
3611 tpdf_size = *ptr_tpdf_size16;
3612 *ptr_tpdf_size16 = 0;
3613 } else {
3614 tpdf_size = *ptr_tpdf_size;
3615 *ptr_tpdf_size = 0;
3616 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003617
3618 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003619 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3620 goto error;
3621 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003622
PavolVican056fcd12017-02-07 15:36:53 +01003623 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3624 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003625 }
PavolVicandf9e7972017-02-07 11:41:38 +01003626 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3627 goto error;
3628 }
PavolVican92f23622017-12-12 13:35:56 +01003629 for(j = 0; j < tpdf[i].ext_size; ++j) {
3630 if (tpdf[i].ext[j]->flags & LYEXT_OPT_VALID) {
3631 tpdf[i].flags |= LYS_VALID_DATA;
3632 break;
3633 }
3634 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003635 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003636 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003637 }
3638
Radek Krejcia2ac9262017-09-12 16:39:04 +02003639 if (ptr_tpdf_size16) {
3640 (*ptr_tpdf_size16)++;
3641 } else {
3642 (*ptr_tpdf_size)++;
3643 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003644 /* check default value*/
Michal Vasko15a43372017-09-25 14:12:42 +02003645 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3646 && 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 +01003647 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003648 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003649 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003650 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003651
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003652 return EXIT_SUCCESS;
3653
3654error:
3655 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3656 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003657}
3658
3659static int
Pavol Vican36e27272016-11-22 15:47:28 +01003660yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3661{
3662 uint32_t i, size, base_size;
3663 uint8_t j;
3664
3665 size = module->ident_size;
3666 module->ident_size = 0;
3667 for (i = 0; i < size; ++i) {
3668 base_size = module->ident[i].base_size;
3669 module->ident[i].base_size = 0;
3670 for (j = 0; j < base_size; ++j) {
3671 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3672 ++j;
3673 module->ident_size = size;
3674 goto error;
3675 }
3676 }
3677 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003678 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3679 goto error;
3680 }
PavolVican8fa31242017-02-07 11:04:26 +01003681 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3682 goto error;
3683 }
Pavol Vican36e27272016-11-22 15:47:28 +01003684 }
3685
PavolVican8fa31242017-02-07 11:04:26 +01003686
Pavol Vican36e27272016-11-22 15:47:28 +01003687 return EXIT_SUCCESS;
3688
3689error:
3690 for (; j< module->ident[i].base_size; ++j) {
3691 free(module->ident[i].base[j]);
3692 }
3693 yang_free_ident_base(module->ident, i + 1, size);
3694 return EXIT_FAILURE;
3695}
3696
3697static int
PavolVican38104a32017-02-08 12:25:23 +01003698yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3699{
3700 uint i;
3701
3702 for (i = 0; i < size; ++i) {
3703 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3704 return EXIT_FAILURE;
3705 }
3706 }
3707 return EXIT_SUCCESS;
3708}
3709
3710static int
PavolVicane87cb932016-12-30 15:36:18 +01003711yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003712 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003713{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003714 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003715 goto error;
3716 }
3717
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003718 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003719 goto error;
3720 }
3721
Radek Krejci7212e0a2017-03-08 15:58:22 +01003722 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003723 *child = NULL;
3724 goto error;
3725 }
3726 *child = NULL;
3727
PavolVican59ba4602017-02-08 11:53:32 +01003728 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3729 goto error;
3730 }
PavolVican38104a32017-02-08 12:25:23 +01003731 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3732 goto error;
3733 }
3734
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003735 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003736 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003737 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003738 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003739 goto error;
3740 }
3741 } else {
3742 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3743 goto error;
3744 }
3745 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003746 }
3747
3748 return EXIT_SUCCESS;
3749error:
3750 return EXIT_FAILURE;
3751}
3752
3753static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003754yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003755{
PavolVican056fcd12017-02-07 15:36:53 +01003756 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003757 yang_type_free(module->ctx, &leaf->type);
3758 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003759 }
PavolVicana08d3652016-12-29 21:07:47 +01003760 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3761 yang_type_free(module->ctx, &leaf->type);
3762 goto error;
3763 }
3764
Pavol Vicanfda8c802016-12-03 02:00:42 +01003765 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003766 yang_type_free(module->ctx, &leaf->type);
3767 goto error;
3768 }
3769
Michal Vasko15a43372017-09-25 14:12:42 +02003770 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003771 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003772 goto error;
3773 }
3774
PavolVican59ba4602017-02-08 11:53:32 +01003775 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3776 goto error;
3777 }
PavolVican38104a32017-02-08 12:25:23 +01003778 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3779 goto error;
3780 }
Michal Vasko89afc112017-03-16 13:57:28 +01003781
Pavol Vicana69aff22016-11-24 18:23:50 +01003782 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003783 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003784 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003785 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003786 goto error;
3787 }
3788 } else {
3789 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3790 goto error;
3791 }
3792 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003793 }
3794
3795 return EXIT_SUCCESS;
3796error:
3797 return EXIT_FAILURE;
3798}
3799
3800static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003801yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3802 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003803{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003804 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003805
PavolVican056fcd12017-02-07 15:36:53 +01003806 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003807 yang_type_free(module->ctx, &leaflist->type);
3808 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003809 }
PavolVicana08d3652016-12-29 21:07:47 +01003810 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3811 yang_type_free(module->ctx, &leaflist->type);
3812 goto error;
3813 }
3814
Pavol Vicanfda8c802016-12-03 02:00:42 +01003815 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003816 yang_type_free(module->ctx, &leaflist->type);
3817 goto error;
3818 }
3819
Pavol Vican36aff862016-11-26 17:07:05 +01003820 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003821 /* check for duplicity in case of configuration data,
3822 * in case of status data duplicities are allowed */
3823 if (leaflist->flags & LYS_CONFIG_W) {
3824 for (j = i +1; j < leaflist->dflt_size; ++j) {
3825 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003826 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3827 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003828 goto error;
3829 }
3830 }
3831 }
3832 /* check default value (if not defined, there still could be some restrictions
3833 * that need to be checked against a default value from a derived type) */
Michal Vasko15a43372017-09-25 14:12:42 +02003834 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003835 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3836 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003837 goto error;
3838 }
3839 }
3840
PavolVican59ba4602017-02-08 11:53:32 +01003841 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3842 goto error;
3843 }
PavolVican38104a32017-02-08 12:25:23 +01003844 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3845 goto error;
3846 }
PavolVican59ba4602017-02-08 11:53:32 +01003847
Pavol Vican36aff862016-11-26 17:07:05 +01003848 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003849 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003850 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003851 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003852 goto error;
3853 }
3854 } else {
3855 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3856 goto error;
3857 }
3858 }
Pavol Vican36aff862016-11-26 17:07:05 +01003859 }
3860
3861 return EXIT_SUCCESS;
3862error:
3863 return EXIT_FAILURE;
3864}
3865
3866static int
PavolVicane87cb932016-12-30 15:36:18 +01003867yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003868 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003869{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003870 struct lys_node *node;
3871
Pavol Vicand8136a42016-11-27 13:28:04 +01003872 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3873 goto error;
3874 }
3875
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003876 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3877 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003878 }
3879
Pavol Vicanfda8c802016-12-03 02:00:42 +01003880 if (list->flags & LYS_CONFIG_R) {
3881 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3882 * ignore oredering MASK - 0x7F
3883 */
3884 list->flags &= 0x7F;
3885 }
3886 /* check - if list is configuration, key statement is mandatory
3887 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003888 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 +01003889 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3890 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3891 goto error;
3892 }
3893
Radek Krejci7212e0a2017-03-08 15:58:22 +01003894 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003895 *child = NULL;
3896 goto error;
3897 }
3898 *child = NULL;
3899
Pavol Vicand8136a42016-11-27 13:28:04 +01003900 if (list->keys && yang_read_key(module, list, unres)) {
3901 goto error;
3902 }
3903
3904 if (yang_read_unique(module, list, unres)) {
3905 goto error;
3906 }
3907
PavolVican59ba4602017-02-08 11:53:32 +01003908 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3909 goto error;
3910 }
PavolVican38104a32017-02-08 12:25:23 +01003911 if (yang_check_must(module, list->must, list->must_size, unres)) {
3912 goto error;
3913 }
Michal Vasko89afc112017-03-16 13:57:28 +01003914
Pavol Vicand8136a42016-11-27 13:28:04 +01003915 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003916 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003917 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003918 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003919 goto error;
3920 }
3921 } else {
3922 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3923 goto error;
3924 }
3925 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003926 }
3927
3928 return EXIT_SUCCESS;
3929error:
3930 return EXIT_FAILURE;
3931}
3932
3933static int
PavolVicane87cb932016-12-30 15:36:18 +01003934yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003935 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003936{
3937 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003938
PavolVicana08d3652016-12-29 21:07:47 +01003939 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3940 free(choice->dflt);
3941 choice->dflt = NULL;
3942 goto error;
3943 }
3944
Radek Krejci7212e0a2017-03-08 15:58:22 +01003945 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003946 *child = NULL;
3947 free(choice->dflt);
3948 choice->dflt = NULL;
3949 goto error;
3950 }
3951 *child = NULL;
3952
Pavol Vican36ace102016-11-28 11:46:59 +01003953 if (choice->dflt) {
3954 value = (char *)choice->dflt;
3955 choice->dflt = NULL;
3956 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3957 free(value);
3958 goto error;
3959 }
3960 free(value);
3961 }
3962
PavolVican59ba4602017-02-08 11:53:32 +01003963 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3964 goto error;
3965 }
3966
Pavol Vican36ace102016-11-28 11:46:59 +01003967 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003968 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01003969 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003970 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003971 goto error;
3972 }
3973 } else {
3974 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3975 goto error;
3976 }
3977 }
Pavol Vican36ace102016-11-28 11:46:59 +01003978 }
3979
3980 return EXIT_SUCCESS;
3981error:
3982 return EXIT_FAILURE;
3983}
3984
3985static int
PavolVicane87cb932016-12-30 15:36:18 +01003986yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003987 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003988{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003989 struct lys_node *node;
3990
3991 if (rpc->nodetype == LYS_ACTION) {
3992 for (node = rpc->parent; node; node = lys_parent(node)) {
3993 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003994 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003995 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003996 goto error;
3997 }
3998 }
3999 }
4000 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
4001 goto error;
4002 }
4003
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004004 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
4005 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004006 }
4007
Radek Krejci7212e0a2017-03-08 15:58:22 +01004008 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004009 *child = NULL;
4010 goto error;
4011 }
4012 *child = NULL;
4013
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004014 return EXIT_SUCCESS;
4015error:
4016 return EXIT_FAILURE;
4017}
4018
4019static int
PavolVicane87cb932016-12-30 15:36:18 +01004020yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004021 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01004022{
Pavol Vican29bf8802016-11-28 20:44:57 +01004023 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
4024 goto error;
4025 }
4026
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004027 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
4028 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01004029 }
4030
Radek Krejci7212e0a2017-03-08 15:58:22 +01004031 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004032 *child = NULL;
4033 goto error;
4034 }
4035 *child = NULL;
4036
Michal Vasko89afc112017-03-16 13:57:28 +01004037 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
4038 goto error;
4039 }
4040
4041 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004042 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01004043 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004044 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004045 goto error;
4046 }
4047 } else {
4048 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
4049 goto error;
4050 }
PavolVican38104a32017-02-08 12:25:23 +01004051 }
Pavol Vican29bf8802016-11-28 20:44:57 +01004052 }
4053
4054 return EXIT_SUCCESS;
4055error:
4056 return EXIT_FAILURE;
4057}
4058
4059static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004060yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004061{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004062 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004063
Pavol Vican3ad50f82016-12-04 15:00:36 +01004064 child = augment->child;
4065 augment->child = NULL;
4066
PavolVicana08d3652016-12-29 21:07:47 +01004067 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4068 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004069 goto error;
4070 }
4071
Radek Krejci7212e0a2017-03-08 15:58:22 +01004072 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004073 goto error;
4074 }
4075
PavolVicanfa9510e2017-02-08 17:20:46 +01004076 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4077 goto error;
4078 }
4079
PavolVican59ba4602017-02-08 11:53:32 +01004080 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4081 goto error;
4082 }
4083
Pavol Vican3ad50f82016-12-04 15:00:36 +01004084 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004085 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004086 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004087 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004088 goto error;
4089 }
4090 } else {
4091 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4092 goto error;
4093 }
4094 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004095 }
4096
4097 return EXIT_SUCCESS;
4098error:
4099 return EXIT_FAILURE;
4100}
4101
4102static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004103yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004104{
4105 uint i, size;
4106
4107 size = uses->augment_size;
4108 uses->augment_size = 0;
4109
4110 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004111 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004112 }
4113
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004114 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004115 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4116 goto error;
4117 }
4118 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4119 goto error;
4120 }
4121 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 +01004122 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004123 }
4124 }
4125
Pavol Vican3ad50f82016-12-04 15:00:36 +01004126 for (i = 0; i < size; ++i) {
4127 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004128 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004129 goto error;
4130 }
4131 }
4132
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004133 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4134 goto error;
4135 }
4136
PavolVican59ba4602017-02-08 11:53:32 +01004137 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4138 goto error;
4139 }
4140
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004141 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004142 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004143 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004144 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004145 goto error;
4146 }
4147 } else {
4148 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4149 goto error;
4150 }
4151 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004152 }
4153
4154 return EXIT_SUCCESS;
4155error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004156 for (i = uses->augment_size; i < size; ++i) {
4157 yang_free_augment(module->ctx, &uses->augment[i]);
4158 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004159 return EXIT_FAILURE;
4160}
4161
4162static int
PavolVican59ba4602017-02-08 11:53:32 +01004163yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004164 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004165{
4166 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4167 goto error;
4168 }
4169
Radek Krejci7212e0a2017-03-08 15:58:22 +01004170 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004171 *child = NULL;
4172 goto error;
4173 }
4174 *child = NULL;
4175
4176 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4177 goto error;
4178 }
PavolVican38104a32017-02-08 12:25:23 +01004179 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4180 goto error;
4181 }
PavolVican59ba4602017-02-08 11:53:32 +01004182
4183 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004184 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004185 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004186 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004187 goto error;
4188 }
4189 } else {
4190 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4191 goto error;
4192 }
4193 }
PavolVican59ba4602017-02-08 11:53:32 +01004194 }
Michal Vasko89afc112017-03-16 13:57:28 +01004195
PavolVican59ba4602017-02-08 11:53:32 +01004196 return EXIT_SUCCESS;
4197error:
4198 return EXIT_FAILURE;
4199}
4200
4201static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004202yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004203 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004204{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004205 struct lys_node *node = nodes, *sibling, *child;
PavolVican92f23622017-12-12 13:35:56 +01004206 int i;
Pavol Vican05810b62016-11-23 14:07:22 +01004207
4208 while (node) {
4209 sibling = node->next;
4210 child = node->child;
4211 node->next = NULL;
4212 node->child = NULL;
PavolVicanbd1d1ae2017-07-20 00:06:00 +02004213 node->parent = NULL;
Pavol Vican05810b62016-11-23 14:07:22 +01004214 node->prev = node;
4215
PavolVican05c4f9b2017-09-07 13:33:54 +02004216 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node) ||
4217 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004218 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004219 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004220 goto error;
4221 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004222 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004223 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4224 goto error;
4225 }
PavolVican92f23622017-12-12 13:35:56 +01004226 for(i = 0; i < node->ext_size; ++i) {
4227 if (node->ext[i]->flags & LYEXT_OPT_VALID) {
4228 node->flags |= LYS_VALID_DATA;
4229 break;
4230 }
4231 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004232
Pavol Vican05810b62016-11-23 14:07:22 +01004233 switch (node->nodetype) {
4234 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004235 if (yang_check_typedef(module, node, unres)) {
4236 goto error;
4237 }
4238 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004239 goto error;
4240 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004241 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004242 child = NULL;
4243 goto error;
4244 }
Pavol Vican05810b62016-11-23 14:07:22 +01004245 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004246 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004247 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004248 goto error;
4249 }
4250 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004251 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004252 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004253 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004254 goto error;
4255 }
4256 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004257 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004258 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004259 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004260 goto error;
4261 }
4262 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004263 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004264 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004265 goto error;
4266 }
4267 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004268 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004269 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004270 goto error;
4271 }
4272 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004273 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004274 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004275 goto error;
4276 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004277 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004278 child = NULL;
4279 goto error;
4280 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004281 if (((struct lys_node_case *)node)->when) {
4282 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4283 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4284 goto error;
4285 }
4286 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004287 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004288 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004289 goto error;
4290 }
4291 } else {
4292 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4293 goto error;
4294 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004295 }
4296 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004297 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004298 case LYS_ANYDATA:
4299 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004300 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004301 goto error;
4302 }
4303 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004304 case LYS_RPC:
4305 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004306 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004307 goto error;
4308 }
4309 break;
Pavol Vican78729392016-11-28 17:18:22 +01004310 case LYS_INPUT:
4311 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004312 if (yang_check_typedef(module, node, unres)) {
4313 goto error;
4314 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004315 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004316 child = NULL;
4317 goto error;
4318 }
PavolVican38104a32017-02-08 12:25:23 +01004319 if (((struct lys_node_inout *)node)->must_size) {
4320 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4321 goto error;
4322 }
4323 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004324 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004325 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004326 goto error;
4327 }
4328 } else {
4329 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4330 goto error;
4331 }
PavolVican38104a32017-02-08 12:25:23 +01004332 }
Pavol Vican78729392016-11-28 17:18:22 +01004333 }
Pavol Vican78729392016-11-28 17:18:22 +01004334 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004335 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004336 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004337 goto error;
4338 }
4339 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004340 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004341 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004342 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004343 goto error;
4344 }
4345 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004346 default:
4347 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01004348 goto error;
4349 }
Pavol Vican05810b62016-11-23 14:07:22 +01004350 node = sibling;
4351 }
4352
4353 return EXIT_SUCCESS;
4354error:
4355 yang_free_nodes(module->ctx, sibling);
4356 yang_free_nodes(module->ctx, child);
4357 return EXIT_FAILURE;
4358}
4359
4360static int
PavolVican75af21d2016-12-29 20:04:07 +01004361yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4362 struct lys_node *dev_target, struct ly_set *dflt_check)
4363{
4364 struct lys_node_leaflist *llist;
4365 struct lys_type *type;
4366 struct lys_tpdf *tmp_parent;
4367 int i, j;
4368
PavolVican6f000922017-02-10 12:56:59 +01004369 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4370 goto error;
4371 }
PavolVican75af21d2016-12-29 20:04:07 +01004372 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4373 goto error;
4374 }
4375 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4376 goto error;
4377 }
4378 if (deviate->dflt_size) {
4379 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4380 goto error;
4381 }
4382 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4383 /* consolidate the final list in the target after removing items from it */
4384 llist = (struct lys_node_leaflist *)dev_target;
4385 for (i = j = 0; j < llist->dflt_size; j++) {
4386 llist->dflt[i] = llist->dflt[j];
4387 if (llist->dflt[i]) {
4388 i++;
4389 }
4390 }
4391 llist->dflt_size = i + 1;
4392 }
4393 }
4394
4395 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4396 goto error;
4397 }
4398
4399 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4400 goto error;
4401 }
4402
4403 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4404 goto error;
4405 }
4406
4407 if ((deviate->flags & LYS_CONFIG_MASK)) {
4408 /* add and replace are the same in this case */
4409 /* remove current config value of the target ... */
4410 dev_target->flags &= ~LYS_CONFIG_MASK;
4411
4412 /* ... and replace it with the value specified in deviation */
4413 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4414 }
4415
4416 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4417 goto error;
4418 }
4419
4420 if (deviate->type) {
4421 /* check target node type */
4422 if (dev_target->nodetype == LYS_LEAF) {
4423 type = &((struct lys_node_leaf *)dev_target)->type;
4424 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4425 type = &((struct lys_node_leaflist *)dev_target)->type;
4426 } else {
4427 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4428 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
4429 goto error;
4430 }
4431 /* remove type and initialize it */
4432 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004433 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004434 memcpy(type, deviate->type, sizeof *deviate->type);
4435 free(deviate->type);
4436 deviate->type = type;
4437 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004438 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4439 goto error;
4440 }
4441
PavolVican75af21d2016-12-29 20:04:07 +01004442 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4443 goto error;
4444 }
4445 }
4446
4447 return EXIT_SUCCESS;
4448error:
4449 if (deviate->type) {
4450 yang_type_free(module->ctx, deviate->type);
4451 deviate->type = NULL;
4452 }
4453 return EXIT_FAILURE;
4454}
4455
4456static int
4457yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4458{
4459 int rc;
4460 uint i;
4461 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004462 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004463 unsigned int u;
4464 const char *value, *target_name;
4465 struct lys_node_leaflist *llist;
4466 struct lys_node_leaf *leaf;
4467 struct unres_schema tmp_unres;
4468 struct lys_module *mod;
4469
4470 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004471 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4472 if (rc == -1) {
PavolVican75af21d2016-12-29 20:04:07 +01004473 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004474 ly_set_free(set);
PavolVican75af21d2016-12-29 20:04:07 +01004475 goto error;
4476 }
Michal Vasko50576712017-07-28 12:28:33 +02004477 dev_target = set->set.s[0];
4478 ly_set_free(set);
4479
PavolVican75af21d2016-12-29 20:04:07 +01004480 if (dev_target->module == lys_main_module(module)) {
4481 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4482 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4483 goto error;
4484 }
4485
4486 if (!dflt_check) {
4487 LOGMEM;
4488 goto error;
4489 }
4490
4491 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4492 /* you cannot remove a key leaf */
4493 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4494 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4495 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4496 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4497 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
PavolVican4b80d042017-02-23 14:30:27 +01004498 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01004499 }
4500 }
4501 }
4502 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004503 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004504 lys_node_unlink(dev_target);
Michal Vaskoa1074a52018-01-03 12:18:53 +01004505 if (parent && (parent->nodetype & (LYS_AUGMENT | LYS_USES))) {
Radek Krejci9cf034c2017-08-24 17:10:35 +02004506 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4507 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4508 * path), so we need to remember the augment as an addition */
Michal Vaskoa1074a52018-01-03 12:18:53 +01004509 /* remember uses parent so we can reconnect to it */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004510 dev_target->parent = parent;
4511 }
PavolVican75af21d2016-12-29 20:04:07 +01004512 dev->orig_node = dev_target;
4513 } else {
4514 /* store a shallow copy of the original node */
4515 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004516 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004517 /* just to be safe */
4518 if (tmp_unres.count) {
4519 LOGINT;
4520 goto error;
4521 }
4522 }
4523
PavolVican6f000922017-02-10 12:56:59 +01004524 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
4525 goto error;
4526 }
4527
Michal Vasko15a43372017-09-25 14:12:42 +02004528 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)) {
4529 for (i = 0; i < dev->deviate_size; ++i) {
4530 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4531 yang_free_deviate(module->ctx, dev, i + 1);
4532 dev->deviate_size = i+1;
4533 goto error; // missing free unresolve type in deviate
PavolVican75af21d2016-12-29 20:04:07 +01004534 }
4535 }
Michal Vasko15a43372017-09-25 14:12:42 +02004536 /* now check whether default value, if any, matches the type */
4537 for (u = 0; u < dflt_check->number; ++u) {
4538 value = NULL;
4539 rc = EXIT_SUCCESS;
4540 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4541 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4542 target_name = leaf->name;
4543 value = leaf->dflt;
4544 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4545 } else { /* LYS_LEAFLIST */
4546 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4547 target_name = llist->name;
4548 for (i = 0; i < llist->dflt_size; i++) {
4549 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4550 (struct lys_node *)(&llist->dflt[i]));
4551 if (rc == -1) {
4552 value = llist->dflt[i];
4553 break;
4554 }
4555 }
4556 }
4557 if (rc == -1) {
4558 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4559 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
4560 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4561 target_name);
4562 goto error;
4563 }
PavolVican75af21d2016-12-29 20:04:07 +01004564 }
Michal Vasko15a43372017-09-25 14:12:42 +02004565 ly_set_free(dflt_check);
Michal Vasko6e2951d2017-12-13 11:15:00 +01004566 dflt_check = NULL;
PavolVican75af21d2016-12-29 20:04:07 +01004567 }
PavolVican75af21d2016-12-29 20:04:07 +01004568
Radek Krejci29eac3d2017-06-01 16:50:02 +02004569 /* mark all the affected modules as deviated and implemented */
4570 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004571 mod = lys_node_module(parent);
4572 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004573 mod->deviated = 1; /* main module */
4574 parent->module->deviated = 1; /* possible submodule */
4575 if (lys_set_implemented(mod)) {
4576 LOGERR(ly_errno, "Setting the deviated module \"%s\" implemented failed.", mod->name);
4577 goto error;
4578 }
4579 }
PavolVican75af21d2016-12-29 20:04:07 +01004580 }
PavolVican75af21d2016-12-29 20:04:07 +01004581
4582 return EXIT_SUCCESS;
4583error:
4584 ly_set_free(dflt_check);
4585 return EXIT_FAILURE;
4586}
4587
4588static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004589yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4590{
PavolVican75af21d2016-12-29 20:04:07 +01004591 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004592
4593 aug_size = module->augment_size;
4594 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004595 dev_size = module->deviation_size;
4596 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004597
PavolVican6f87bf92017-02-15 19:38:55 +01004598 if (yang_check_typedef(module, NULL, unres)) {
4599 goto error;
4600 }
4601
PavolVicanc1807262017-01-31 18:00:27 +01004602 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4603 goto error;
4604 }
4605
PavolVican171717d2017-02-01 14:49:55 +01004606 /* check extension in revision */
4607 for (i = 0; i < module->rev_size; ++i) {
4608 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4609 goto error;
4610 }
4611 }
4612
PavolVican19dc6152017-02-06 12:04:15 +01004613 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004614 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004615 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4616 goto error;
4617 }
4618 }
4619
Pavol Vican7a7916f2016-11-21 23:38:30 +01004620 /* check features */
4621 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004622 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4623 goto error;
4624 }
PavolVican5393d3f2017-02-06 23:30:55 +01004625 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4626 goto error;
4627 }
4628
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004629 /* check for circular dependencies */
4630 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4631 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004632 }
4633 }
Pavol Vican36e27272016-11-22 15:47:28 +01004634 erase_identities = 0;
4635 if (yang_check_identities(module, unres)) {
4636 goto error;
4637 }
Pavol Vican05810b62016-11-23 14:07:22 +01004638 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004639 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004640 goto error;
4641 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004642
PavolVican75af21d2016-12-29 20:04:07 +01004643 /* check deviation */
4644 for (i = 0; i < dev_size; ++i) {
4645 module->deviation_size++;
4646 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4647 goto error;
4648 }
4649 }
4650
Pavol Vican3ad50f82016-12-04 15:00:36 +01004651 /* check augments */
4652 for (i = 0; i < aug_size; ++i) {
4653 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004654 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004655 goto error;
4656 }
4657 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4658 goto error;
4659 }
4660 }
4661
Pavol Vican7313fc02016-11-14 01:10:31 +01004662 return EXIT_SUCCESS;
4663error:
Pavol Vican36e27272016-11-22 15:47:28 +01004664 if (erase_identities) {
4665 yang_free_ident_base(module->ident, 0, module->ident_size);
4666 }
Pavol Vican05810b62016-11-23 14:07:22 +01004667 if (erase_nodes) {
4668 yang_free_nodes(module->ctx, node);
4669 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004670 for (i = module->augment_size; i < aug_size; ++i) {
4671 yang_free_augment(module->ctx, &module->augment[i]);
4672 }
PavolVican75af21d2016-12-29 20:04:07 +01004673 for (i = module->deviation_size; i < dev_size; ++i) {
4674 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4675 free(module->deviation[i].deviate);
4676 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004677 return EXIT_FAILURE;
4678}
PavolVican22e88682017-02-14 22:38:18 +01004679
4680int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004681yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004682 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4683{
4684 int c;
4685 const char **str, ***p = NULL;
4686 void *reallocated;
4687 struct lyext_substmt *info;
4688
4689 c = 0;
4690 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004691 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004692 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4693 if (info->cardinality < LY_STMT_CARD_SOME) {
4694 str++;
4695 } else {
4696 /* get the index in the array to add new item */
4697 p = (const char ***)str;
4698 for (c = 0; p[0][c + 1]; c++);
4699 str = p[1];
4700 }
4701 str[c] = lydict_insert_zc(module->ctx, value);
4702 } else {
4703 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4704 if (!str) {
4705 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004706 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004707 }
4708 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
4709 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004710 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004711 }
4712
4713 if (info->cardinality >= LY_STMT_CARD_SOME) {
4714 /* there can be multiple instances, str is actually const char *** */
4715 p = (const char ***)str;
4716 if (!p[0]) {
4717 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004718 p[0] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004719 LY_CHECK_ERR_GOTO(!p[0], LOGMEM, error);
PavolVican22e88682017-02-14 22:38:18 +01004720 if (stmt == LY_STMT_BELONGSTO) {
4721 /* allocate another array for the belongs-to's prefixes */
4722 p[1] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004723 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004724 } else if (stmt == LY_STMT_ARGUMENT) {
4725 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004726 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004727 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004728 /* default value of yin element */
4729 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004730 }
4731 } else {
4732 /* get the index in the array to add new item */
4733 for (c = 0; p[0][c]; c++);
4734 }
4735 str = p[0];
4736 }
4737
4738 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004739 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004740
PavolVican50809742017-02-18 21:22:54 +01004741 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004742 /* enlarge the array(s) */
4743 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4744 if (!reallocated) {
4745 LOGMEM;
4746 lydict_remove(module->ctx, p[0][c]);
4747 p[0][c] = NULL;
4748 return EXIT_FAILURE;
4749 }
4750 p[0] = reallocated;
4751 p[0][c + 1] = NULL;
4752
4753 if (stmt == LY_STMT_BELONGSTO) {
4754 /* enlarge the second belongs-to's array with prefixes */
4755 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4756 if (!reallocated) {
4757 LOGMEM;
4758 lydict_remove(module->ctx, p[1][c]);
4759 p[1][c] = NULL;
4760 return EXIT_FAILURE;
4761 }
4762 p[1] = reallocated;
4763 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004764 } else if (stmt == LY_STMT_ARGUMENT) {
4765 /* enlarge the second argument's array with yin element */
4766 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4767 if (!reallocated) {
4768 LOGMEM;
4769 ((uint8_t *)p[1])[c] = 0;
4770 return EXIT_FAILURE;
4771 }
4772 p[1] = reallocated;
4773 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004774 }
4775 }
4776 }
4777
4778 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004779
4780error:
4781 free(value);
4782 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004783}
PavolVican5334c892017-02-15 16:29:09 +01004784
4785static int
4786yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4787{
4788 int c = 0, decrement = 0;
4789 const char **str, ***p = NULL;
4790 struct lyext_substmt *info;
4791
4792
4793 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4794 stmt = LY_STMT_BELONGSTO;
4795 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004796 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4797 stmt = LY_STMT_ARGUMENT;
4798 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004799 }
4800
4801 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4802 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4803 return 0;
4804 } else {
4805 p = (const char ***)str;
4806 /* get the index in the array */
4807 for (c = 0; p[0][c]; c++);
4808 return c + decrement;
4809 }
4810}
PavolVicana0fdbf32017-02-15 17:59:02 +01004811
4812void **
PavolVicanfe83b152017-02-19 03:19:29 +01004813yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4814 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004815{
4816 int c;
4817 void **data, ***p = NULL;
4818 void *reallocated;
4819 struct lyext_substmt *info;
4820
4821 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4822 if (!data) {
4823 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4824 return NULL;
4825 }
4826 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
4827 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4828 return NULL;
4829 }
4830
4831 c = 0;
4832 if (info->cardinality >= LY_STMT_CARD_SOME) {
4833 /* there can be multiple instances, so instead of pointer to array,
4834 * we have in data pointer to pointer to array */
4835 p = (void ***)data;
4836 data = *p;
4837 if (!data) {
4838 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004839 *p = data = calloc(2, sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004840 LY_CHECK_ERR_RETURN(!data, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004841 } else {
4842 for (c = 0; *data; data++, c++);
4843 }
4844 }
4845
PavolVicaneef1d912017-02-19 00:19:15 +01004846 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004847 /* enlarge the array */
4848 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004849 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004850 *p = reallocated;
4851 data = *p;
4852 data[c + 1] = NULL;
4853 }
4854
PavolVicanfe83b152017-02-19 03:19:29 +01004855 if (index) {
4856 *index = c;
4857 return data;
4858 } else {
4859 return &data[c];
4860 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004861}
PavolVicanff0f7f42017-02-16 11:35:42 +01004862
4863int
4864yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4865 LY_STMT stmt, uint16_t value, uint16_t mask)
4866{
4867 uint16_t *data;
4868 struct lyext_substmt *info;
4869
4870 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4871 if (!data) {
4872 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4873 return EXIT_FAILURE;
4874 }
4875 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
4876 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4877 return EXIT_FAILURE;
4878 }
4879
4880 *data |= value;
4881 return EXIT_SUCCESS;
4882}
PavolVican8e8dfd12017-02-16 13:51:41 +01004883
4884int
PavolVican6a852a62017-02-16 15:36:01 +01004885yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4886 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004887{
PavolVican6a852a62017-02-16 15:36:01 +01004888 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004889 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004890 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004891
4892 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4893 if (!val) {
4894 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4895 return EXIT_FAILURE;
4896 }
PavolVican6a852a62017-02-16 15:36:01 +01004897 if (stmt == LY_STMT_DIGITS) {
4898 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
4899 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4900 return EXIT_FAILURE;
4901 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004902
PavolVican6a852a62017-02-16 15:36:01 +01004903 if (info->cardinality >= LY_STMT_CARD_SOME) {
4904 /* there can be multiple instances */
4905 pp = (uint8_t**)val;
4906 if (!(*pp)) {
4907 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Radek Krejcia8d111f2017-05-31 13:57:37 +02004908 LY_CHECK_ERR_RETURN(!*pp, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004909 } else {
4910 for (i = 0; (*pp)[i]; i++);
4911 }
4912 val = &(*pp)[i];
4913 }
4914
4915 /* stored value */
4916 *val = value;
4917
4918 if (i) {
4919 /* enlarge the array */
4920 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004921 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004922 *pp = reallocated;
4923 (*pp)[i + 1] = 0;
4924 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004925 } else {
PavolVican6a852a62017-02-16 15:36:01 +01004926 if (*val) {
4927 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4928 return EXIT_FAILURE;
4929 }
4930
4931 if (stmt == LY_STMT_REQINSTANCE) {
4932 *val = (value == 1) ? 1 : 2;
4933 } else if (stmt == LY_STMT_MODIFIER) {
4934 *val = 1;
4935 } else {
4936 LOGINT;
4937 return EXIT_FAILURE;
4938 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004939 }
4940
4941 return EXIT_SUCCESS;
4942}
PavolVican3f47b292017-02-16 20:38:16 +01004943
PavolVicanf3091bf2017-02-19 18:27:01 +01004944int
4945yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4946 struct lys_node *node, LY_STMT stmt)
4947{
4948 struct lyext_substmt *info;
4949 struct lys_node **snode, *siter;
4950
4951 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
4952 if (!snode) {
4953 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4954 return EXIT_FAILURE;
4955 }
4956 if (info->cardinality < LY_STMT_CARD_SOME) {
4957 LY_TREE_FOR(node, siter) {
4958 if (stmt == lys_snode2stmt(siter->nodetype)) {
4959 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4960 return EXIT_FAILURE;
4961 }
4962 }
4963 }
4964
4965 return EXIT_SUCCESS;
4966}
PavolVicandb0e8172017-02-20 00:46:09 +01004967
4968int
4969yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
4970 char *parent_name, char **values, int implemented)
4971{
4972 int c, i;
4973 struct lys_module **modules, ***p, *reallocated, **pp;
4974 struct lyext_substmt *info;
4975
4976 if (!values) {
4977 return EXIT_SUCCESS;
4978 }
4979 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
4980 if (!modules) {
4981 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
4982 return EXIT_FAILURE;
4983 }
4984
4985 for (i = 0; values[i]; ++i) {
4986 c = 0;
4987 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
4988 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
4989 return EXIT_FAILURE;
4990 }
4991 if (info->cardinality >= LY_STMT_CARD_SOME) {
4992 /* there can be multiple instances, so instead of pointer to array,
4993 * we have in modules pointer to pointer to array */
4994 p = (struct lys_module ***)pp;
4995 modules = *p;
4996 if (!modules) {
4997 /* allocate initial array */
4998 *p = modules = calloc(2, sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004999 LY_CHECK_ERR_RETURN(!*p, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005000 } else {
5001 for (c = 0; *modules; modules++, c++);
5002 }
5003 }
5004
5005 if (c) {
5006 /* enlarge the array */
5007 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02005008 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005009 *p = (struct lys_module **)reallocated;
5010 modules = *p;
5011 modules[c + 1] = NULL;
5012 }
5013
5014 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
5015 if (!modules[c]) {
5016 return EXIT_FAILURE;
5017 }
5018 }
5019
5020 return EXIT_SUCCESS;
5021}