blob: a269e9e3ad0f5be38ed1d4899ff1729e7177c8e3 [file] [log] [blame]
Pavol Vican021488a2016-01-25 23:56:12 +01001/**
2 * @file parser_yang.c
3 * @author Pavol Vican
4 * @brief YANG parser for libyang
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Pavol Vican9a3a7212016-03-23 10:04:00 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
Pavol Vican021488a2016-01-25 23:56:12 +010013 */
14
Pavol Vican5de33492016-02-22 14:03:24 +010015#include <ctype.h>
Pavol Vican7313fc02016-11-14 01:10:31 +010016#include <assert.h>
Pavol Vican021488a2016-01-25 23:56:12 +010017#include "parser_yang.h"
Pavol Vican8e7110b2016-03-22 17:00:26 +010018#include "parser_yang_lex.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010019#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010020#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010021
Pavol Vican082afd02016-10-25 12:39:15 +020022static void yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size);
PavolVican6f000922017-02-10 12:56:59 +010023static int yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres);
Pavol Vican082afd02016-10-25 12:39:15 +020024static void yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size);
Pavol Vican7313fc02016-11-14 01:10:31 +010025static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
Pavol Vican05810b62016-11-23 14:07:22 +010026static void free_yang_common(struct lys_module *module, struct lys_node *node);
Pavol Vican3ad50f82016-12-04 15:00:36 +010027static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +010028 int options, struct unres_schema *unres);
PavolVican5334c892017-02-15 16:29:09 +010029static int yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword);
PavolVicanf3091bf2017-02-19 18:27:01 +010030static void yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node);
Frank Rimplerc4db1c72017-09-12 12:56:39 +000031void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size, int shallow,
Radek Krejci5138e9f2017-04-12 13:10:46 +020032 void (*private_destructor)(const struct lys_node *node, void *priv));
Pavol Vican082afd02016-10-25 12:39:15 +020033
Michal Vaskofe7e5a72016-05-02 14:49:23 +020034static int
PavolVican196694c2017-01-27 10:33:09 +010035yang_check_string(struct lys_module *module, const char **target, char *what,
36 char *where, char *value, struct lys_node *node)
Pavol Vican2a064652016-02-02 22:54:34 +010037{
Pavol Vicanbf805472016-01-26 14:24:56 +010038 if (*target) {
Michal Vasko53b7da02018-02-13 15:28:42 +010039 LOGVAL(module->ctx, LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010040 free(value);
41 return 1;
42 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010043 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010044 return 0;
45 }
46}
47
Michal Vaskofe7e5a72016-05-02 14:49:23 +020048int
Pavol Vican5f0316a2016-04-05 21:21:11 +020049yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010050{
Pavol Vican6eb14e82016-02-03 12:27:13 +010051 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010052
53 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010054 case MODULE_KEYWORD:
55 module->name = lydict_insert_zc(module->ctx, value);
56 break;
57 case NAMESPACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010058 ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +010059 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010060 case ORGANIZATION_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010061 ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010062 break;
63 case CONTACT_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010064 ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010065 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020066 default:
67 free(value);
Michal Vasko53b7da02018-02-13 15:28:42 +010068 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +020069 ret = EXIT_FAILURE;
70 break;
Pavol Vican2a064652016-02-02 22:54:34 +010071 }
72
Pavol Vican021488a2016-01-25 23:56:12 +010073 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010074}
75
Michal Vaskofe7e5a72016-05-02 14:49:23 +020076int
Pavol Vicand0b64c12016-07-15 09:56:19 +020077yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
78{
79 int ret = EXIT_SUCCESS;
80
81 if (repeat) {
Michal Vasko53b7da02018-02-13 15:28:42 +010082 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
Michal Vasko3767fb22016-07-21 12:10:57 +020083 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020084 } else {
85 if (!strcmp(value, "1")) {
86 if (submodule) {
87 if (module->version > 1) {
Michal Vasko53b7da02018-02-13 15:28:42 +010088 LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
Pavol Vicand0b64c12016-07-15 09:56:19 +020089 ret = EXIT_FAILURE;
90 }
Radek Krejci29eac3d2017-06-01 16:50:02 +020091 submodule->version = 1;
Pavol Vicand0b64c12016-07-15 09:56:19 +020092 } else {
93 module->version = 1;
94 }
95 } else if (!strcmp(value, "1.1")) {
96 if (submodule) {
97 if (module->version != 2) {
Michal Vasko53b7da02018-02-13 15:28:42 +010098 LOGVAL(module->ctx, LYE_INVER, LY_VLOG_NONE, NULL);
Pavol Vicand0b64c12016-07-15 09:56:19 +020099 ret = EXIT_FAILURE;
100 }
Radek Krejci29eac3d2017-06-01 16:50:02 +0200101 submodule->version = 2;
Pavol Vicand0b64c12016-07-15 09:56:19 +0200102 } else {
103 module->version = 2;
104 }
105 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100106 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
Pavol Vicand0b64c12016-07-15 09:56:19 +0200107 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200108 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200109 }
110 free(value);
111 return ret;
112}
113
114int
Pavol Vicane024ab72016-07-27 14:27:43 +0200115yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100116{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100117 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100118
Michal Vasko53b7da02018-02-13 15:28:42 +0100119 if (!imp && lyp_check_identifier(module->ctx, value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100120 free(value);
121 return EXIT_FAILURE;
122 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200123
124 if (imp) {
PavolVican196694c2017-01-27 10:33:09 +0100125 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
Pavol Vicane024ab72016-07-27 14:27:43 +0200126 } else {
PavolVican196694c2017-01-27 10:33:09 +0100127 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +0100128 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100129
Pavol Vicanbf805472016-01-26 14:24:56 +0100130 return ret;
131}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100132
Pavol Vican1cc4e192016-10-24 16:38:31 +0200133static int
PavolVican7d0b5ab2017-02-01 13:06:53 +0100134yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
135 char *value, struct unres_schema *unres)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100136{
Pavol Vican0da132e2016-03-21 12:03:03 +0100137 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200138 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100139
Pavol Vican1cc4e192016-10-24 16:38:31 +0200140 if (!imp_old->prefix) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100141 LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 goto error;
143 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100144 if (lyp_check_identifier(module->ctx, imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +0200145 goto error;
146 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200147 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200148 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100149 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200150 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100151 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200152 module->imp_size++;
PavolVican7d0b5ab2017-02-01 13:06:53 +0100153 if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200154 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100155 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100156
Pavol Vican6eb14e82016-02-03 12:27:13 +0100157 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200158
159error:
160 free(value);
161 lydict_remove(module->ctx, imp_old->dsc);
162 lydict_remove(module->ctx, imp_old->ref);
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, ' '))) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100233 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
Michal Vasko97b32be2016-07-25 10:59:53 +0200234 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100287 LOGVAL(module->ctx, 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100302 LY_CHECK_ERR_RETURN(!retval, LOGMEM(module->ctx); 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100310 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100318 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100325 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100332 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100339 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100346 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100353 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100360 LOGVAL(module->ctx, 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) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100367 LOGVAL(module->ctx, 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100396 LY_CHECK_ERR_RETURN(!node, LOGMEM(module->ctx); free(value), NULL);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200397
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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100430 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +0200431 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100459 LOGINT(module->ctx);
Pavol Vican5f0316a2016-04-05 21:21:11 +0200460 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100483 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM(module->ctx), EXIT_FAILURE);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200484
Radek 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100509 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM(module->ctx), 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)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100527 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
528 LOGVAL(module->ctx, 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);
Michal Vasko53b7da02018-02-13 15:28:42 +0100535 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM(module->ctx), 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
Michal Vaskoe59ada92018-02-22 14:05:34 +0100567 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)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100585 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200586 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100587 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200588 if (stype->type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100589 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200590 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
Michal Vasko53b7da02018-02-13 15:28:42 +0100602yang_read_require_instance(struct ly_ctx *ctx, struct yang_type *stype, int req)
Pavol Vican81344ac2016-09-02 14:23:06 +0200603{
604 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100605 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican81344ac2016-09-02 14:23:06 +0200606 return EXIT_FAILURE;
607 }
608 if (stype->type->info.lref.req) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100609 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
Pavol Vican81344ac2016-09-02 14:23:06 +0200610 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{
Michal Vasko53b7da02018-02-13 15:28:42 +0100620 struct ly_ctx *ctx = module->ctx;
Radek Krejcidce5f972017-09-12 15:47:49 +0200621 int rc, ret = -1;
622 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200623 int8_t req;
Michal Vasko568b1952018-01-30 15:53:30 +0100624 const char *name, *value, *module_name = NULL;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100625 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200626 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200627 struct lys_type *dertype;
628 struct lys_type_enum *enms_sc = NULL;
629 struct lys_type_bit *bits_sc = NULL;
630 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100631 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100632
Pavol Vican0adf01d2016-03-22 12:29:33 +0100633 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100634 if (!value) {
635 goto error;
636 }
637
638 i = parse_identifier(value);
639 if (i < 1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100640 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
641 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100642 goto error;
643 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200644 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100645 name = value;
646 if (value[i]) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100647 module_name = lydict_insert(ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100648 name += i;
649 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100650 LOGVAL(ctx, LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
651 lydict_remove(ctx, module_name);
652 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100653 goto error;
654 }
655 ++name;
656 }
657
Michal Vasko568b1952018-01-30 15:53:30 +0100658 rc = resolve_superior_type(name, module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100659 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100660 LOGVAL(ctx, LYE_INMOD, LY_VLOG_NONE, NULL, module_name);
661 lydict_remove(ctx, module_name);
662 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100663 goto error;
664
Michal Vasko01c6fd22016-05-20 11:43:05 +0200665 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100666 } else if (rc == EXIT_FAILURE) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100667 LOGVAL(ctx, LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
668 lydict_remove(ctx, module_name);
669 lydict_remove(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100670 ret = EXIT_FAILURE;
671 goto error;
672 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100673 lydict_remove(ctx, module_name);
674 lydict_remove(ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200675
Pavol Vican7313fc02016-11-14 01:10:31 +0100676 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200677 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200678 * 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 +0200679 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
680 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200681 assert(((struct lys_node_grp *)siter)->unres_count);
682 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200683 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100684 LOGINT(ctx);
Radek Krejcic13db382016-08-16 10:52:42 +0200685 goto error;
686 }
687 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200688
689 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100690 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
691 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200692 goto error;
693 }
694
Pavol Vican8bd72e42016-08-29 09:53:05 +0200695 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100696 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100697 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100698 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100699 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100700 }
701 switch (base) {
702 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100703 if (type->base == LY_TYPE_BINARY) {
704 if (type->info.str.pat_count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100705 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100706 goto error;
707 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100708 type->info.binary.length = type->info.str.length;
Michal Vasko53b7da02018-02-13 15:28:42 +0100709 if (type->info.binary.length && lyp_check_length_range(ctx, type->info.binary.length->expr, type)) {
710 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100711 goto error;
712 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100713 } else if (type->base == LY_TYPE_STRING) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100714 if (type->info.str.length && lyp_check_length_range(ctx, type->info.str.length->expr, type)) {
715 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100716 goto error;
717 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100718 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100719 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100720 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100721 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100722 break;
723 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100724 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100725 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100726 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100727 /* decimal64 type directly derived from built-in type requires fraction-digits */
Michal Vasko53b7da02018-02-13 15:28:42 +0100728 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100729 goto error;
730 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100731 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100732 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Michal Vasko53b7da02018-02-13 15:28:42 +0100733 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100734 goto error;
735 }
Radek Krejci4800f652016-09-08 14:02:52 +0200736
737 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100738 if (type->der->type.der) {
739 type->info.dec64.dig = type->der->type.info.dec64.dig;
740 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200741 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100742 if (type->info.dec64.range && lyp_check_length_range(ctx, type->info.dec64.range->expr, type)) {
743 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200744 goto error;
745 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100746 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
747 if (type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100748 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100749 goto error;
750 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100751 type->info.num.range = type->info.dec64.range;
Michal Vasko53b7da02018-02-13 15:28:42 +0100752 if (type->info.num.range && lyp_check_length_range(ctx, type->info.num.range->expr, type)) {
753 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100754 goto error;
755 }
756 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100757 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100758 goto error;
759 }
760 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100761 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100762 if (type->base != LY_TYPE_ENUM) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100763 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100764 goto error;
765 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100766 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200767
768 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100769 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200770 /* type is derived directly from buit-in enumeartion type and enum statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100771 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200772 goto error;
773 }
774 } else {
775 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100776 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200777 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
778 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100779 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200780 goto error;
781 }
782
783 /* restricted enumeration type - the name MUST be used in the base type */
784 enms_sc = dertype->info.enums.enm;
Michal Vaskoe59ada92018-02-22 14:05:34 +0100785 for (i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200786 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100787 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200788 break;
789 }
790 }
791 if (j == dertype->info.enums.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100792 LOGVAL(ctx, LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200793 goto error;
794 }
795
Pavol Vican7313fc02016-11-14 01:10:31 +0100796 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200797 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100798 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200799 } else {
800 /* check that the assigned value corresponds to the original
801 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100802 if (type->info.enums.enm[i].value != enms_sc[j].value) {
803 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200804 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100805 LOGVAL(ctx, LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
Pavol Vican7313fc02016-11-14 01:10:31 +0100806 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200807 goto error;
808 }
809 }
810 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100811 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100812 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100813 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100814 if (type->base != LY_TYPE_BITS) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100815 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100816 goto error;
817 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100818 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200819
820 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100821 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200822 /* type is derived directly from buit-in bits type and bit statement is required */
Michal Vasko53b7da02018-02-13 15:28:42 +0100823 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200824 goto error;
825 }
826 } else {
827 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100828 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200829 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
830 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100831 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200832 goto error;
833 }
834
835 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100836 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200837 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200839 break;
840 }
841 }
842 if (j == dertype->info.bits.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100843 LOGVAL(ctx, LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200844 goto error;
845 }
846
847 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100848 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200849 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100850 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200851 } else {
852 /* check that the assigned position corresponds to the original
853 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100854 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
855 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200856 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100857 LOGVAL(ctx, LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
Pavol Vican7313fc02016-11-14 01:10:31 +0100858 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200859 goto error;
860 }
861 }
862 }
Pavol Vican03a59442016-03-21 15:23:45 +0100863 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200864
Radek Krejcidce5f972017-09-12 15:47:49 +0200865 for (i = type->info.bits.count; i > 0; i--) {
866 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200867
868 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100869 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200870 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100871 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
872 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
873 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200874 j--;
875 }
Pavol Vican03a59442016-03-21 15:23:45 +0100876 }
877 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100878 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100879 if (type->base == LY_TYPE_INST) {
880 if (type->info.lref.path) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100881 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100882 goto error;
883 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100884 if ((req = type->info.lref.req)) {
885 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200886 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100887 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200888 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100889 if (type->info.lref.req && (module->version < 2)) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100890 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
Pavol Vican92626d72016-09-21 09:36:09 +0200891 goto error;
892 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200893 /* flag resolving for later use */
894 if (!tpdftype) {
895 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
896 if (siter) {
897 /* just a flag - do not resolve */
898 tpdftype = 1;
899 }
900 }
901
Pavol Vican7313fc02016-11-14 01:10:31 +0100902 if (type->info.lref.path) {
903 if (type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100904 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican894ee0f2016-08-30 15:29:46 +0200905 goto error;
906 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100907 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100908 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100909 type->info.lref.path = transform_schema2json(module, value);
Michal Vasko53b7da02018-02-13 15:28:42 +0100910 lydict_remove(ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100911 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100912 goto error;
913 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200914 /* try to resolve leafref path only when this is instantiated
915 * leaf, so it is not:
916 * - typedef's type,
917 * - in grouping definition,
918 * - just instantiated in a grouping definition,
919 * because in those cases the nodes referenced in path might not be present
920 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100921 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100922 goto error;
923 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100924 } else if (!type->der->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100925 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100926 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200927 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200928 /* copy leafref definition into the derived type */
Michal Vasko53b7da02018-02-13 15:28:42 +0100929 type->info.lref.path = lydict_insert(ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200930 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100931 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200932 goto error;
933 }
Pavol Vican191613a2016-02-26 16:21:32 +0100934 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100935 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100936 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100937 goto error;
938 }
939 break;
940 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100941 if (type->base != LY_TYPE_IDENT) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100942 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100943 goto error;
944 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100945 if (type->der->type.der) {
946 if (type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100947 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
Pavol Vican07f220f2016-09-02 13:04:37 +0200948 goto error;
949 }
950 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100951 if (!type->info.ident.ref) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100952 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
Pavol Vican07f220f2016-09-02 13:04:37 +0200953 goto error;
954 }
955 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100956 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100957 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100958 if (type->base != LY_TYPE_UNION) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100959 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100960 goto error;
961 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100962 if (!type->info.uni.types) {
963 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100964 /* this is just a derived type with no additional type specified/required */
Michal Vaskob6ab50c2018-03-08 13:46:10 +0100965 assert(type->der->type.base == LY_TYPE_UNION);
966 type->info.uni.has_ptr_type = type->der->type.info.uni.has_ptr_type;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100967 break;
968 }
Michal Vasko53b7da02018-02-13 15:28:42 +0100969 LOGVAL(ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100970 goto error;
971 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100972 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100973 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100974 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
975 yang = (struct yang_type *)dertype->der;
976 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100977 dertype->parent = type->parent;
978 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100979 dertype->der = (struct lys_tpdf *)yang;
980 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100981 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100982 base = 0;
983 goto error;
984 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +0100985 lydict_remove(ctx, yang->name);
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100986 free(yang);
987 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100988 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200989 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100990 if (dertype->base == LY_TYPE_EMPTY) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100991 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200992 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100993 } else if (dertype->base == LY_TYPE_LEAFREF) {
Michal Vasko53b7da02018-02-13 15:28:42 +0100994 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200995 goto error;
996 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100997 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100998 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
999 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +01001000 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +01001001 }
Pavol Vicana4f045a2016-02-29 15:01:20 +01001002 }
1003 break;
Pavol Vicana1827962016-02-29 15:39:42 +01001004
1005 default:
1006 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001007 if (type->base != base) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001008 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001009 goto error;
1010 }
1011 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001012 LOGINT(ctx);
Pavol Vicana1827962016-02-29 15:39:42 +01001013 goto error;
1014 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001015 }
PavolVican92f23622017-12-12 13:35:56 +01001016
1017 /* if derived type has extension, which need validate data */
1018 dertype = &type->der->type;
1019 while (dertype->der) {
1020 if (dertype->parent->flags & LYS_VALID_DATA) {
1021 type->parent->flags |= LYS_VALID_DATA;
1022 }
1023 dertype = &dertype->der->type;
1024 }
1025
Pavol Vican73e7c992016-02-24 12:18:05 +01001026 return EXIT_SUCCESS;
1027
1028error:
Pavol Vican8bd72e42016-08-29 09:53:05 +02001029 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001030 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001031 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001032 return ret;
1033}
1034
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001035void
1036yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1037{
1038 struct lys_type *stype;
1039 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001040 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001041
1042 for (i = 0; i < type->info.uni.count; ++i) {
1043 stype = &type->info.uni.types[i];
1044 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1045 yang = (struct yang_type *)stype->der;
1046 stype->base = yang->base;
1047 lydict_remove(ctx, yang->name);
1048 free(yang);
1049 } else if (stype->base == LY_TYPE_UNION) {
1050 yang_free_type_union(ctx, stype);
1051 }
1052 }
1053}
1054
Pavol Vican73e7c992016-02-24 12:18:05 +01001055void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001056yang_read_type(struct ly_ctx *ctx, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001057{
1058 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001059 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001060
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001061 typ = calloc(1, sizeof *typ);
Michal Vasko53b7da02018-02-13 15:28:42 +01001062 LY_CHECK_ERR_RETURN(!typ, LOGMEM(ctx), NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001063
1064 typ->flags = LY_YANG_STRUCTURE_FLAG;
1065 switch (type) {
1066 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001067 if (((struct lys_node_leaf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001068 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
Pavol Vican85427f02016-09-26 15:21:05 +02001069 goto error;
1070 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001071 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1072 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1073 typ->type = &((struct lys_node_leaf *)parent)->type;
1074 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001075 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001076 if (((struct lys_node_leaflist *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001077 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
Pavol Vican85427f02016-09-26 15:21:05 +02001078 goto error;
1079 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001080 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1081 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1082 typ->type = &((struct lys_node_leaflist *)parent)->type;
1083 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001084 case UNION_KEYWORD:
1085 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1086 typ->type = (struct lys_type *)parent;
1087 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001088 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001089 if (((struct lys_tpdf *)parent)->type.der) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001090 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
Pavol Vican85427f02016-09-26 15:21:05 +02001091 goto error;
1092 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001093 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1094 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001095 break;
1096 case REPLACE_KEYWORD:
1097 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001098 dev = (struct lys_deviate *)parent;
1099 if (dev->type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001100 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001101 goto error;
1102 }
PavolVican75af21d2016-12-29 20:04:07 +01001103 dev->type = calloc(1, sizeof *dev->type);
Michal Vasko53b7da02018-02-13 15:28:42 +01001104 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001105 dev->type->der = (struct lys_tpdf *)typ;
1106 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001107 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001108 case EXTENSION_INSTANCE:
1109 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1110 typ->type = parent;
1111 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001112 default:
1113 goto error;
1114 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001115 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001116 typ->name = lydict_insert_zc(ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001117 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001118
1119error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001120 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001121 free(typ);
1122 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001123}
1124
1125void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001126yang_read_length(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001127{
PavolVicaneef1d912017-02-19 00:19:15 +01001128 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001129
PavolVicaneef1d912017-02-19 00:19:15 +01001130 if (is_ext_instance) {
1131 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001132 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001133 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1134 stype->base = LY_TYPE_STRING;
1135 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001136 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001137 goto error;
1138 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001139
PavolVicaneef1d912017-02-19 00:19:15 +01001140 if (stype->type->info.str.length) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001141 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001142 goto error;
1143 }
1144 length = calloc(1, sizeof *length);
Michal Vasko53b7da02018-02-13 15:28:42 +01001145 LY_CHECK_ERR_GOTO(!length, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001146 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001147 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001148 length->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001149 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001150
1151error:
1152 free(value);
1153 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001154}
Pavol Vican1c203db2016-02-24 14:05:23 +01001155
Pavol Vican6eecf302016-08-10 11:09:05 +02001156int
Michal Vasko53b7da02018-02-13 15:28:42 +01001157yang_read_pattern(struct ly_ctx *ctx, struct lys_restr *pattern, void **precomp, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001158{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001159 char *buf;
1160 size_t len;
1161
Michal Vasko53b7da02018-02-13 15:28:42 +01001162 if (precomp && lyp_precompile_pattern(ctx, value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001163 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001164 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001165 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001166
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001167 len = strlen(value);
1168 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Michal Vasko53b7da02018-02-13 15:28:42 +01001169 LY_CHECK_ERR_RETURN(!buf, LOGMEM(ctx); free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001170
1171 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001172 strcpy(&buf[1], value);
1173 free(value);
1174
Michal Vasko53b7da02018-02-13 15:28:42 +01001175 pattern->expr = lydict_insert_zc(ctx, buf);
Pavol Vican6eecf302016-08-10 11:09:05 +02001176 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001177}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001178
1179void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001180yang_read_range(struct ly_ctx *ctx, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001181{
PavolVicaneef1d912017-02-19 00:19:15 +01001182 struct lys_restr * range;
1183
1184 if (is_ext_instance) {
1185 range = (struct lys_restr *)stype;
1186 } else {
1187 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001188 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
PavolVicaneef1d912017-02-19 00:19:15 +01001189 goto error;
1190 }
1191 stype->base = LY_TYPE_DEC64;
1192 if (stype->type->info.dec64.range) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001193 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
PavolVicaneef1d912017-02-19 00:19:15 +01001194 goto error;
1195 }
1196 range = calloc(1, sizeof *range);
Michal Vasko53b7da02018-02-13 15:28:42 +01001197 LY_CHECK_ERR_GOTO(!range, LOGMEM(ctx), error);
PavolVicaneef1d912017-02-19 00:19:15 +01001198 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001199 }
Michal Vasko53b7da02018-02-13 15:28:42 +01001200 range->expr = lydict_insert_zc(ctx, value);
PavolVicaneef1d912017-02-19 00:19:15 +01001201 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001202
1203error:
1204 free(value);
1205 return NULL;
1206}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001207
1208int
Michal Vasko53b7da02018-02-13 15:28:42 +01001209yang_read_fraction(struct ly_ctx *ctx, struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001210{
Pavol Vican6b072512016-04-04 10:50:21 +02001211 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1212 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001213 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001214 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001215 goto error;
1216 }
1217 if (typ->type->info.dec64.dig) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001218 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001219 goto error;
1220 }
1221 /* range check */
1222 if (value < 1 || value > 18) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001223 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001224 goto error;
1225 }
1226 typ->type->info.dec64.dig = value;
1227 return EXIT_SUCCESS;
1228
1229error:
1230 return EXIT_FAILURE;
1231}
Pavol Vican79a763d2016-02-25 15:41:27 +01001232
Pavol Vican874715f2016-10-25 14:52:08 +02001233int
Michal Vasko53b7da02018-02-13 15:28:42 +01001234yang_read_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001235{
Pavol Vican874715f2016-10-25 14:52:08 +02001236 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001237
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001238 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001239 if (!value[0]) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001240 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1241 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
Pavol Vicanc6662412016-08-30 08:06:28 +02001242 free(value);
1243 goto error;
1244 }
1245
Michal Vasko53b7da02018-02-13 15:28:42 +01001246 enm->name = lydict_insert_zc(ctx, value);
Pavol Vican79a763d2016-02-25 15:41:27 +01001247
1248 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1249 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001250 LOGVAL(ctx, LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001251 goto error;
1252 }
1253
Pavol Vican874715f2016-10-25 14:52:08 +02001254 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001255 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001256 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001257 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001258 LOGVAL(ctx, LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001259 goto error;
1260 }
1261 }
1262
Pavol Vican874715f2016-10-25 14:52:08 +02001263 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001264
1265error:
Pavol Vican874715f2016-10-25 14:52:08 +02001266 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001267}
1268
1269int
Michal Vasko53b7da02018-02-13 15:28:42 +01001270yang_check_enum(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001271{
1272 int i, j;
1273
1274 if (!assign) {
1275 /* assign value automatically */
1276 if (*value > INT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001277 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001278 goto error;
1279 }
1280 enm->value = *value;
1281 enm->flags |= LYS_AUTOASSIGNED;
1282 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001283 } else if (typ->type->info.enums.enm == enm) {
1284 /* change value, which is assigned automatically, if first enum has value. */
1285 *value = typ->type->info.enums.enm[0].value;
1286 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001287 }
1288
1289 /* check that the value is unique */
1290 j = typ->type->info.enums.count-1;
1291 for (i = 0; i < j; i++) {
1292 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001293 LOGVAL(ctx, LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001294 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1295 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001296 goto error;
1297 }
1298 }
1299
1300 return EXIT_SUCCESS;
1301
1302error:
1303 return EXIT_FAILURE;
1304}
Pavol Vican9887c682016-02-29 11:32:01 +01001305
Pavol Vican59e8dee2016-10-25 15:29:38 +02001306int
Michal Vasko53b7da02018-02-13 15:28:42 +01001307yang_read_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001308{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001309 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001310
PavolVicane87cb932016-12-30 15:36:18 +01001311 typ->base = LY_TYPE_BITS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001312 bit->name = lydict_insert_zc(ctx, value);
1313 if (lyp_check_identifier(ctx, bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001314 goto error;
1315 }
Pavol Vican9887c682016-02-29 11:32:01 +01001316
Pavol Vican59e8dee2016-10-25 15:29:38 +02001317 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001318 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001319 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001320 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001321 LOGVAL(ctx, LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001322 goto error;
1323 }
1324 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001325 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001326
1327error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001328 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001329}
1330
1331int
Michal Vasko53b7da02018-02-13 15:28:42 +01001332yang_check_bit(struct ly_ctx *ctx, struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001333{
1334 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001335
1336 if (!assign) {
1337 /* assign value automatically */
1338 if (*value > UINT32_MAX) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001339 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001340 goto error;
1341 }
1342 bit->pos = (uint32_t)*value;
1343 bit->flags |= LYS_AUTOASSIGNED;
1344 (*value)++;
1345 }
1346
1347 j = typ->type->info.bits.count - 1;
1348 /* check that the value is unique */
1349 for (i = 0; i < j; i++) {
1350 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001351 LOGVAL(ctx, LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
Pavol Vican9887c682016-02-29 11:32:01 +01001352 goto error;
1353 }
1354 }
1355
Pavol Vican9887c682016-02-29 11:32:01 +01001356 return EXIT_SUCCESS;
1357
1358error:
1359 return EXIT_FAILURE;
1360}
Pavol Vican0df02b02016-03-01 10:28:50 +01001361
Pavol Vican3ad50f82016-12-04 15:00:36 +01001362int
1363yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001364{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001365 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001366 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001367 free(value);
1368 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001369 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001370 }
1371 aug->parent = parent;
1372 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001373 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001374}
Pavol Vican220e5a12016-03-03 14:19:43 +01001375
PavolVican6f000922017-02-10 12:56:59 +01001376void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001377yang_read_deviate_unsupported(struct ly_ctx *ctx, struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001378{
PavolVican75af21d2016-12-29 20:04:07 +01001379 if (dev->deviate_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001380 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001381 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001382 }
PavolVican75af21d2016-12-29 20:04:07 +01001383 dev->deviate = calloc(1, sizeof *dev->deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001384 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001385 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1386 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001387 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001388}
1389
1390void *
Michal Vasko53b7da02018-02-13 15:28:42 +01001391yang_read_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001392{
PavolVican75af21d2016-12-29 20:04:07 +01001393 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001394
PavolVican4b80d042017-02-23 14:30:27 +01001395 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001396 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1397 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001398 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001399 }
PavolVican75af21d2016-12-29 20:04:07 +01001400 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1401 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Michal Vasko53b7da02018-02-13 15:28:42 +01001402 LY_CHECK_ERR_RETURN(!deviate, LOGMEM(ctx), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001403 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1404 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001405 }
PavolVican75af21d2016-12-29 20:04:07 +01001406 dev->deviate[dev->deviate_size].mod = mod;
1407 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001408}
1409
1410int
PavolVican75af21d2016-12-29 20:04:07 +01001411yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001412{
1413 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001414 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001415
Pavol Vican85f12022016-03-05 16:30:35 +01001416 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001417 if (dev_target->nodetype == LYS_LEAFLIST) {
1418 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1419 } else if (dev_target->nodetype == LYS_LEAF) {
1420 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001421 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001422 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1423 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001424 goto error;
1425 }
1426
PavolVican75af21d2016-12-29 20:04:07 +01001427 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001428 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001429 if (!ly_strequal(*stritem, deviate->units, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001430 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
1431 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001432 goto error;
1433 }
1434 /* remove current units value of the target */
1435 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001436 *stritem = NULL;
1437 /* remove its extensions */
1438 j = -1;
1439 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1440 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1441 --j;
1442 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001443 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001444 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001445 /* check that there is no current value */
1446 if (*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001447 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1448 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001449 goto error;
1450 }
1451 } else { /* replace */
1452 if (!*stritem) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001453 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1454 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001455 goto error;
1456 }
1457 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001458 /* remove current units value of the target ... */
1459 lydict_remove(ctx, *stritem);
1460
1461 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001462 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001463 }
1464
Pavol Vican85f12022016-03-05 16:30:35 +01001465 return EXIT_SUCCESS;
1466
1467error:
1468 return EXIT_FAILURE;
1469}
1470
1471int
PavolVican75af21d2016-12-29 20:04:07 +01001472yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001473{
Michal Vasko53b7da02018-02-13 15:28:42 +01001474 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican85f12022016-03-05 16:30:35 +01001475 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001476 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001477
1478 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001479 if (dev_target->nodetype != LYS_LIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001480 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1481 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001482 goto error;
1483 }
1484
PavolVican75af21d2016-12-29 20:04:07 +01001485 list = (struct lys_node_list *)dev_target;
1486 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001487 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001488 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Michal Vasko53b7da02018-02-13 15:28:42 +01001489 LY_CHECK_ERR_GOTO(!unique, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001490 list->unique = unique;
1491 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001492 }
1493
1494 return EXIT_SUCCESS;
1495
1496error:
1497 return EXIT_FAILURE;
1498}
1499
1500int
PavolVican75af21d2016-12-29 20:04:07 +01001501yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1502 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001503{
1504 struct lys_node *node;
1505 struct lys_node_choice *choice;
1506 struct lys_node_leaf *leaf;
1507 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001508 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001509 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001510
Pavol Vican38321d02016-08-16 14:56:02 +02001511 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001512 if (dev_target->nodetype == LYS_CHOICE) {
1513 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001514 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1515 if (rc || !node) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001516 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001517 goto error;
1518 }
PavolVican75af21d2016-12-29 20:04:07 +01001519 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001520 if (!choice->dflt || (choice->dflt != node)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001521 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1522 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001523 goto error;
1524 }
PavolVican6f000922017-02-10 12:56:59 +01001525 choice->dflt = NULL;
1526 /* remove extensions of this default instance from the target node */
1527 j = -1;
1528 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1529 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1530 --j;
1531 }
Pavol Vican38321d02016-08-16 14:56:02 +02001532 } else { /* add or replace */
1533 choice->dflt = node;
1534 if (!choice->dflt) {
1535 /* default branch not found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001536 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
Pavol Vican38321d02016-08-16 14:56:02 +02001537 goto error;
1538 }
1539 }
PavolVican75af21d2016-12-29 20:04:07 +01001540 } else if (dev_target->nodetype == LYS_LEAF) {
1541 leaf = (struct lys_node_leaf *)dev_target;
1542 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001543 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001544 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1545 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vican38321d02016-08-16 14:56:02 +02001546 goto error;
1547 }
1548 /* remove value */
1549 lydict_remove(ctx, leaf->dflt);
1550 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001551 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001552 /* remove extensions of this default instance from the target node */
1553 j = -1;
1554 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1555 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1556 --j;
1557 }
Pavol Vican38321d02016-08-16 14:56:02 +02001558 } else { /* add (already checked) and replace */
1559 /* remove value */
1560 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001561 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001562
1563 /* set new value */
1564 leaf->dflt = lydict_insert(ctx, value, u);
1565
1566 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001567 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001568 }
1569 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001570 llist = (struct lys_node_leaflist *)dev_target;
1571 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001572 /* find and remove the value in target list */
1573 for (i = 0; i < llist->dflt_size; i++) {
1574 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1575 /* match, remove the value */
1576 lydict_remove(llist->module->ctx, llist->dflt[i]);
1577 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001578 /* remove extensions of this default instance from the target node */
1579 j = -1;
1580 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1581 if (dev_target->ext[j]->insubstmt_index == i) {
1582 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1583 --j;
1584 } else if (dev_target->ext[j]->insubstmt_index > i) {
1585 /* decrease the substatement index of the extension because of the changed array of defaults */
1586 dev_target->ext[j]->insubstmt_index--;
1587 }
1588 }
Pavol Vican38321d02016-08-16 14:56:02 +02001589 break;
1590 }
1591 }
1592 if (i == llist->dflt_size) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001593 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1594 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
Pavol Vican38321d02016-08-16 14:56:02 +02001595 goto error;
1596 }
1597 } else {
1598 /* add or replace, anyway we place items into the deviate's list
1599 which propagates to the target */
1600 /* we just want to check that the value isn't already in the list */
1601 for (i = 0; i < llist->dflt_size; i++) {
1602 if (ly_strequal(llist->dflt[i], value, 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001603 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1604 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
Pavol Vican38321d02016-08-16 14:56:02 +02001605 goto error;
1606 }
1607 }
1608 /* store it in target node */
1609 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1610
1611 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001612 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001613 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001614 }
1615 }
1616
1617 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001618
Pavol Vican38321d02016-08-16 14:56:02 +02001619error:
1620 return EXIT_FAILURE;
1621}
1622
Pavol Vican38321d02016-08-16 14:56:02 +02001623int
PavolVican75af21d2016-12-29 20:04:07 +01001624yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1625 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001626{
Michal Vasko53b7da02018-02-13 15:28:42 +01001627 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001628 int i;
1629 struct lys_node_leaflist *llist;
1630 const char **dflt;
1631
1632 /* check target node type */
1633 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001634 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1635 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001636 goto error;
1637 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
Michal Vasko53b7da02018-02-13 15:28:42 +01001638 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1639 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
PavolVican75af21d2016-12-29 20:04:07 +01001640 goto error;
1641 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001642 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1643 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001644 goto error;
1645 }
1646
PavolVican75af21d2016-12-29 20:04:07 +01001647 if (deviate->mod == LY_DEVIATE_ADD) {
1648 /* check that there is no current value */
1649 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1650 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001651 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1652 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
PavolVican75af21d2016-12-29 20:04:07 +01001653 goto error;
1654 }
Pavol Vican85f12022016-03-05 16:30:35 +01001655
PavolVican75af21d2016-12-29 20:04:07 +01001656 /* check collision with mandatory/min-elements */
1657 if ((dev_target->flags & LYS_MAND_TRUE) ||
1658 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001659 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1660 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
PavolVican75af21d2016-12-29 20:04:07 +01001661 "Adding the \"default\" statement is forbidden on %s statement.",
1662 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1663 goto error;
1664 }
1665 } else if (deviate->mod == LY_DEVIATE_RPL) {
1666 /* check that there was a value before */
1667 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1668 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001669 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1670 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
PavolVican75af21d2016-12-29 20:04:07 +01001671 goto error;
1672 }
1673 }
Pavol Vican85f12022016-03-05 16:30:35 +01001674
PavolVican75af21d2016-12-29 20:04:07 +01001675 if (dev_target->nodetype == LYS_LEAFLIST) {
1676 /* reallocate default list in the target */
1677 llist = (struct lys_node_leaflist *)dev_target;
1678 if (deviate->mod == LY_DEVIATE_ADD) {
1679 /* reallocate (enlarge) the unique array of the target */
1680 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001681 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001682 llist->dflt = dflt;
1683 } else if (deviate->mod == LY_DEVIATE_RPL) {
1684 /* reallocate (replace) the unique array of the target */
1685 for (i = 0; i < llist->dflt_size; i++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001686 lydict_remove(ctx, llist->dflt[i]);
PavolVican75af21d2016-12-29 20:04:07 +01001687 }
1688 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Michal Vasko53b7da02018-02-13 15:28:42 +01001689 LY_CHECK_ERR_GOTO(!dflt, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001690 llist->dflt = dflt;
1691 llist->dflt_size = 0;
1692 }
1693 }
1694
1695 for (i = 0; i < deviate->dflt_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001696 if (yang_fill_deviate_default(ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
PavolVican75af21d2016-12-29 20:04:07 +01001697 goto error;
1698 }
1699 }
Pavol Vican85f12022016-03-05 16:30:35 +01001700
1701 return EXIT_SUCCESS;
1702
1703error:
1704 return EXIT_FAILURE;
1705}
1706
1707int
PavolVican75af21d2016-12-29 20:04:07 +01001708yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001709{
Michal Vasko53b7da02018-02-13 15:28:42 +01001710 struct ly_ctx *ctx = dev_target->module->ctx;
Radek Krejcie00d2312016-08-12 15:27:49 +02001711 struct lys_node *parent;
1712
Pavol Vican85f12022016-03-05 16:30:35 +01001713 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001714 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001715 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1716 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001717 goto error;
1718 }
1719
PavolVican75af21d2016-12-29 20:04:07 +01001720 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001721 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001722 if (dev_target->flags & LYS_MAND_MASK) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001723 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1724 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001725 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001726 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001727 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001728 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
Michal Vasko53b7da02018-02-13 15:28:42 +01001729 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1730 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001731 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001732 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001733 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1734 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
Pavol Vican321a02e2016-04-05 16:11:59 +02001735 goto error;
1736 }
Pavol Vican85f12022016-03-05 16:30:35 +01001737 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001738 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001739 if (!(dev_target->flags & LYS_MAND_MASK)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001740 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1741 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001742 goto error;
1743 }
Pavol Vican85f12022016-03-05 16:30:35 +01001744 }
1745
Pavol Vican85f12022016-03-05 16:30:35 +01001746 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001747 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001748
1749 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001750 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001751
Radek Krejcie00d2312016-08-12 15:27:49 +02001752 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001753 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001754 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1755 parent = parent->parent) {
1756 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1757 /* stop also on presence containers */
1758 break;
1759 }
1760 }
1761 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1762 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1763 if (lyp_check_mandatory_choice(parent)) {
1764 goto error;
1765 }
1766 }
1767
Pavol Vican85f12022016-03-05 16:30:35 +01001768 return EXIT_SUCCESS;
1769
1770error:
1771 return EXIT_FAILURE;
1772}
1773
1774int
PavolVican75af21d2016-12-29 20:04:07 +01001775yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001776{
Michal Vasko53b7da02018-02-13 15:28:42 +01001777 struct ly_ctx *ctx = dev_target->module->ctx;
Pavol Vican09adcc32016-08-25 10:51:36 +02001778 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001779
1780 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001781 if (dev_target->nodetype == LYS_LEAFLIST) {
1782 max = &((struct lys_node_leaflist *)dev_target)->max;
1783 min = &((struct lys_node_leaflist *)dev_target)->min;
1784 } else if (dev_target->nodetype == LYS_LIST) {
1785 max = &((struct lys_node_list *)dev_target)->max;
1786 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001787 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001788 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1789 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"%s\" property.", (type) ? "max-elements" : "min-elements");
Pavol Vican85f12022016-03-05 16:30:35 +01001790 goto error;
1791 }
1792
PavolVican75af21d2016-12-29 20:04:07 +01001793 ui32val = (type) ? max : min;
1794 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001795 /* check that there is no current value */
1796 if (*ui32val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001797 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1798 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001799 goto error;
1800 }
PavolVican75af21d2016-12-29 20:04:07 +01001801 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001802 /* unfortunately, there is no way to check reliably that there
1803 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001804 }
1805
1806 /* add (already checked) and replace */
1807 /* set new value specified in deviation */
1808 *ui32val = value;
1809
Pavol Vican09adcc32016-08-25 10:51:36 +02001810 /* check min-elements is smaller than max-elements */
1811 if (*max && *min > *max) {
1812 if (type) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001813 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1814 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001815 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01001816 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1817 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
Pavol Vican09adcc32016-08-25 10:51:36 +02001818 }
1819 goto error;
1820 }
1821
Pavol Vican85f12022016-03-05 16:30:35 +01001822 return EXIT_SUCCESS;
1823
1824error:
1825 return EXIT_FAILURE;
1826}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001827
1828int
PavolVican75af21d2016-12-29 20:04:07 +01001829yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1830 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001831{
Michal Vasko53b7da02018-02-13 15:28:42 +01001832 struct ly_ctx *ctx = module->ctx;
PavolVican75af21d2016-12-29 20:04:07 +01001833 int i, j, erase_must = 1;
1834 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001835 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001836
PavolVican75af21d2016-12-29 20:04:07 +01001837 /* check target node type */
1838 switch (dev_target->nodetype) {
1839 case LYS_LEAF:
1840 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1841 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001842 break;
PavolVican75af21d2016-12-29 20:04:07 +01001843 case LYS_CONTAINER:
1844 trg_must = &((struct lys_node_container *)dev_target)->must;
1845 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1846 break;
1847 case LYS_LEAFLIST:
1848 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1849 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1850 break;
1851 case LYS_LIST:
1852 trg_must = &((struct lys_node_list *)dev_target)->must;
1853 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1854 break;
1855 case LYS_ANYXML:
1856 case LYS_ANYDATA:
1857 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1858 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1859 break;
1860 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01001861 LOGVAL(ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1862 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01001863 goto error;
1864 }
1865
1866 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001867 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001868
1869 if (deviate->mod == LY_DEVIATE_ADD) {
1870 /* reallocate the must array of the target */
1871 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Michal Vasko53b7da02018-02-13 15:28:42 +01001872 LY_CHECK_ERR_GOTO(!must, LOGMEM(ctx), error);
PavolVican75af21d2016-12-29 20:04:07 +01001873 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001874 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001875 free(deviate->must);
1876 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001877 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001878 erase_must = 0;
1879 } else if (deviate->mod == LY_DEVIATE_DEL) {
1880 /* find must to delete, we are ok with just matching conditions */
1881 for (j = 0; j < deviate->must_size; ++j) {
1882 for (i = 0; i < *trg_must_size; i++) {
1883 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1884 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001885 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001886 /* ... and maintain the array */
1887 (*trg_must_size)--;
1888 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001889 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001890 }
1891 if (!(*trg_must_size)) {
1892 free(*trg_must);
1893 *trg_must = NULL;
1894 } else {
PavolVican214408f2017-02-03 11:54:05 +01001895 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001896 }
1897
1898 i = -1; /* set match flag */
1899 break;
1900 }
1901 }
1902 if (i != -1) {
1903 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001904 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1905 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
PavolVican75af21d2016-12-29 20:04:07 +01001906 goto error;
1907 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001908 }
1909 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001910
PavolVican6f000922017-02-10 12:56:59 +01001911 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1912 goto error;
1913 }
PavolVican75af21d2016-12-29 20:04:07 +01001914 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02001915 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1916 && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001917 goto error;
1918 }
1919
PavolVican75af21d2016-12-29 20:04:07 +01001920 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01001921
PavolVican75af21d2016-12-29 20:04:07 +01001922error:
1923 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1924 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001925 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001926 }
1927 free(deviate->must);
1928 }
1929 return EXIT_FAILURE;
1930}
1931
1932int
1933yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1934 struct lys_node_list *list, int index, char * value)
1935{
Michal Vasko53b7da02018-02-13 15:28:42 +01001936 struct ly_ctx *ctx = module->ctx;
PavolVican6f000922017-02-10 12:56:59 +01001937 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001938
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001939 /* find unique structures to delete */
1940 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001941 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001942 continue;
1943 }
1944
PavolVican75af21d2016-12-29 20:04:07 +01001945 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1946 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001947 break;
1948 }
1949 }
1950
PavolVican75af21d2016-12-29 20:04:07 +01001951 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001952 /* we have a match, free the unique structure ... */
1953 for (j = 0; j < list->unique[i].expr_size; j++) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001954 lydict_remove(ctx, list->unique[i].expr[j]);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001955 }
1956 free(list->unique[i].expr);
1957 /* ... and maintain the array */
1958 list->unique_size--;
1959 if (i != list->unique_size) {
1960 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1961 list->unique[i].expr = list->unique[list->unique_size].expr;
1962 }
1963
1964 if (!list->unique_size) {
1965 free(list->unique);
1966 list->unique = NULL;
1967 } else {
1968 list->unique[list->unique_size].expr_size = 0;
1969 list->unique[list->unique_size].expr = NULL;
1970 }
1971
PavolVican6f000922017-02-10 12:56:59 +01001972 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001973 i = -1; /* set match flag */
1974 break;
1975 }
1976 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001977
1978 if (i != -1) {
1979 /* no match found */
Michal Vasko53b7da02018-02-13 15:28:42 +01001980 LOGVAL(ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1981 LOGVAL(ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001982 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001983 }
1984
PavolVican6f000922017-02-10 12:56:59 +01001985 /* remove extensions of this unique instance from the target node */
1986 j = -1;
1987 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1988 if (list->ext[j]->insubstmt_index == k) {
Michal Vasko53b7da02018-02-13 15:28:42 +01001989 lyp_ext_instance_rm(ctx, &list->ext, &list->ext_size, j);
PavolVican6f000922017-02-10 12:56:59 +01001990 --j;
1991 } else if (list->ext[j]->insubstmt_index > k) {
1992 /* decrease the substatement index of the extension because of the changed array of uniques */
1993 list->ext[j]->insubstmt_index--;
1994 }
1995 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001996 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001997}
Pavol Vican021488a2016-01-25 23:56:12 +01001998
PavolVican75af21d2016-12-29 20:04:07 +01001999int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01002000{
PavolVican75af21d2016-12-29 20:04:07 +01002001 struct lys_node_list *list;
2002 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01002003 uint i = 0;
2004 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01002005
PavolVican75af21d2016-12-29 20:04:07 +01002006 if (yang_read_deviate_unique(deviate, dev_target)) {
2007 goto error;
2008 }
2009 list = (struct lys_node_list *)dev_target;
2010 last_unique = &list->unique[list->unique_size];
2011 for (i = 0; i < deviate->unique_size; ++i) {
2012 str = (char *) deviate->unique[i].expr;
2013 if (deviate->mod == LY_DEVIATE_ADD) {
2014 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
2015 free(str);
2016 goto error;
2017 }
2018 list->unique_size++;
2019 } else if (deviate->mod == LY_DEVIATE_DEL) {
2020 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2021 free(str);
2022 goto error;
2023 }
2024 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2025 free(str);
2026 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002027 }
2028 }
PavolVican75af21d2016-12-29 20:04:07 +01002029 free(str);
2030 }
2031 if (deviate->mod == LY_DEVIATE_ADD) {
2032 free(deviate->unique);
2033 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002034 }
Pavol Vican38321d02016-08-16 14:56:02 +02002035
PavolVican75af21d2016-12-29 20:04:07 +01002036 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01002037
Pavol Vican021488a2016-01-25 23:56:12 +01002038error:
PavolVican75af21d2016-12-29 20:04:07 +01002039 if (deviate->mod == LY_DEVIATE_ADD) {
2040 for (i = i + 1; i < deviate->unique_size; ++i) {
2041 free(deviate->unique[i].expr);
2042 }
2043 free(deviate->unique);
2044 deviate->unique = last_unique;
2045
2046 }
Pavol Vican021488a2016-01-25 23:56:12 +01002047 return EXIT_FAILURE;
2048}
2049
Pavol Vicanec423c92016-10-24 21:33:43 +02002050static int
2051yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2052 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002053{
Pavol Vican55870412016-03-10 12:36:21 +01002054 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002055 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002056 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002057
Pavol Vicanec423c92016-10-24 21:33:43 +02002058 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002059 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002060 if (!rc) {
2061 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002062 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002063 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2064 &trg->inc[trg->inc_size], unres)) {
2065 ret = -1;
2066 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002067 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002068 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002069 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002070 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002071 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002072
Pavol Vicanec423c92016-10-24 21:33:43 +02002073 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002074 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002075}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002076
PavolVicanc1807262017-01-31 18:00:27 +01002077struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002078yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002079{
2080 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2081 LYEXT_PAR parent_type;
2082 uint8_t *size;
2083
2084 switch (type) {
2085 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002086 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002087 ext = &((struct lys_module *)node)->ext;
2088 size = &((struct lys_module *)node)->ext_size;
2089 parent_type = LYEXT_PAR_MODULE;
2090 break;
PavolVican22e88682017-02-14 22:38:18 +01002091 case BELONGS_TO_KEYWORD:
2092 if (is_ext_instance) {
2093 ext = &((struct lys_ext_instance *)node)->ext;
2094 size = &((struct lys_ext_instance *)node)->ext_size;
2095 parent_type = LYEXT_PAR_EXTINST;
2096 } else {
2097 ext = &((struct lys_module *)node)->ext;
2098 size = &((struct lys_module *)node)->ext_size;
2099 parent_type = LYEXT_PAR_MODULE;
2100 }
2101 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002102 case IMPORT_KEYWORD:
2103 ext = &((struct lys_import *)node)->ext;
2104 size = &((struct lys_import *)node)->ext_size;
2105 parent_type = LYEXT_PAR_IMPORT;
2106 break;
2107 case INCLUDE_KEYWORD:
2108 ext = &((struct lys_include *)node)->ext;
2109 size = &((struct lys_include *)node)->ext_size;
2110 parent_type = LYEXT_PAR_INCLUDE;
2111 break;
PavolVican171717d2017-02-01 14:49:55 +01002112 case REVISION_KEYWORD:
2113 ext = &((struct lys_revision *)node)->ext;
2114 size = &((struct lys_revision *)node)->ext_size;
2115 parent_type = LYEXT_PAR_REVISION;
2116 break;
PavolVican70ce7452017-02-01 15:39:39 +01002117 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002118 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002119 case LEAF_KEYWORD:
2120 case LEAF_LIST_KEYWORD:
2121 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002122 case CHOICE_KEYWORD:
2123 case CASE_KEYWORD:
2124 case ANYXML_KEYWORD:
2125 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002126 case USES_KEYWORD:
2127 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002128 case ACTION_KEYWORD:
2129 case RPC_KEYWORD:
2130 case INPUT_KEYWORD:
2131 case OUTPUT_KEYWORD:
2132 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002133 ext = &((struct lys_node *)node)->ext;
2134 size = &((struct lys_node *)node)->ext_size;
2135 parent_type = LYEXT_PAR_NODE;
2136 break;
PavolVican19dc6152017-02-06 12:04:15 +01002137 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002138 if (is_ext_instance) {
2139 ext = &((struct lys_ext_instance *)node)->ext;
2140 size = &((struct lys_ext_instance *)node)->ext_size;
2141 parent_type = LYEXT_PAR_EXTINST;
2142 } else {
2143 ext = &((struct lys_ext *)node)->ext;
2144 size = &((struct lys_ext *)node)->ext_size;
2145 parent_type = LYEXT_PAR_EXT;
2146 }
2147 break;
PavolVican19dc6152017-02-06 12:04:15 +01002148 case EXTENSION_KEYWORD:
2149 ext = &((struct lys_ext *)node)->ext;
2150 size = &((struct lys_ext *)node)->ext_size;
2151 parent_type = LYEXT_PAR_EXT;
2152 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002153 case FEATURE_KEYWORD:
2154 ext = &((struct lys_feature *)node)->ext;
2155 size = &((struct lys_feature *)node)->ext_size;
2156 parent_type = LYEXT_PAR_FEATURE;
2157 break;
PavolVican8fa31242017-02-07 11:04:26 +01002158 case IDENTITY_KEYWORD:
2159 ext = &((struct lys_ident *)node)->ext;
2160 size = &((struct lys_ident *)node)->ext_size;
2161 parent_type = LYEXT_PAR_IDENT;
2162 break;
2163 case IF_FEATURE_KEYWORD:
2164 ext = &((struct lys_iffeature *)node)->ext;
2165 size = &((struct lys_iffeature *)node)->ext_size;
2166 parent_type = LYEXT_PAR_IFFEATURE;
2167 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002168 case TYPEDEF_KEYWORD:
2169 ext = &((struct lys_tpdf *)node)->ext;
2170 size = &((struct lys_tpdf *)node)->ext_size;
2171 parent_type = LYEXT_PAR_TPDF;
2172 break;
PavolVican056fcd12017-02-07 15:36:53 +01002173 case TYPE_KEYWORD:
2174 ext = &((struct yang_type *)node)->type->ext;
2175 size = &((struct yang_type *)node)->type->ext_size;
2176 parent_type = LYEXT_PAR_TYPE;
2177 break;
2178 case LENGTH_KEYWORD:
2179 case PATTERN_KEYWORD:
2180 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002181 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002182 ext = &((struct lys_restr *)node)->ext;
2183 size = &((struct lys_restr *)node)->ext_size;
2184 parent_type = LYEXT_PAR_RESTR;
2185 break;
PavolVican59ba4602017-02-08 11:53:32 +01002186 case WHEN_KEYWORD:
2187 ext = &((struct lys_when *)node)->ext;
2188 size = &((struct lys_when *)node)->ext_size;
2189 parent_type = LYEXT_PAR_RESTR;
2190 break;
PavolVican056fcd12017-02-07 15:36:53 +01002191 case ENUM_KEYWORD:
2192 ext = &((struct lys_type_enum *)node)->ext;
2193 size = &((struct lys_type_enum *)node)->ext_size;
2194 parent_type = LYEXT_PAR_TYPE_ENUM;
2195 break;
2196 case BIT_KEYWORD:
2197 ext = &((struct lys_type_bit *)node)->ext;
2198 size = &((struct lys_type_bit *)node)->ext_size;
2199 parent_type = LYEXT_PAR_TYPE_BIT;
2200 break;
PavolVican77374ee2017-02-08 15:18:45 +01002201 case REFINE_KEYWORD:
2202 ext = &((struct lys_type_bit *)node)->ext;
2203 size = &((struct lys_type_bit *)node)->ext_size;
2204 parent_type = LYEXT_PAR_REFINE;
2205 break;
PavolVican6f000922017-02-10 12:56:59 +01002206 case DEVIATION_KEYWORD:
2207 ext = &((struct lys_deviation *)node)->ext;
2208 size = &((struct lys_deviation *)node)->ext_size;
2209 parent_type = LYEXT_PAR_DEVIATION;
2210 break;
2211 case NOT_SUPPORTED_KEYWORD:
2212 case ADD_KEYWORD:
2213 case DELETE_KEYWORD:
2214 case REPLACE_KEYWORD:
2215 ext = &((struct lys_deviate *)node)->ext;
2216 size = &((struct lys_deviate *)node)->ext_size;
2217 parent_type = LYEXT_PAR_DEVIATE;
2218 break;
PavolVicandefa4852017-02-10 13:13:23 +01002219 case EXTENSION_INSTANCE:
2220 ext = &((struct lys_ext_instance *)node)->ext;
2221 size = &((struct lys_ext_instance *)node)->ext_size;
2222 parent_type = LYEXT_PAR_EXTINST;
2223 break;
PavolVicanc1807262017-01-31 18:00:27 +01002224 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002225 LOGINT(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002226 return NULL;
2227 }
2228
2229 instance = calloc(1, sizeof *instance);
2230 if (!instance) {
2231 goto error;
2232 }
2233 instance->parent_type = parent_type;
2234 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2235 if (!tmp) {
2236 goto error;
2237 }
2238 tmp[*size] = instance;
2239 *ext = tmp;
2240 (*size)++;
2241 return instance;
2242
2243error:
Michal Vasko53b7da02018-02-13 15:28:42 +01002244 LOGMEM(NULL);
PavolVicanc1807262017-01-31 18:00:27 +01002245 free(instance);
2246 return NULL;
2247}
2248
2249void *
2250yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002251 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002252{
2253 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002254 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002255
2256 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002257 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002258 if (!instance) {
2259 return NULL;
2260 }
PavolVicanc1807262017-01-31 18:00:27 +01002261 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002262 case YANG_VERSION_KEYWORD:
2263 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002264 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002265 break;
PavolVicanc1807262017-01-31 18:00:27 +01002266 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002267 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002268 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002269 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002270 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002271 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002272 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002273 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002274 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002275 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002276 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002277 break;
2278 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002279 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002280 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002281 break;
2282 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002283 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002284 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002285 break;
PavolVican171717d2017-02-01 14:49:55 +01002286 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002287 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002288 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002289 break;
2290 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002291 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002292 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002293 break;
PavolVican19dc6152017-02-06 12:04:15 +01002294 case YIN_ELEMENT_KEYWORD:
2295 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002296 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002297 break;
2298 case STATUS_KEYWORD:
2299 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002300 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002301 break;
PavolVican8fa31242017-02-07 11:04:26 +01002302 case BASE_KEYWORD:
2303 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002304 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002305 if (backup_type == IDENTITY_KEYWORD) {
2306 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002307 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002308 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2309 }
PavolVican8fa31242017-02-07 11:04:26 +01002310 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002311 case DEFAULT_KEYWORD:
2312 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002313 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002314 switch (backup_type) {
2315 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002316 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002317 break;
2318 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002319 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002320 break;
2321 case ADD_KEYWORD:
2322 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2323 break;
2324 default:
2325 /* nothing changes */
2326 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002327 }
PavolVicandf9e7972017-02-07 11:41:38 +01002328 break;
2329 case UNITS_KEYWORD:
2330 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002331 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002332 break;
PavolVican056fcd12017-02-07 15:36:53 +01002333 case REQUIRE_INSTANCE_KEYWORD:
2334 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002335 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002336 break;
2337 case PATH_KEYWORD:
2338 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002339 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002340 break;
2341 case ERROR_MESSAGE_KEYWORD:
2342 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002343 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002344 break;
2345 case ERROR_APP_TAG_KEYWORD:
2346 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002347 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002348 break;
2349 case MODIFIER_KEYWORD:
2350 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002351 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002352 break;
2353 case FRACTION_DIGITS_KEYWORD:
2354 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002355 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002356 break;
2357 case VALUE_KEYWORD:
2358 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002359 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002360 break;
2361 case POSITION_KEYWORD:
2362 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002363 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002364 break;
PavolVican5b910842017-02-08 13:08:47 +01002365 case PRESENCE_KEYWORD:
2366 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002367 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002368 break;
2369 case CONFIG_KEYWORD:
2370 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002371 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002372 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002373 case MANDATORY_KEYWORD:
2374 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002375 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002376 break;
2377 case MIN_ELEMENTS_KEYWORD:
2378 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002379 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002380 break;
2381 case MAX_ELEMENTS_KEYWORD:
2382 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002383 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002384 break;
2385 case ORDERED_BY_KEYWORD:
2386 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002387 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002388 break;
2389 case KEY_KEYWORD:
2390 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002391 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002392 break;
2393 case UNIQUE_KEYWORD:
2394 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002395 stmt = LY_STMT_UNIQUE;
2396 switch (backup_type) {
2397 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002398 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002399 break;
2400 case ADD_KEYWORD:
2401 case DELETE_KEYWORD:
2402 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002403 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002404 break;
2405 default:
2406 /* nothing changes */
2407 break;
PavolVican6f000922017-02-10 12:56:59 +01002408 }
PavolVican3feb2f92017-02-08 13:44:39 +01002409 break;
PavolVicanc1807262017-01-31 18:00:27 +01002410 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01002411 LOGINT(module->ctx);
PavolVicanc1807262017-01-31 18:00:27 +01002412 return NULL;
2413 }
2414 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002415 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002416 if (!instance) {
2417 return NULL;
2418 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002419 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002420 switch (actual_type) {
2421 case ARGUMENT_KEYWORD:
2422 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002423 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002424 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002425 case BELONGS_TO_KEYWORD:
2426 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002427 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002428 break;
PavolVican19dc6152017-02-06 12:04:15 +01002429 default:
2430 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2431 break;
2432 }
PavolVicanc1807262017-01-31 18:00:27 +01002433 }
2434 instance->flags |= LYEXT_OPT_YANG;
2435 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2436 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002437 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2438 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2439 }
PavolVicanc1807262017-01-31 18:00:27 +01002440 return instance;
2441}
2442
PavolVican05c4f9b2017-09-07 13:33:54 +02002443static int
2444check_status_flag(struct lys_node *node, struct lys_node *parent)
2445{
Michal Vasko53b7da02018-02-13 15:28:42 +01002446 struct ly_ctx *ctx = node->module->ctx;
PavolVican05c4f9b2017-09-07 13:33:54 +02002447 char *str;
2448
Radek Krejcie4dce292017-10-30 11:16:47 +01002449 if (node->nodetype & (LYS_OUTPUT | LYS_INPUT)) {
2450 return EXIT_SUCCESS;
2451 }
2452
PavolVican05c4f9b2017-09-07 13:33:54 +02002453 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2454 /* status is not inherited by specification, but it not make sense to have
2455 * current in deprecated or deprecated in obsolete, so we print warning
2456 * and fix the schema by inheriting */
2457 if (!(node->flags & (LYS_STATUS_MASK))) {
2458 /* status not explicitely specified on the current node -> inherit */
Michal Vasko395b0a02018-01-22 09:36:20 +01002459 str = lys_path(node, LYS_PATH_FIRST_PREFIX);
Michal Vasko53b7da02018-02-13 15:28:42 +01002460 LOGWRN(ctx, "Missing status in %s subtree (%s), inheriting.",
PavolVican05c4f9b2017-09-07 13:33:54 +02002461 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2462 free(str);
2463 node->flags |= parent->flags & LYS_STATUS_MASK;
2464 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2465 /* invalid combination of statuses */
2466 switch (node->flags & LYS_STATUS_MASK) {
2467 case 0:
2468 case LYS_STATUS_CURR:
Michal Vasko53b7da02018-02-13 15:28:42 +01002469 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002470 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2471 break;
2472 case LYS_STATUS_DEPRC:
Michal Vasko53b7da02018-02-13 15:28:42 +01002473 LOGVAL(ctx, LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
PavolVican05c4f9b2017-09-07 13:33:54 +02002474 "obsolete", parent->name);
2475 break;
2476 }
2477 return EXIT_FAILURE;
2478 }
2479 }
2480
2481 return EXIT_SUCCESS;
2482}
2483
Pavol Vicanf4717e62016-03-16 11:30:01 +01002484int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002485store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002486{
Pavol Vicanec598812016-11-30 14:13:38 +01002487 switch (node->nodetype) {
2488 case LYS_CONTAINER:
2489 case LYS_LEAF:
2490 case LYS_LEAFLIST:
2491 case LYS_LIST:
2492 case LYS_CHOICE:
2493 case LYS_ANYDATA:
2494 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002495 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002496 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002497 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002498 if (!(node->flags & LYS_CONFIG_MASK)) {
2499 /* get config flag from parent */
2500 if (node->parent) {
2501 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2502 } else {
2503 /* default config is true */
2504 node->flags |= LYS_CONFIG_W;
2505 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002506 }
2507 }
Pavol Vicanec598812016-11-30 14:13:38 +01002508 break;
2509 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002510 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002511 if (!(node->flags & LYS_CONFIG_MASK)) {
2512 /* get config flag from parent */
2513 if (node->parent) {
2514 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2515 } else {
2516 /* default config is true */
2517 node->flags |= LYS_CONFIG_W;
2518 }
2519 }
2520 }
2521 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002522 default:
2523 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002524 }
Pavol Vicanec598812016-11-30 14:13:38 +01002525
Radek Krejci7212e0a2017-03-08 15:58:22 +01002526 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002527}
2528
2529int
Pavol Vican9d50a772016-10-14 22:23:36 +02002530yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2531 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002532{
Pavol Vican974377b2016-03-23 00:38:53 +01002533 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002534 YY_BUFFER_STATE bp;
2535 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002536 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002537 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002538 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002539
Pavol Vican8e7110b2016-03-22 17:00:26 +01002540 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002541 yylex_init(&scanner);
Michal Vasko53b7da02018-02-13 15:28:42 +01002542 yyset_extra(module->ctx, scanner);
Pavol Vican4fb66c92016-03-17 10:32:27 +01002543 bp = yy_scan_buffer((char *)data, size, scanner);
2544 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002545 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002546 param.module = module;
2547 param.submodule = submodule;
2548 param.unres = unres;
2549 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002550 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002551 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002552 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002553 trg = (submodule) ? (struct lys_module *)submodule : module;
2554 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2555 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2556 trg->inc_size = 0;
2557 trg->imp_size = 0;
2558 }
PavolVican22e88682017-02-14 22:38:18 +01002559 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2560 }
2561 yy_delete_buffer(bp, scanner);
2562 yylex_destroy(scanner);
2563 return ret;
2564}
2565
2566int
2567yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2568 char *ext_name, struct lys_ext_instance_complex *ext)
2569{
2570 unsigned int size;
2571 YY_BUFFER_STATE bp;
2572 yyscan_t scanner = NULL;
2573 int ret = 0;
2574 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002575 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002576
PavolVicandb0e8172017-02-20 00:46:09 +01002577 if (!data) {
2578 return EXIT_SUCCESS;
2579 }
PavolVican22e88682017-02-14 22:38:18 +01002580 size = strlen(data) + 2;
2581 yylex_init(&scanner);
2582 bp = yy_scan_buffer((char *)data, size, scanner);
2583 yy_switch_to_buffer(bp, scanner);
2584 memset(&param, 0, sizeof param);
2585 param.module = module;
2586 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002587 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002588 param.actual_node = (void **)ext;
2589 param.data_node = (void **)ext_name;
2590 param.flags |= EXT_INSTANCE_SUBSTMT;
2591 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002592 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002593 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002594 } else {
2595 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002596 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002597 ret = -1;
2598 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002599 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002600 yy_delete_buffer(bp, scanner);
2601 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002602 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002603}
2604
2605struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002606yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002607{
2608
PavolVican9e81c6a2017-02-09 13:09:07 +01002609 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002610 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002611 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002612 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002613
2614 unres = calloc(1, sizeof *unres);
Michal Vasko53b7da02018-02-13 15:28:42 +01002615 LY_CHECK_ERR_GOTO(!unres, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002616
2617 module = calloc(1, sizeof *module);
Michal Vasko53b7da02018-02-13 15:28:42 +01002618 LY_CHECK_ERR_GOTO(!module, LOGMEM(ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002619
2620 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002621 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002622 module->type = 0;
2623 module->implemented = (implement ? 1 : 0);
2624
Radek Krejci9e757e02017-03-08 17:18:09 +01002625 /* add into the list of processed modules */
2626 if (lyp_check_circmod_add(module)) {
2627 goto error;
2628 }
2629
PavolVican9e81c6a2017-02-09 13:09:07 +01002630 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2631 if (ret == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002632 if (ly_vecode(ctx) == LYVE_SUBMODULE) {
Radek Krejci95e00a42017-11-02 16:29:22 +01002633 free(module);
2634 module = NULL;
2635 } else {
2636 free_yang_common(module, node);
2637 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002638 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002639 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002640 assert(!unres->count);
2641 } else {
2642 if (yang_check_sub_module(module, unres, node)) {
2643 goto error;
2644 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002645
Michal Vasko7b460e52017-02-10 14:50:26 +01002646 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002647 goto error;
2648 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002649 }
2650
PavolVicanfe83b152017-02-19 03:19:29 +01002651 lyp_sort_revisions(module);
2652
Pavol Vican8e7110b2016-03-22 17:00:26 +01002653 if (revision) {
2654 /* check revision of the parsed model */
2655 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2656 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2657 module->name, module->rev[0].date, revision);
2658 goto error;
2659 }
2660 }
2661
PavolVican9e81c6a2017-02-09 13:09:07 +01002662 /* add into context if not already there */
2663 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002664 /* check correctness of includes */
2665 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002666 goto error;
2667 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002668
PavolVican6f000922017-02-10 12:56:59 +01002669 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002670 goto error;
2671 }
2672
PavolVican9e81c6a2017-02-09 13:09:07 +01002673 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002674 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002675 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002676
2677 if (module->deviation_size && !module->implemented) {
2678 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2679 /* deviations always causes target to be made implemented,
2680 * but augents and leafrefs not, so we have to apply them now */
2681 if (lys_set_implemented(module)) {
2682 goto error;
2683 }
2684 }
Michal Vasko10681e82018-01-16 14:54:16 +01002685
2686 /* remove our submodules from the parsed submodules list */
2687 lyp_del_includedup(module, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002688 } else {
2689 tmp_mod = module;
2690
2691 /* get the model from the context */
Radek Krejcidfb00d62017-09-06 09:39:35 +02002692 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002693 assert(module);
2694
2695 /* free what was parsed */
Michal Vasko10681e82018-01-16 14:54:16 +01002696 lys_free(tmp_mod, NULL, 0, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002697 }
2698
Michal Vasko44ab1462017-05-18 13:18:36 +02002699 unres_schema_free(NULL, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002700 lyp_check_circmod_pop(ctx);
Michal Vaskobe136f62017-09-21 12:08:39 +02002701 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2702 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002703 return module;
2704
2705error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002706 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002707 unres_schema_free(module, &unres, 1);
Radek Krejcif505cd12017-06-13 10:32:48 +02002708 if (!module) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002709 if (ly_vecode(ctx) != LYVE_SUBMODULE) {
2710 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002711 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002712 return NULL;
2713 }
2714
Radek Krejcif505cd12017-06-13 10:32:48 +02002715 if (module->name) {
Michal Vasko53b7da02018-02-13 15:28:42 +01002716 LOGERR(ctx, ly_errno, "Module \"%s\" parsing failed.", module->name);
Radek Krejcif505cd12017-06-13 10:32:48 +02002717 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01002718 LOGERR(ctx, ly_errno, "Module parsing failed.");
Radek Krejcif505cd12017-06-13 10:32:48 +02002719 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002720
Radek Krejci9e757e02017-03-08 17:18:09 +01002721 lyp_check_circmod_pop(ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002722 lys_sub_module_remove_devs_augs(module);
Michal Vasko10681e82018-01-16 14:54:16 +01002723 lyp_del_includedup(module, 1);
2724 lys_free(module, NULL, 0, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002725 return NULL;
2726}
2727
2728struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002729yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002730{
2731 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002732 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002733
2734 submodule = calloc(1, sizeof *submodule);
Michal Vasko53b7da02018-02-13 15:28:42 +01002735 LY_CHECK_ERR_GOTO(!submodule, LOGMEM(module->ctx), error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002736
2737 submodule->ctx = module->ctx;
2738 submodule->type = 1;
Radek Krejci29eac3d2017-06-01 16:50:02 +02002739 submodule->implemented = module->implemented;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002740 submodule->belongsto = module;
2741
Radek Krejci9e757e02017-03-08 17:18:09 +01002742 /* add into the list of processed modules */
2743 if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2744 goto error;
2745 }
2746
PavolVican9e81c6a2017-02-09 13:09:07 +01002747 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002748 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002749 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002750 goto error;
2751 }
2752
PavolVicanfe83b152017-02-19 03:19:29 +01002753 lyp_sort_revisions((struct lys_module *)submodule);
2754
Pavol Vican7313fc02016-11-14 01:10:31 +01002755 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002756 goto error;
2757 }
2758
Radek Krejci9e757e02017-03-08 17:18:09 +01002759 lyp_check_circmod_pop(module->ctx);
2760
Pavol Vican8e7110b2016-03-22 17:00:26 +01002761 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002762 return submodule;
2763
2764error:
2765 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002766 if (!submodule || !submodule->name) {
2767 free(submodule);
Michal Vasko53b7da02018-02-13 15:28:42 +01002768 LOGERR(module->ctx, ly_errno, "Submodule parsing failed.");
Pavol Vican8e7110b2016-03-22 17:00:26 +01002769 return NULL;
2770 }
2771
Michal Vasko53b7da02018-02-13 15:28:42 +01002772 LOGERR(module->ctx, ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002773
Michal Vaskoa9728122018-01-16 14:00:13 +01002774 unres_schema_free((struct lys_module *)submodule, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002775 lyp_check_circmod_pop(module->ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002776 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2777 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002778 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002779 return NULL;
2780}
Pavol Vican8760bb72016-04-07 09:44:01 +02002781
2782static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002783read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2784{
2785 int k = 0, j;
2786
2787 while (in_index < size) {
2788 if (input[in_index] == ' ') {
2789 k++;
2790 } else if (input[in_index] == '\t') {
2791 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2792 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002793 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2794 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2795 k += 8;
2796 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002797 } else {
2798 break;
2799 }
2800 ++in_index;
2801 if (k >= indent) {
2802 for (j = k - indent; j > 0; --j) {
2803 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002804 if (j > 1) {
2805 ++(*out_index);
2806 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002807 }
2808 break;
2809 }
2810 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002811 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002812}
2813
2814char *
Michal Vasko53b7da02018-02-13 15:28:42 +01002815yang_read_string(struct ly_ctx *ctx, const char *input, char *output, int size, int offset, int indent)
2816{
Pavol Vican3f598892016-09-28 15:41:07 +02002817 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002818
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002819 while (i < size) {
2820 switch (input[i]) {
2821 case '\n':
2822 out_index -= space;
2823 output[out_index] = '\n';
2824 space = 0;
2825 i = read_indent(input, indent, size, i + 1, &out_index, output);
2826 break;
2827 case ' ':
2828 case '\t':
2829 output[out_index] = input[i];
2830 ++space;
2831 break;
2832 case '\\':
2833 if (input[i + 1] == 'n') {
2834 out_index -= space;
2835 output[out_index] = '\n';
2836 space = 0;
2837 i = read_indent(input, indent, size, i + 2, &out_index, output);
2838 } else if (input[i + 1] == 't') {
2839 output[out_index] = '\t';
2840 ++i;
2841 ++space;
2842 } else if (input[i + 1] == '\\') {
2843 output[out_index] = '\\';
2844 ++i;
2845 } else if ((i + 1) != size && input[i + 1] == '"') {
2846 output[out_index] = '"';
2847 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002848 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002849 /* backslash must not be followed by any other character */
Michal Vaskoc8f80a62018-02-16 12:32:00 +01002850 LOGVAL(ctx, LYE_XML_INCHAR, LY_VLOG_NONE, NULL, input + i);
PavolVican1bc22062017-01-19 15:09:04 +01002851 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002852 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002853 break;
2854 default:
2855 output[out_index] = input[i];
2856 space = 0;
2857 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002858 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002859 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002860 ++out_index;
2861 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002862 output[out_index] = '\0';
2863 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002864 output = realloc(output, out_index + 1);
Michal Vasko53b7da02018-02-13 15:28:42 +01002865 LY_CHECK_ERR_RETURN(!output, LOGMEM(ctx), NULL);
Pavol Vican8760bb72016-04-07 09:44:01 +02002866 }
Pavol Vican3f598892016-09-28 15:41:07 +02002867 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002868}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002869
2870/* free function */
2871
PavolVicana0fdbf32017-02-15 17:59:02 +01002872void
2873yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002874{
2875 struct yang_type *stype = (struct yang_type *)type->der;
Radek Krejcidce5f972017-09-12 15:47:49 +02002876 unsigned int i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002877
2878 if (!stype) {
2879 return ;
2880 }
PavolVicane87cb932016-12-30 15:36:18 +01002881 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2882 lydict_remove(ctx, stype->name);
2883 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2884 for (i = 0; i < type->info.ident.count; ++i) {
2885 free(type->info.ident.ref[i]);
2886 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002887 }
PavolVicane87cb932016-12-30 15:36:18 +01002888 if (stype->base == LY_TYPE_UNION) {
2889 for (i = 0; i < type->info.uni.count; ++i) {
2890 yang_type_free(ctx, &type->info.uni.types[i]);
2891 }
2892 free(type->info.uni.types);
2893 type->base = LY_TYPE_DER;
2894 } else {
2895 type->base = stype->base;
2896 }
2897 free(stype);
2898 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002899 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02002900 lys_type_free(ctx, type, NULL);
Radek Krejci0ec2cc52017-11-09 16:30:12 +01002901 memset(type, 0, sizeof (struct lys_type));
Pavol Vican7313fc02016-11-14 01:10:31 +01002902}
2903
2904static void
Radek Krejcia2ac9262017-09-12 16:39:04 +02002905yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint16_t start, uint16_t size)
Pavol Vican7313fc02016-11-14 01:10:31 +01002906{
2907 uint8_t i;
2908
2909 assert(ctx);
2910 if (!tpdf) {
2911 return;
2912 }
2913
2914 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002915 lydict_remove(ctx, tpdf[i].name);
2916 lydict_remove(ctx, tpdf[i].dsc);
2917 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002918
Pavol Vicancee10802016-11-22 15:48:35 +01002919 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002920
Pavol Vicancee10802016-11-22 15:48:35 +01002921 lydict_remove(ctx, tpdf[i].units);
2922 lydict_remove(ctx, tpdf[i].dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002923 lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
Pavol Vican7313fc02016-11-14 01:10:31 +01002924 }
2925}
2926
Pavol Vican1cc4e192016-10-24 16:38:31 +02002927static void
2928yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2929{
2930 uint8_t i;
2931
2932 for (i = start; i < size; ++i){
2933 free((char *)imp[i].module);
2934 lydict_remove(ctx, imp[i].prefix);
2935 lydict_remove(ctx, imp[i].dsc);
2936 lydict_remove(ctx, imp[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002937 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002938 }
2939}
2940
Pavol Vicanec423c92016-10-24 21:33:43 +02002941static void
2942yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2943{
2944 uint8_t i;
2945
2946 for (i = start; i < size; ++i){
2947 free((char *)inc[i].submodule);
2948 lydict_remove(ctx, inc[i].dsc);
2949 lydict_remove(ctx, inc[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002950 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
Pavol Vicanec423c92016-10-24 21:33:43 +02002951 }
2952}
2953
Pavol Vican36e27272016-11-22 15:47:28 +01002954static void
2955yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2956{
2957 uint32_t i;
2958 uint8_t j;
2959
2960 /* free base name */
2961 for (i = start; i < size; ++i) {
2962 for (j = 0; j < ident[i].base_size; ++j) {
2963 free(ident[i].base[j]);
2964 }
2965 }
2966}
2967
Pavol Vican05810b62016-11-23 14:07:22 +01002968static void
2969yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2970{
2971 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2972 free(grp->tpdf);
2973}
2974
2975static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002976yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2977{
2978 uint8_t i;
2979
2980 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2981 free(cont->tpdf);
2982 lydict_remove(ctx, cont->presence);
2983
Pavol Vicanfda8c802016-12-03 02:00:42 +01002984 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002985 lys_restr_free(ctx, &cont->must[i], NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002986 }
2987 free(cont->must);
2988
Radek Krejci5138e9f2017-04-12 13:10:46 +02002989 lys_when_free(ctx, cont->when, NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002990}
2991
2992static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002993yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2994{
2995 uint8_t i;
2996
2997 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002998 lys_restr_free(ctx, &leaf->must[i], NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002999 }
3000 free(leaf->must);
3001
Radek Krejci5138e9f2017-04-12 13:10:46 +02003002 lys_when_free(ctx, leaf->when, NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01003003
3004 yang_type_free(ctx, &leaf->type);
3005 lydict_remove(ctx, leaf->units);
3006 lydict_remove(ctx, leaf->dflt);
3007}
3008
3009static void
Pavol Vican36aff862016-11-26 17:07:05 +01003010yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
3011{
3012 uint8_t i;
3013
3014 for (i = 0; i < leaflist->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003015 lys_restr_free(ctx, &leaflist->must[i], NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003016 }
3017 free(leaflist->must);
3018
3019 for (i = 0; i < leaflist->dflt_size; i++) {
3020 lydict_remove(ctx, leaflist->dflt[i]);
3021 }
3022 free(leaflist->dflt);
3023
Radek Krejci5138e9f2017-04-12 13:10:46 +02003024 lys_when_free(ctx, leaflist->when, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01003025
3026 yang_type_free(ctx, &leaflist->type);
3027 lydict_remove(ctx, leaflist->units);
3028}
3029
3030static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003031yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3032{
3033 uint8_t i;
3034
3035 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3036 free(list->tpdf);
3037
3038 for (i = 0; i < list->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003039 lys_restr_free(ctx, &list->must[i], NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003040 }
3041 free(list->must);
3042
Radek Krejci5138e9f2017-04-12 13:10:46 +02003043 lys_when_free(ctx, list->when, NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003044
3045 for (i = 0; i < list->unique_size; ++i) {
3046 free(list->unique[i].expr);
3047 }
3048 free(list->unique);
3049
3050 free(list->keys);
3051}
3052
3053static void
Pavol Vican36ace102016-11-28 11:46:59 +01003054yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3055{
3056 free(choice->dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003057 lys_when_free(ctx, choice->when, NULL);
Pavol Vican36ace102016-11-28 11:46:59 +01003058}
3059
3060static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003061yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3062{
3063 uint8_t i;
3064
3065 for (i = 0; i < anydata->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003066 lys_restr_free(ctx, &anydata->must[i], NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003067 }
3068 free(anydata->must);
3069
Radek Krejci5138e9f2017-04-12 13:10:46 +02003070 lys_when_free(ctx, anydata->when, NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003071}
3072
3073static void
Pavol Vican78729392016-11-28 17:18:22 +01003074yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3075{
3076 uint8_t i;
3077
3078 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3079 free(inout->tpdf);
3080
3081 for (i = 0; i < inout->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003082 lys_restr_free(ctx, &inout->must[i], NULL);
Pavol Vican78729392016-11-28 17:18:22 +01003083 }
3084 free(inout->must);
3085}
3086
3087static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003088yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3089{
3090 uint8_t i;
3091
3092 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3093 free(notif->tpdf);
3094
3095 for (i = 0; i < notif->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003096 lys_restr_free(ctx, &notif->must[i], NULL);
Pavol Vican29bf8802016-11-28 20:44:57 +01003097 }
3098 free(notif->must);
3099}
3100
3101static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003102yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3103{
3104 int i, j;
3105
3106 for (i = 0; i < uses->refine_size; i++) {
3107 lydict_remove(ctx, uses->refine[i].target_name);
3108 lydict_remove(ctx, uses->refine[i].dsc);
3109 lydict_remove(ctx, uses->refine[i].ref);
3110
3111 for (j = 0; j < uses->refine[i].must_size; j++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003112 lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003113 }
3114 free(uses->refine[i].must);
3115
3116 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3117 lydict_remove(ctx, uses->refine[i].dflt[j]);
3118 }
3119 free(uses->refine[i].dflt);
3120
3121 if (uses->refine[i].target_type & LYS_CONTAINER) {
3122 lydict_remove(ctx, uses->refine[i].mod.presence);
3123 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003124 lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003125 }
3126 free(uses->refine);
3127
Radek Krejci5138e9f2017-04-12 13:10:46 +02003128 lys_when_free(ctx, uses->when, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003129}
3130
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003131static void
Pavol Vican05810b62016-11-23 14:07:22 +01003132yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3133{
3134 struct lys_node *tmp, *child, *sibling;
3135
3136 if (!node) {
3137 return;
3138 }
3139 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003140
3141 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003142 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003143 sibling = tmp->next;
3144 /* common part */
3145 lydict_remove(ctx, tmp->name);
3146 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003147 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003148 lydict_remove(ctx, tmp->dsc);
3149 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003150 }
3151
3152 switch (tmp->nodetype) {
3153 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003154 case LYS_RPC:
3155 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003156 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3157 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003158 case LYS_CONTAINER:
3159 yang_free_container(ctx, (struct lys_node_container *)tmp);
3160 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003161 case LYS_LEAF:
3162 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3163 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003164 case LYS_LEAFLIST:
3165 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3166 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003167 case LYS_LIST:
3168 yang_free_list(ctx, (struct lys_node_list *)tmp);
3169 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003170 case LYS_CHOICE:
3171 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3172 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003173 case LYS_CASE:
Radek Krejci5138e9f2017-04-12 13:10:46 +02003174 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
Pavol Vicana420bac2016-11-28 14:51:54 +01003175 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003176 case LYS_ANYXML:
3177 case LYS_ANYDATA:
3178 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3179 break;
Pavol Vican78729392016-11-28 17:18:22 +01003180 case LYS_INPUT:
3181 case LYS_OUTPUT:
3182 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3183 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003184 case LYS_NOTIF:
3185 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3186 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003187 case LYS_USES:
3188 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3189 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003190 default:
3191 break;
3192 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003193 lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
Pavol Vican05810b62016-11-23 14:07:22 +01003194 yang_free_nodes(ctx, child);
3195 free(tmp);
3196 tmp = sibling;
3197 }
3198}
3199
Pavol Vican3ad50f82016-12-04 15:00:36 +01003200static void
3201yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3202{
3203 lydict_remove(ctx, aug->target_name);
3204 lydict_remove(ctx, aug->dsc);
3205 lydict_remove(ctx, aug->ref);
3206
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003207 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003208 lys_when_free(ctx, aug->when, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003209 yang_free_nodes(ctx, aug->child);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003210 lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003211}
3212
PavolVican75af21d2016-12-29 20:04:07 +01003213static void
3214yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3215{
3216 uint i, j;
3217
3218 for (i = index; i < dev->deviate_size; ++i) {
3219 lydict_remove(ctx, dev->deviate[i].units);
3220
3221 if (dev->deviate[i].type) {
3222 yang_type_free(ctx, dev->deviate[i].type);
3223 }
3224
3225 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3226 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3227 }
3228 free(dev->deviate[i].dflt);
3229
3230 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003231 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003232 }
3233 free(dev->deviate[i].must);
3234
3235 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3236 free(dev->deviate[i].unique[j].expr);
3237 }
3238 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003239 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003240 }
3241}
3242
PavolVicandb0e8172017-02-20 00:46:09 +01003243void
3244yang_free_ext_data(struct yang_ext_substmt *substmt)
3245{
3246 int i;
3247
3248 if (!substmt) {
3249 return;
3250 }
3251
3252 free(substmt->ext_substmt);
3253 if (substmt->ext_modules) {
3254 for (i = 0; substmt->ext_modules[i]; ++i) {
3255 free(substmt->ext_modules[i]);
3256 }
3257 free(substmt->ext_modules);
3258 }
3259 free(substmt);
3260}
3261
Pavol Vican7313fc02016-11-14 01:10:31 +01003262/* free common item from module and submodule */
3263static void
Pavol Vican05810b62016-11-23 14:07:22 +01003264free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003265{
PavolVican75af21d2016-12-29 20:04:07 +01003266 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003267 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3268 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003269 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003270 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003271 for (i = 0; i < module->augment_size; ++i) {
3272 yang_free_augment(module->ctx, &module->augment[i]);
3273 }
3274 module->augment_size = 0;
3275 for (i = 0; i < module->deviation_size; ++i) {
3276 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3277 free(module->deviation[i].deviate);
3278 }
3279 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003280}
3281
Pavol Vican1cc4e192016-10-24 16:38:31 +02003282/* check function*/
3283
3284int
PavolVicanc1807262017-01-31 18:00:27 +01003285yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3286 void *parent, struct unres_schema *unres)
3287{
3288 struct unres_ext *info;
3289 uint i;
3290
3291 for (i = 0; i < size; ++i) {
3292 info = malloc(sizeof *info);
Michal Vasko53b7da02018-02-13 15:28:42 +01003293 LY_CHECK_ERR_RETURN(!info, LOGMEM(module->ctx), EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003294 info->data.yang = (*ext)[i]->parent;
3295 info->datatype = LYS_IN_YANG;
3296 info->parent = parent;
3297 info->mod = module;
3298 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003299 info->substmt = (*ext)[i]->insubstmt;
3300 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003301 info->ext_index = i;
3302 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3303 return EXIT_FAILURE;
3304 }
3305 }
3306
3307 return EXIT_SUCCESS;
3308}
3309
3310int
Pavol Vicanec423c92016-10-24 21:33:43 +02003311yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003312{
3313 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003314 struct lys_include *inc;
3315 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003316 char *s;
3317
3318 imp = module->imp;
3319 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003320 inc = module->inc;
3321 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003322
3323 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003324 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003325 module->imp_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003326 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM(module->ctx), error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003327 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003328
Pavol Vicanec423c92016-10-24 21:33:43 +02003329 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003330 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003331 module->inc_size = 0;
Michal Vasko53b7da02018-02-13 15:28:42 +01003332 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM(module->ctx), error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003333 }
3334
3335 for (i = 0; i < imp_size; ++i) {
3336 s = (char *) imp[i].module;
3337 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003338 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003339 ++i;
3340 goto error;
3341 }
3342 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003343 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003344 s = (char *) inc[j].submodule;
3345 inc[j].submodule = NULL;
3346 if (yang_fill_include(module, s, &inc[j], unres)) {
3347 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003348 goto error;
3349 }
3350 }
3351 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003352 free(imp);
3353
3354 return EXIT_SUCCESS;
3355
3356error:
3357 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003358 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003359 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003360 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003361 return EXIT_FAILURE;
3362}
Pavol Vican7313fc02016-11-14 01:10:31 +01003363
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003364static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003365yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003366{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003367 struct lys_iffeature *iffeature;
3368 uint8_t *ptr_size, size, i;
3369 char *s;
3370 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003371
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003372 switch (type) {
3373 case FEATURE_KEYWORD:
3374 iffeature = ((struct lys_feature *)parent)->iffeature;
3375 size = ((struct lys_feature *)parent)->iffeature_size;
3376 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3377 parent_is_feature = 1;
3378 break;
3379 case IDENTITY_KEYWORD:
3380 iffeature = ((struct lys_ident *)parent)->iffeature;
3381 size = ((struct lys_ident *)parent)->iffeature_size;
3382 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3383 break;
3384 case ENUM_KEYWORD:
3385 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3386 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3387 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3388 break;
3389 case BIT_KEYWORD:
3390 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3391 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3392 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3393 break;
3394 case REFINE_KEYWORD:
3395 iffeature = ((struct lys_refine *)ptr)->iffeature;
3396 size = ((struct lys_refine *)ptr)->iffeature_size;
3397 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3398 break;
3399 default:
3400 iffeature = ((struct lys_node *)parent)->iffeature;
3401 size = ((struct lys_node *)parent)->iffeature_size;
3402 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3403 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003404 }
3405
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003406 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003407 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003408 s = (char *)iffeature[i].features;
3409 iffeature[i].features = NULL;
3410 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3411 *ptr_size = size;
3412 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003413 }
PavolVican8fa31242017-02-07 11:04:26 +01003414 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3415 *ptr_size = size;
3416 return EXIT_FAILURE;
3417 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003418 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003419 }
3420
3421 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003422}
3423
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003424static int
3425yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3426{
3427 uint size, i;
3428 int rc;
3429 struct lys_ident **ref;
3430 const char *value;
3431 char *expr;
3432
3433 ref = type->info.ident.ref;
3434 size = type->info.ident.count;
3435 type->info.ident.count = 0;
3436 type->info.ident.ref = NULL;
3437 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3438
3439 for (i = 0; i < size; ++i) {
3440 expr = (char *)ref[i];
3441 /* store in the JSON format */
3442 value = transform_schema2json(module, expr);
3443 free(expr);
3444
3445 if (!value) {
3446 goto error;
3447 }
3448 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3449 lydict_remove(module->ctx, value);
3450
3451 if (rc == -1) {
3452 goto error;
3453 }
3454 }
3455 free(ref);
3456
3457 return EXIT_SUCCESS;
3458error:
3459 for (i = i+1; i < size; ++i) {
3460 free(ref[i]);
3461 }
3462 free(ref);
3463 return EXIT_FAILURE;
3464}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003465
Pavol Vican7313fc02016-11-14 01:10:31 +01003466int
PavolVican056fcd12017-02-07 15:36:53 +01003467yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3468 void *parent, struct unres_schema *unres)
3469{
PavolVican92f23622017-12-12 13:35:56 +01003470 unsigned int i, j;
PavolVican056fcd12017-02-07 15:36:53 +01003471
3472 type->parent = parent;
3473 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3474 return EXIT_FAILURE;
3475 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003476 for (j = 0; j < type->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003477 if (type->ext[j]->flags & LYEXT_OPT_VALID) {
3478 type->parent->flags |= LYS_VALID_DATA;
3479 break;
3480 }
3481 }
3482
PavolVican056fcd12017-02-07 15:36:53 +01003483 switch (stype->base) {
3484 case LY_TYPE_ENUM:
3485 for (i = 0; i < type->info.enums.count; ++i) {
3486 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3487 return EXIT_FAILURE;
3488 }
3489 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3490 &type->info.enums.enm[i], unres)) {
3491 return EXIT_FAILURE;
3492 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003493 for (j = 0; j < type->info.enums.enm[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003494 if (type->info.enums.enm[i].ext[j]->flags & LYEXT_OPT_VALID) {
3495 type->parent->flags |= LYS_VALID_DATA;
3496 break;
3497 }
3498 }
PavolVican056fcd12017-02-07 15:36:53 +01003499 }
3500 break;
3501 case LY_TYPE_BITS:
3502 for (i = 0; i < type->info.bits.count; ++i) {
3503 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3504 return EXIT_FAILURE;
3505 }
3506 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3507 &type->info.bits.bit[i], unres)) {
3508 return EXIT_FAILURE;
3509 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003510 for (j = 0; j < type->info.bits.bit[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003511 if (type->info.bits.bit[i].ext[j]->flags & LYEXT_OPT_VALID) {
3512 type->parent->flags |= LYS_VALID_DATA;
3513 break;
3514 }
3515 }
PavolVican056fcd12017-02-07 15:36:53 +01003516 }
3517 break;
3518 case LY_TYPE_IDENT:
3519 if (yang_check_identityref(module, type, unres)) {
3520 return EXIT_FAILURE;
3521 }
3522 break;
3523 case LY_TYPE_STRING:
PavolVican92f23622017-12-12 13:35:56 +01003524 if (type->info.str.length) {
3525 if (yang_check_ext_instance(module, &type->info.str.length->ext,
3526 type->info.str.length->ext_size, type->info.str.length, unres)) {
3527 return EXIT_FAILURE;
3528 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003529 for (j = 0; j < type->info.str.length->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003530 if (type->info.str.length->ext[j]->flags & LYEXT_OPT_VALID) {
3531 type->parent->flags |= LYS_VALID_DATA;
3532 break;
3533 }
3534 }
PavolVican056fcd12017-02-07 15:36:53 +01003535 }
PavolVican92f23622017-12-12 13:35:56 +01003536
PavolVican056fcd12017-02-07 15:36:53 +01003537 for (i = 0; i < type->info.str.pat_count; ++i) {
3538 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3539 &type->info.str.patterns[i], unres)) {
3540 return EXIT_FAILURE;
3541 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003542 for (j = 0; j < type->info.str.patterns[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003543 if (type->info.str.patterns[i].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_DEC64:
PavolVican92f23622017-12-12 13:35:56 +01003551 if (type->info.dec64.range) {
3552 if (yang_check_ext_instance(module, &type->info.dec64.range->ext,
3553 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3554 return EXIT_FAILURE;
3555 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003556 for (j = 0; j < type->info.dec64.range->ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003557 if (type->info.dec64.range->ext[j]->flags & LYEXT_OPT_VALID) {
3558 type->parent->flags |= LYS_VALID_DATA;
3559 break;
3560 }
3561 }
PavolVican056fcd12017-02-07 15:36:53 +01003562 }
3563 break;
3564 case LY_TYPE_UNION:
3565 for (i = 0; i < type->info.uni.count; ++i) {
3566 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3567 parent, unres)) {
3568 return EXIT_FAILURE;
3569 }
3570 }
Radek Krejci57b41682017-03-07 12:33:24 +01003571 break;
PavolVican056fcd12017-02-07 15:36:53 +01003572 default:
3573 /* nothing checks */
3574 break;
3575 }
3576 return EXIT_SUCCESS;
3577}
3578
3579int
Pavol Vican7313fc02016-11-14 01:10:31 +01003580yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3581{
3582 struct lys_tpdf *tpdf;
Radek Krejcidaa547a2017-09-22 15:56:27 +02003583 uint8_t *ptr_tpdf_size = NULL;
PavolVican92f23622017-12-12 13:35:56 +01003584 uint16_t j, i, tpdf_size, *ptr_tpdf_size16 = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01003585
3586 if (!parent) {
3587 tpdf = module->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003588 //ptr_tpdf_size = &module->tpdf_size;
3589 ptr_tpdf_size16 = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003590 } else {
3591 switch (parent->nodetype) {
3592 case LYS_GROUPING:
3593 tpdf = ((struct lys_node_grp *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003594 ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003595 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003596 case LYS_CONTAINER:
3597 tpdf = ((struct lys_node_container *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003598 ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003599 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003600 case LYS_LIST:
3601 tpdf = ((struct lys_node_list *)parent)->tpdf;
3602 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3603 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003604 case LYS_RPC:
3605 case LYS_ACTION:
3606 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003607 ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003608 break;
Pavol Vican78729392016-11-28 17:18:22 +01003609 case LYS_INPUT:
3610 case LYS_OUTPUT:
3611 tpdf = ((struct lys_node_inout *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003612 ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
Pavol Vican78729392016-11-28 17:18:22 +01003613 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003614 case LYS_NOTIF:
3615 tpdf = ((struct lys_node_notif *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003616 ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
Pavol Vican29bf8802016-11-28 20:44:57 +01003617 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003618 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01003619 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01003620 return EXIT_FAILURE;
3621 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003622 }
3623
Radek Krejcia2ac9262017-09-12 16:39:04 +02003624 if (ptr_tpdf_size16) {
3625 tpdf_size = *ptr_tpdf_size16;
3626 *ptr_tpdf_size16 = 0;
3627 } else {
3628 tpdf_size = *ptr_tpdf_size;
3629 *ptr_tpdf_size = 0;
3630 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003631
3632 for (i = 0; i < tpdf_size; ++i) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003633 if (lyp_check_identifier(module->ctx, tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003634 goto error;
3635 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003636
PavolVican056fcd12017-02-07 15:36:53 +01003637 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3638 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003639 }
PavolVicandf9e7972017-02-07 11:41:38 +01003640 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3641 goto error;
3642 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01003643 for (j = 0; j < tpdf[i].ext_size; ++j) {
PavolVican92f23622017-12-12 13:35:56 +01003644 if (tpdf[i].ext[j]->flags & LYEXT_OPT_VALID) {
3645 tpdf[i].flags |= LYS_VALID_DATA;
3646 break;
3647 }
3648 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003649 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003650 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003651 }
3652
Radek Krejcia2ac9262017-09-12 16:39:04 +02003653 if (ptr_tpdf_size16) {
3654 (*ptr_tpdf_size16)++;
3655 } else {
3656 (*ptr_tpdf_size)++;
3657 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003658 /* check default value*/
Michal Vasko15a43372017-09-25 14:12:42 +02003659 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3660 && 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 +01003661 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003662 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003663 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003664 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003665
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003666 return EXIT_SUCCESS;
3667
3668error:
3669 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3670 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003671}
3672
3673static int
Pavol Vican36e27272016-11-22 15:47:28 +01003674yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3675{
3676 uint32_t i, size, base_size;
3677 uint8_t j;
3678
3679 size = module->ident_size;
3680 module->ident_size = 0;
3681 for (i = 0; i < size; ++i) {
3682 base_size = module->ident[i].base_size;
3683 module->ident[i].base_size = 0;
3684 for (j = 0; j < base_size; ++j) {
3685 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3686 ++j;
3687 module->ident_size = size;
3688 goto error;
3689 }
3690 }
3691 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003692 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3693 goto error;
3694 }
PavolVican8fa31242017-02-07 11:04:26 +01003695 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3696 goto error;
3697 }
Pavol Vican36e27272016-11-22 15:47:28 +01003698 }
3699
3700 return EXIT_SUCCESS;
3701
3702error:
3703 for (; j< module->ident[i].base_size; ++j) {
3704 free(module->ident[i].base[j]);
3705 }
3706 yang_free_ident_base(module->ident, i + 1, size);
3707 return EXIT_FAILURE;
3708}
3709
3710static int
PavolVican38104a32017-02-08 12:25:23 +01003711yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3712{
3713 uint i;
3714
3715 for (i = 0; i < size; ++i) {
3716 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3717 return EXIT_FAILURE;
3718 }
3719 }
3720 return EXIT_SUCCESS;
3721}
3722
3723static int
PavolVicane87cb932016-12-30 15:36:18 +01003724yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003725 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003726{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003727 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003728 goto error;
3729 }
3730
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003731 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003732 goto error;
3733 }
3734
Radek Krejci7212e0a2017-03-08 15:58:22 +01003735 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003736 *child = NULL;
3737 goto error;
3738 }
3739 *child = NULL;
3740
PavolVican59ba4602017-02-08 11:53:32 +01003741 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3742 goto error;
3743 }
PavolVican38104a32017-02-08 12:25:23 +01003744 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3745 goto error;
3746 }
3747
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003748 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003749 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003750 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003751 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003752 goto error;
3753 }
3754 } else {
3755 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3756 goto error;
3757 }
3758 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003759 }
3760
3761 return EXIT_SUCCESS;
3762error:
Michal Vasko53b7da02018-02-13 15:28:42 +01003763
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003764 return EXIT_FAILURE;
3765}
3766
3767static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003768yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003769{
PavolVican056fcd12017-02-07 15:36:53 +01003770 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003771 yang_type_free(module->ctx, &leaf->type);
3772 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003773 }
PavolVicana08d3652016-12-29 21:07:47 +01003774 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3775 yang_type_free(module->ctx, &leaf->type);
3776 goto error;
3777 }
3778
Pavol Vicanfda8c802016-12-03 02:00:42 +01003779 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003780 yang_type_free(module->ctx, &leaf->type);
3781 goto error;
3782 }
3783
Michal Vasko15a43372017-09-25 14:12:42 +02003784 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003785 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003786 goto error;
3787 }
3788
PavolVican59ba4602017-02-08 11:53:32 +01003789 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3790 goto error;
3791 }
PavolVican38104a32017-02-08 12:25:23 +01003792 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3793 goto error;
3794 }
Michal Vasko89afc112017-03-16 13:57:28 +01003795
Pavol Vicana69aff22016-11-24 18:23:50 +01003796 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003797 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003798 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003799 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003800 goto error;
3801 }
3802 } else {
3803 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3804 goto error;
3805 }
3806 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003807 }
3808
3809 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003810
Pavol Vicana69aff22016-11-24 18:23:50 +01003811error:
3812 return EXIT_FAILURE;
3813}
3814
3815static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003816yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3817 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003818{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003819 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003820
PavolVican056fcd12017-02-07 15:36:53 +01003821 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003822 yang_type_free(module->ctx, &leaflist->type);
3823 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003824 }
PavolVicana08d3652016-12-29 21:07:47 +01003825 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3826 yang_type_free(module->ctx, &leaflist->type);
3827 goto error;
3828 }
3829
Pavol Vicanfda8c802016-12-03 02:00:42 +01003830 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003831 yang_type_free(module->ctx, &leaflist->type);
3832 goto error;
3833 }
3834
Pavol Vican36aff862016-11-26 17:07:05 +01003835 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003836 /* check for duplicity in case of configuration data,
3837 * in case of status data duplicities are allowed */
3838 if (leaflist->flags & LYS_CONFIG_W) {
3839 for (j = i +1; j < leaflist->dflt_size; ++j) {
3840 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003841 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3842 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003843 goto error;
3844 }
3845 }
3846 }
3847 /* check default value (if not defined, there still could be some restrictions
3848 * that need to be checked against a default value from a derived type) */
Michal Vasko15a43372017-09-25 14:12:42 +02003849 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003850 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3851 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003852 goto error;
3853 }
3854 }
3855
PavolVican59ba4602017-02-08 11:53:32 +01003856 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3857 goto error;
3858 }
PavolVican38104a32017-02-08 12:25:23 +01003859 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3860 goto error;
3861 }
PavolVican59ba4602017-02-08 11:53:32 +01003862
Pavol Vican36aff862016-11-26 17:07:05 +01003863 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003864 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003865 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003866 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003867 goto error;
3868 }
3869 } else {
3870 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3871 goto error;
3872 }
3873 }
Pavol Vican36aff862016-11-26 17:07:05 +01003874 }
3875
3876 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003877
Pavol Vican36aff862016-11-26 17:07:05 +01003878error:
3879 return EXIT_FAILURE;
3880}
3881
3882static int
PavolVicane87cb932016-12-30 15:36:18 +01003883yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003884 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003885{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003886 struct lys_node *node;
3887
Pavol Vicand8136a42016-11-27 13:28:04 +01003888 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3889 goto error;
3890 }
3891
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003892 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3893 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003894 }
3895
Pavol Vicanfda8c802016-12-03 02:00:42 +01003896 if (list->flags & LYS_CONFIG_R) {
3897 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3898 * ignore oredering MASK - 0x7F
3899 */
3900 list->flags &= 0x7F;
3901 }
3902 /* check - if list is configuration, key statement is mandatory
3903 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003904 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 +01003905 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
Michal Vasko53b7da02018-02-13 15:28:42 +01003906 LOGVAL(module->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
Pavol Vicanfda8c802016-12-03 02:00:42 +01003907 goto error;
3908 }
3909
Radek Krejci7212e0a2017-03-08 15:58:22 +01003910 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003911 *child = NULL;
3912 goto error;
3913 }
3914 *child = NULL;
3915
Pavol Vicand8136a42016-11-27 13:28:04 +01003916 if (list->keys && yang_read_key(module, list, unres)) {
3917 goto error;
3918 }
3919
3920 if (yang_read_unique(module, list, unres)) {
3921 goto error;
3922 }
3923
PavolVican59ba4602017-02-08 11:53:32 +01003924 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3925 goto error;
3926 }
PavolVican38104a32017-02-08 12:25:23 +01003927 if (yang_check_must(module, list->must, list->must_size, unres)) {
3928 goto error;
3929 }
Michal Vasko89afc112017-03-16 13:57:28 +01003930
Pavol Vicand8136a42016-11-27 13:28:04 +01003931 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003932 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003933 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003934 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003935 goto error;
3936 }
3937 } else {
3938 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3939 goto error;
3940 }
3941 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003942 }
3943
3944 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003945
Pavol Vicand8136a42016-11-27 13:28:04 +01003946error:
3947 return EXIT_FAILURE;
3948}
3949
3950static int
PavolVicane87cb932016-12-30 15:36:18 +01003951yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003952 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003953{
3954 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003955
PavolVicana08d3652016-12-29 21:07:47 +01003956 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3957 free(choice->dflt);
3958 choice->dflt = NULL;
3959 goto error;
3960 }
3961
Radek Krejci7212e0a2017-03-08 15:58:22 +01003962 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003963 *child = NULL;
3964 free(choice->dflt);
3965 choice->dflt = NULL;
3966 goto error;
3967 }
3968 *child = NULL;
3969
Pavol Vican36ace102016-11-28 11:46:59 +01003970 if (choice->dflt) {
3971 value = (char *)choice->dflt;
3972 choice->dflt = NULL;
3973 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3974 free(value);
3975 goto error;
3976 }
3977 free(value);
3978 }
3979
PavolVican59ba4602017-02-08 11:53:32 +01003980 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3981 goto error;
3982 }
3983
Pavol Vican36ace102016-11-28 11:46:59 +01003984 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003985 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01003986 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003987 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003988 goto error;
3989 }
3990 } else {
3991 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3992 goto error;
3993 }
3994 }
Pavol Vican36ace102016-11-28 11:46:59 +01003995 }
3996
3997 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01003998
Pavol Vican36ace102016-11-28 11:46:59 +01003999error:
4000 return EXIT_FAILURE;
4001}
4002
4003static int
PavolVicane87cb932016-12-30 15:36:18 +01004004yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004005 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004006{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004007 struct lys_node *node;
4008
4009 if (rpc->nodetype == LYS_ACTION) {
4010 for (node = rpc->parent; node; node = lys_parent(node)) {
4011 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01004012 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004013 LOGVAL(module->ctx, LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004014 goto error;
4015 }
4016 }
4017 }
4018 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
4019 goto error;
4020 }
4021
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004022 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
4023 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004024 }
4025
Radek Krejci7212e0a2017-03-08 15:58:22 +01004026 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004027 *child = NULL;
4028 goto error;
4029 }
4030 *child = NULL;
4031
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004032 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004033
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004034error:
4035 return EXIT_FAILURE;
4036}
4037
4038static int
PavolVicane87cb932016-12-30 15:36:18 +01004039yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004040 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01004041{
Pavol Vican29bf8802016-11-28 20:44:57 +01004042 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
4043 goto error;
4044 }
4045
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004046 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
4047 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01004048 }
4049
Radek Krejci7212e0a2017-03-08 15:58:22 +01004050 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004051 *child = NULL;
4052 goto error;
4053 }
4054 *child = NULL;
4055
Michal Vasko89afc112017-03-16 13:57:28 +01004056 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
4057 goto error;
4058 }
4059
4060 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004061 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01004062 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004063 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004064 goto error;
4065 }
4066 } else {
4067 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
4068 goto error;
4069 }
PavolVican38104a32017-02-08 12:25:23 +01004070 }
Pavol Vican29bf8802016-11-28 20:44:57 +01004071 }
4072
4073 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004074
Pavol Vican29bf8802016-11-28 20:44:57 +01004075error:
4076 return EXIT_FAILURE;
4077}
4078
4079static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004080yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004081{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004082 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004083
Pavol Vican3ad50f82016-12-04 15:00:36 +01004084 child = augment->child;
4085 augment->child = NULL;
4086
PavolVicana08d3652016-12-29 21:07:47 +01004087 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4088 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004089 goto error;
4090 }
4091
Radek Krejci7212e0a2017-03-08 15:58:22 +01004092 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004093 goto error;
4094 }
4095
PavolVicanfa9510e2017-02-08 17:20:46 +01004096 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4097 goto error;
4098 }
4099
PavolVican59ba4602017-02-08 11:53:32 +01004100 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4101 goto error;
4102 }
4103
Pavol Vican3ad50f82016-12-04 15:00:36 +01004104 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004105 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004106 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004107 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004108 goto error;
4109 }
4110 } else {
4111 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4112 goto error;
4113 }
4114 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004115 }
4116
4117 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004118
Pavol Vican3ad50f82016-12-04 15:00:36 +01004119error:
4120 return EXIT_FAILURE;
4121}
4122
4123static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004124yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004125{
4126 uint i, size;
4127
4128 size = uses->augment_size;
4129 uses->augment_size = 0;
4130
4131 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004132 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004133 }
4134
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004135 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004136 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4137 goto error;
4138 }
4139 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4140 goto error;
4141 }
4142 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 +01004143 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004144 }
4145 }
4146
Pavol Vican3ad50f82016-12-04 15:00:36 +01004147 for (i = 0; i < size; ++i) {
4148 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004149 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004150 goto error;
4151 }
4152 }
4153
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004154 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4155 goto error;
4156 }
4157
PavolVican59ba4602017-02-08 11:53:32 +01004158 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4159 goto error;
4160 }
4161
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004162 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004163 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004164 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004165 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004166 goto error;
4167 }
4168 } else {
4169 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4170 goto error;
4171 }
4172 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004173 }
4174
4175 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004176
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004177error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004178 for (i = uses->augment_size; i < size; ++i) {
4179 yang_free_augment(module->ctx, &uses->augment[i]);
4180 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004181 return EXIT_FAILURE;
4182}
4183
4184static int
PavolVican59ba4602017-02-08 11:53:32 +01004185yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004186 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004187{
4188 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4189 goto error;
4190 }
4191
Radek Krejci7212e0a2017-03-08 15:58:22 +01004192 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004193 *child = NULL;
4194 goto error;
4195 }
4196 *child = NULL;
4197
4198 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4199 goto error;
4200 }
PavolVican38104a32017-02-08 12:25:23 +01004201 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4202 goto error;
4203 }
PavolVican59ba4602017-02-08 11:53:32 +01004204
4205 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004206 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004207 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004208 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004209 goto error;
4210 }
4211 } else {
4212 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4213 goto error;
4214 }
4215 }
PavolVican59ba4602017-02-08 11:53:32 +01004216 }
Michal Vasko89afc112017-03-16 13:57:28 +01004217
PavolVican59ba4602017-02-08 11:53:32 +01004218 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004219
PavolVican59ba4602017-02-08 11:53:32 +01004220error:
4221 return EXIT_FAILURE;
4222}
4223
4224static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004225yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004226 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004227{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004228 struct lys_node *node = nodes, *sibling, *child;
PavolVican92f23622017-12-12 13:35:56 +01004229 int i;
Pavol Vican05810b62016-11-23 14:07:22 +01004230
4231 while (node) {
4232 sibling = node->next;
4233 child = node->child;
4234 node->next = NULL;
4235 node->child = NULL;
PavolVicanbd1d1ae2017-07-20 00:06:00 +02004236 node->parent = NULL;
Pavol Vican05810b62016-11-23 14:07:22 +01004237 node->prev = node;
4238
PavolVican05c4f9b2017-09-07 13:33:54 +02004239 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node) ||
4240 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004241 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004242 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004243 goto error;
4244 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004245 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004246 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4247 goto error;
4248 }
Michal Vaskoe59ada92018-02-22 14:05:34 +01004249 for (i = 0; i < node->ext_size; ++i) {
PavolVican92f23622017-12-12 13:35:56 +01004250 if (node->ext[i]->flags & LYEXT_OPT_VALID) {
4251 node->flags |= LYS_VALID_DATA;
4252 break;
4253 }
4254 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004255
Pavol Vican05810b62016-11-23 14:07:22 +01004256 switch (node->nodetype) {
4257 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004258 if (yang_check_typedef(module, node, unres)) {
4259 goto error;
4260 }
4261 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004262 goto error;
4263 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004264 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004265 child = NULL;
4266 goto error;
4267 }
Pavol Vican05810b62016-11-23 14:07:22 +01004268 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004269 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004270 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004271 goto error;
4272 }
4273 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004274 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004275 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004276 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004277 goto error;
4278 }
4279 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004280 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004281 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004282 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004283 goto error;
4284 }
4285 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004286 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004287 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004288 goto error;
4289 }
4290 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004291 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004292 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004293 goto error;
4294 }
4295 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004296 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004297 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004298 goto error;
4299 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004300 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004301 child = NULL;
4302 goto error;
4303 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004304 if (((struct lys_node_case *)node)->when) {
4305 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4306 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4307 goto error;
4308 }
4309 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004310 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004311 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004312 goto error;
4313 }
4314 } else {
4315 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4316 goto error;
4317 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004318 }
4319 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004320 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004321 case LYS_ANYDATA:
4322 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004323 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004324 goto error;
4325 }
4326 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004327 case LYS_RPC:
4328 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004329 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004330 goto error;
4331 }
4332 break;
Pavol Vican78729392016-11-28 17:18:22 +01004333 case LYS_INPUT:
4334 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004335 if (yang_check_typedef(module, node, unres)) {
4336 goto error;
4337 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004338 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004339 child = NULL;
4340 goto error;
4341 }
PavolVican38104a32017-02-08 12:25:23 +01004342 if (((struct lys_node_inout *)node)->must_size) {
4343 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4344 goto error;
4345 }
4346 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004347 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004348 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004349 goto error;
4350 }
4351 } else {
4352 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4353 goto error;
4354 }
PavolVican38104a32017-02-08 12:25:23 +01004355 }
Pavol Vican78729392016-11-28 17:18:22 +01004356 }
Pavol Vican78729392016-11-28 17:18:22 +01004357 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004358 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004359 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004360 goto error;
4361 }
4362 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004363 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004364 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004365 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004366 goto error;
4367 }
4368 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004369 default:
Michal Vasko53b7da02018-02-13 15:28:42 +01004370 LOGINT(module->ctx);
Pavol Vican05810b62016-11-23 14:07:22 +01004371 goto error;
4372 }
Pavol Vican05810b62016-11-23 14:07:22 +01004373 node = sibling;
4374 }
4375
4376 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004377
Pavol Vican05810b62016-11-23 14:07:22 +01004378error:
4379 yang_free_nodes(module->ctx, sibling);
4380 yang_free_nodes(module->ctx, child);
4381 return EXIT_FAILURE;
4382}
4383
4384static int
PavolVican75af21d2016-12-29 20:04:07 +01004385yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4386 struct lys_node *dev_target, struct ly_set *dflt_check)
4387{
4388 struct lys_node_leaflist *llist;
4389 struct lys_type *type;
4390 struct lys_tpdf *tmp_parent;
4391 int i, j;
4392
PavolVican6f000922017-02-10 12:56:59 +01004393 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4394 goto error;
4395 }
PavolVican75af21d2016-12-29 20:04:07 +01004396 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4397 goto error;
4398 }
4399 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4400 goto error;
4401 }
4402 if (deviate->dflt_size) {
4403 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4404 goto error;
4405 }
4406 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4407 /* consolidate the final list in the target after removing items from it */
4408 llist = (struct lys_node_leaflist *)dev_target;
4409 for (i = j = 0; j < llist->dflt_size; j++) {
4410 llist->dflt[i] = llist->dflt[j];
4411 if (llist->dflt[i]) {
4412 i++;
4413 }
4414 }
4415 llist->dflt_size = i + 1;
4416 }
4417 }
4418
4419 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4420 goto error;
4421 }
4422
4423 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4424 goto error;
4425 }
4426
4427 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4428 goto error;
4429 }
4430
4431 if ((deviate->flags & LYS_CONFIG_MASK)) {
4432 /* add and replace are the same in this case */
4433 /* remove current config value of the target ... */
4434 dev_target->flags &= ~LYS_CONFIG_MASK;
4435
4436 /* ... and replace it with the value specified in deviation */
4437 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4438 }
4439
4440 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4441 goto error;
4442 }
4443
4444 if (deviate->type) {
4445 /* check target node type */
4446 if (dev_target->nodetype == LYS_LEAF) {
4447 type = &((struct lys_node_leaf *)dev_target)->type;
4448 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4449 type = &((struct lys_node_leaflist *)dev_target)->type;
4450 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01004451 LOGVAL(module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4452 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
PavolVican75af21d2016-12-29 20:04:07 +01004453 goto error;
4454 }
4455 /* remove type and initialize it */
4456 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004457 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004458 memcpy(type, deviate->type, sizeof *deviate->type);
4459 free(deviate->type);
4460 deviate->type = type;
4461 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004462 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4463 goto error;
4464 }
4465
PavolVican75af21d2016-12-29 20:04:07 +01004466 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4467 goto error;
4468 }
4469 }
4470
4471 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004472
PavolVican75af21d2016-12-29 20:04:07 +01004473error:
4474 if (deviate->type) {
4475 yang_type_free(module->ctx, deviate->type);
4476 deviate->type = NULL;
4477 }
4478 return EXIT_FAILURE;
4479}
4480
4481static int
4482yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4483{
4484 int rc;
4485 uint i;
4486 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004487 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004488 unsigned int u;
4489 const char *value, *target_name;
4490 struct lys_node_leaflist *llist;
4491 struct lys_node_leaf *leaf;
4492 struct unres_schema tmp_unres;
4493 struct lys_module *mod;
4494
4495 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004496 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4497 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004498 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004499 ly_set_free(set);
PavolVican75af21d2016-12-29 20:04:07 +01004500 goto error;
4501 }
Michal Vasko50576712017-07-28 12:28:33 +02004502 dev_target = set->set.s[0];
4503 ly_set_free(set);
4504
PavolVican75af21d2016-12-29 20:04:07 +01004505 if (dev_target->module == lys_main_module(module)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004506 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4507 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
PavolVican75af21d2016-12-29 20:04:07 +01004508 goto error;
4509 }
4510
4511 if (!dflt_check) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004512 LOGMEM(module->ctx);
PavolVican75af21d2016-12-29 20:04:07 +01004513 goto error;
4514 }
4515
4516 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4517 /* you cannot remove a key leaf */
4518 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4519 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4520 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004521 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4522 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
PavolVican4b80d042017-02-23 14:30:27 +01004523 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01004524 }
4525 }
4526 }
4527 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004528 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004529 lys_node_unlink(dev_target);
Michal Vaskoa1074a52018-01-03 12:18:53 +01004530 if (parent && (parent->nodetype & (LYS_AUGMENT | LYS_USES))) {
Radek Krejci9cf034c2017-08-24 17:10:35 +02004531 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4532 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4533 * path), so we need to remember the augment as an addition */
Michal Vaskoa1074a52018-01-03 12:18:53 +01004534 /* remember uses parent so we can reconnect to it */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004535 dev_target->parent = parent;
4536 }
PavolVican75af21d2016-12-29 20:04:07 +01004537 dev->orig_node = dev_target;
4538 } else {
4539 /* store a shallow copy of the original node */
4540 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004541 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004542 /* just to be safe */
4543 if (tmp_unres.count) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004544 LOGINT(module->ctx);
PavolVican75af21d2016-12-29 20:04:07 +01004545 goto error;
4546 }
4547 }
4548
PavolVican6f000922017-02-10 12:56:59 +01004549 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
4550 goto error;
4551 }
4552
Michal Vasko15a43372017-09-25 14:12:42 +02004553 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)) {
4554 for (i = 0; i < dev->deviate_size; ++i) {
4555 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4556 yang_free_deviate(module->ctx, dev, i + 1);
4557 dev->deviate_size = i+1;
4558 goto error; // missing free unresolve type in deviate
PavolVican75af21d2016-12-29 20:04:07 +01004559 }
4560 }
Michal Vasko15a43372017-09-25 14:12:42 +02004561 /* now check whether default value, if any, matches the type */
4562 for (u = 0; u < dflt_check->number; ++u) {
4563 value = NULL;
4564 rc = EXIT_SUCCESS;
4565 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4566 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4567 target_name = leaf->name;
4568 value = leaf->dflt;
4569 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4570 } else { /* LYS_LEAFLIST */
4571 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4572 target_name = llist->name;
4573 for (i = 0; i < llist->dflt_size; i++) {
4574 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4575 (struct lys_node *)(&llist->dflt[i]));
4576 if (rc == -1) {
4577 value = llist->dflt[i];
4578 break;
4579 }
4580 }
4581 }
4582 if (rc == -1) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004583 LOGVAL(module->ctx, LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4584 LOGVAL(module->ctx, LYE_SPEC, LY_VLOG_NONE, NULL,
Michal Vasko15a43372017-09-25 14:12:42 +02004585 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4586 target_name);
4587 goto error;
4588 }
PavolVican75af21d2016-12-29 20:04:07 +01004589 }
Michal Vasko15a43372017-09-25 14:12:42 +02004590 ly_set_free(dflt_check);
Michal Vasko6e2951d2017-12-13 11:15:00 +01004591 dflt_check = NULL;
PavolVican75af21d2016-12-29 20:04:07 +01004592 }
PavolVican75af21d2016-12-29 20:04:07 +01004593
Radek Krejci29eac3d2017-06-01 16:50:02 +02004594 /* mark all the affected modules as deviated and implemented */
4595 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004596 mod = lys_node_module(parent);
4597 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004598 mod->deviated = 1; /* main module */
4599 parent->module->deviated = 1; /* possible submodule */
4600 if (lys_set_implemented(mod)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004601 LOGERR(module->ctx, ly_errno, "Setting the deviated module \"%s\" implemented failed.", mod->name);
Radek Krejci29eac3d2017-06-01 16:50:02 +02004602 goto error;
4603 }
4604 }
PavolVican75af21d2016-12-29 20:04:07 +01004605 }
PavolVican75af21d2016-12-29 20:04:07 +01004606
4607 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004608
PavolVican75af21d2016-12-29 20:04:07 +01004609error:
4610 ly_set_free(dflt_check);
4611 return EXIT_FAILURE;
4612}
4613
4614static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004615yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4616{
PavolVican75af21d2016-12-29 20:04:07 +01004617 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004618
4619 aug_size = module->augment_size;
4620 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004621 dev_size = module->deviation_size;
4622 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004623
PavolVican6f87bf92017-02-15 19:38:55 +01004624 if (yang_check_typedef(module, NULL, unres)) {
4625 goto error;
4626 }
4627
PavolVicanc1807262017-01-31 18:00:27 +01004628 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4629 goto error;
4630 }
4631
PavolVican171717d2017-02-01 14:49:55 +01004632 /* check extension in revision */
4633 for (i = 0; i < module->rev_size; ++i) {
4634 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4635 goto error;
4636 }
4637 }
4638
PavolVican19dc6152017-02-06 12:04:15 +01004639 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004640 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004641 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4642 goto error;
4643 }
4644 }
4645
Pavol Vican7a7916f2016-11-21 23:38:30 +01004646 /* check features */
4647 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004648 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4649 goto error;
4650 }
PavolVican5393d3f2017-02-06 23:30:55 +01004651 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4652 goto error;
4653 }
4654
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004655 /* check for circular dependencies */
4656 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4657 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004658 }
4659 }
Pavol Vican36e27272016-11-22 15:47:28 +01004660 erase_identities = 0;
4661 if (yang_check_identities(module, unres)) {
4662 goto error;
4663 }
Pavol Vican05810b62016-11-23 14:07:22 +01004664 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004665 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004666 goto error;
4667 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004668
PavolVican75af21d2016-12-29 20:04:07 +01004669 /* check deviation */
4670 for (i = 0; i < dev_size; ++i) {
4671 module->deviation_size++;
4672 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4673 goto error;
4674 }
4675 }
4676
Pavol Vican3ad50f82016-12-04 15:00:36 +01004677 /* check augments */
4678 for (i = 0; i < aug_size; ++i) {
4679 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004680 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004681 goto error;
4682 }
4683 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4684 goto error;
4685 }
4686 }
4687
Pavol Vican7313fc02016-11-14 01:10:31 +01004688 return EXIT_SUCCESS;
Michal Vasko53b7da02018-02-13 15:28:42 +01004689
Pavol Vican7313fc02016-11-14 01:10:31 +01004690error:
Pavol Vican36e27272016-11-22 15:47:28 +01004691 if (erase_identities) {
4692 yang_free_ident_base(module->ident, 0, module->ident_size);
4693 }
Pavol Vican05810b62016-11-23 14:07:22 +01004694 if (erase_nodes) {
4695 yang_free_nodes(module->ctx, node);
4696 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004697 for (i = module->augment_size; i < aug_size; ++i) {
4698 yang_free_augment(module->ctx, &module->augment[i]);
4699 }
PavolVican75af21d2016-12-29 20:04:07 +01004700 for (i = module->deviation_size; i < dev_size; ++i) {
4701 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4702 free(module->deviation[i].deviate);
4703 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004704 return EXIT_FAILURE;
4705}
PavolVican22e88682017-02-14 22:38:18 +01004706
4707int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004708yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004709 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4710{
4711 int c;
4712 const char **str, ***p = NULL;
4713 void *reallocated;
4714 struct lyext_substmt *info;
4715
4716 c = 0;
4717 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004718 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004719 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4720 if (info->cardinality < LY_STMT_CARD_SOME) {
4721 str++;
4722 } else {
4723 /* get the index in the array to add new item */
4724 p = (const char ***)str;
4725 for (c = 0; p[0][c + 1]; c++);
4726 str = p[1];
4727 }
4728 str[c] = lydict_insert_zc(module->ctx, value);
4729 } else {
4730 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4731 if (!str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004732 LOGVAL(module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004733 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004734 }
4735 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004736 LOGVAL(module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004737 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004738 }
4739
4740 if (info->cardinality >= LY_STMT_CARD_SOME) {
4741 /* there can be multiple instances, str is actually const char *** */
4742 p = (const char ***)str;
4743 if (!p[0]) {
4744 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004745 p[0] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004746 LY_CHECK_ERR_GOTO(!p[0], LOGMEM(module->ctx), error);
PavolVican22e88682017-02-14 22:38:18 +01004747 if (stmt == LY_STMT_BELONGSTO) {
4748 /* allocate another array for the belongs-to's prefixes */
4749 p[1] = calloc(2, sizeof(const char *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004750 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004751 } else if (stmt == LY_STMT_ARGUMENT) {
4752 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004753 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Michal Vasko53b7da02018-02-13 15:28:42 +01004754 LY_CHECK_ERR_GOTO(!p[1], LOGMEM(module->ctx), error);
PavolVican50809742017-02-18 21:22:54 +01004755 /* default value of yin element */
4756 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004757 }
4758 } else {
4759 /* get the index in the array to add new item */
4760 for (c = 0; p[0][c]; c++);
4761 }
4762 str = p[0];
4763 }
4764
4765 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004766 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004767
PavolVican50809742017-02-18 21:22:54 +01004768 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004769 /* enlarge the array(s) */
4770 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4771 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004772 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004773 lydict_remove(module->ctx, p[0][c]);
4774 p[0][c] = NULL;
4775 return EXIT_FAILURE;
4776 }
4777 p[0] = reallocated;
4778 p[0][c + 1] = NULL;
4779
4780 if (stmt == LY_STMT_BELONGSTO) {
4781 /* enlarge the second belongs-to's array with prefixes */
4782 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4783 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004784 LOGMEM(module->ctx);
PavolVican22e88682017-02-14 22:38:18 +01004785 lydict_remove(module->ctx, p[1][c]);
4786 p[1][c] = NULL;
4787 return EXIT_FAILURE;
4788 }
4789 p[1] = reallocated;
4790 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004791 } else if (stmt == LY_STMT_ARGUMENT) {
4792 /* enlarge the second argument's array with yin element */
4793 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4794 if (!reallocated) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004795 LOGMEM(module->ctx);
PavolVican50809742017-02-18 21:22:54 +01004796 ((uint8_t *)p[1])[c] = 0;
4797 return EXIT_FAILURE;
4798 }
4799 p[1] = reallocated;
4800 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004801 }
4802 }
4803 }
4804
4805 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004806
4807error:
4808 free(value);
4809 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004810}
PavolVican5334c892017-02-15 16:29:09 +01004811
4812static int
4813yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4814{
4815 int c = 0, decrement = 0;
4816 const char **str, ***p = NULL;
4817 struct lyext_substmt *info;
4818
4819
4820 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4821 stmt = LY_STMT_BELONGSTO;
4822 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004823 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4824 stmt = LY_STMT_ARGUMENT;
4825 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004826 }
4827
4828 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4829 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4830 return 0;
4831 } else {
4832 p = (const char ***)str;
4833 /* get the index in the array */
4834 for (c = 0; p[0][c]; c++);
4835 return c + decrement;
4836 }
4837}
PavolVicana0fdbf32017-02-15 17:59:02 +01004838
4839void **
PavolVicanfe83b152017-02-19 03:19:29 +01004840yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4841 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004842{
Michal Vasko53b7da02018-02-13 15:28:42 +01004843 struct ly_ctx *ctx = ext->module->ctx;
PavolVicana0fdbf32017-02-15 17:59:02 +01004844 int c;
4845 void **data, ***p = NULL;
4846 void *reallocated;
4847 struct lyext_substmt *info;
4848
4849 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4850 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004851 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004852 return NULL;
4853 }
4854 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004855 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicana0fdbf32017-02-15 17:59:02 +01004856 return NULL;
4857 }
4858
4859 c = 0;
4860 if (info->cardinality >= LY_STMT_CARD_SOME) {
4861 /* there can be multiple instances, so instead of pointer to array,
4862 * we have in data pointer to pointer to array */
4863 p = (void ***)data;
4864 data = *p;
4865 if (!data) {
4866 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004867 *p = data = calloc(2, sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004868 LY_CHECK_ERR_RETURN(!data, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004869 } else {
4870 for (c = 0; *data; data++, c++);
4871 }
4872 }
4873
PavolVicaneef1d912017-02-19 00:19:15 +01004874 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004875 /* enlarge the array */
4876 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Michal Vasko53b7da02018-02-13 15:28:42 +01004877 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004878 *p = reallocated;
4879 data = *p;
4880 data[c + 1] = NULL;
4881 }
4882
PavolVicanfe83b152017-02-19 03:19:29 +01004883 if (index) {
4884 *index = c;
4885 return data;
4886 } else {
4887 return &data[c];
4888 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004889}
PavolVicanff0f7f42017-02-16 11:35:42 +01004890
4891int
4892yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4893 LY_STMT stmt, uint16_t value, uint16_t mask)
4894{
4895 uint16_t *data;
4896 struct lyext_substmt *info;
4897
4898 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4899 if (!data) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004900 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004901 return EXIT_FAILURE;
4902 }
4903 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004904 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanff0f7f42017-02-16 11:35:42 +01004905 return EXIT_FAILURE;
4906 }
4907
4908 *data |= value;
4909 return EXIT_SUCCESS;
4910}
PavolVican8e8dfd12017-02-16 13:51:41 +01004911
4912int
PavolVican6a852a62017-02-16 15:36:01 +01004913yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4914 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004915{
Michal Vasko53b7da02018-02-13 15:28:42 +01004916 struct ly_ctx *ctx = ext->module->ctx;
PavolVican6a852a62017-02-16 15:36:01 +01004917 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004918 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004919 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004920
4921 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4922 if (!val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004923 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican8e8dfd12017-02-16 13:51:41 +01004924 return EXIT_FAILURE;
4925 }
PavolVican6a852a62017-02-16 15:36:01 +01004926 if (stmt == LY_STMT_DIGITS) {
4927 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004928 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01004929 return EXIT_FAILURE;
4930 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004931
PavolVican6a852a62017-02-16 15:36:01 +01004932 if (info->cardinality >= LY_STMT_CARD_SOME) {
4933 /* there can be multiple instances */
4934 pp = (uint8_t**)val;
4935 if (!(*pp)) {
4936 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Michal Vasko53b7da02018-02-13 15:28:42 +01004937 LY_CHECK_ERR_RETURN(!*pp, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004938 } else {
4939 for (i = 0; (*pp)[i]; i++);
4940 }
4941 val = &(*pp)[i];
4942 }
4943
4944 /* stored value */
4945 *val = value;
4946
4947 if (i) {
4948 /* enlarge the array */
4949 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Michal Vasko53b7da02018-02-13 15:28:42 +01004950 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004951 *pp = reallocated;
4952 (*pp)[i + 1] = 0;
4953 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004954 } else {
PavolVican6a852a62017-02-16 15:36:01 +01004955 if (*val) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004956 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVican6a852a62017-02-16 15:36:01 +01004957 return EXIT_FAILURE;
4958 }
4959
4960 if (stmt == LY_STMT_REQINSTANCE) {
4961 *val = (value == 1) ? 1 : 2;
4962 } else if (stmt == LY_STMT_MODIFIER) {
4963 *val = 1;
4964 } else {
Michal Vasko53b7da02018-02-13 15:28:42 +01004965 LOGINT(ctx);
PavolVican6a852a62017-02-16 15:36:01 +01004966 return EXIT_FAILURE;
4967 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004968 }
4969
4970 return EXIT_SUCCESS;
4971}
PavolVican3f47b292017-02-16 20:38:16 +01004972
PavolVicanf3091bf2017-02-19 18:27:01 +01004973int
4974yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4975 struct lys_node *node, LY_STMT stmt)
4976{
4977 struct lyext_substmt *info;
4978 struct lys_node **snode, *siter;
4979
4980 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
4981 if (!snode) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004982 LOGVAL(ext->module->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01004983 return EXIT_FAILURE;
4984 }
4985 if (info->cardinality < LY_STMT_CARD_SOME) {
4986 LY_TREE_FOR(node, siter) {
4987 if (stmt == lys_snode2stmt(siter->nodetype)) {
Michal Vasko53b7da02018-02-13 15:28:42 +01004988 LOGVAL(ext->module->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
PavolVicanf3091bf2017-02-19 18:27:01 +01004989 return EXIT_FAILURE;
4990 }
4991 }
4992 }
4993
4994 return EXIT_SUCCESS;
4995}
PavolVicandb0e8172017-02-20 00:46:09 +01004996
4997int
4998yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
4999 char *parent_name, char **values, int implemented)
5000{
5001 int c, i;
5002 struct lys_module **modules, ***p, *reallocated, **pp;
5003 struct lyext_substmt *info;
5004
5005 if (!values) {
5006 return EXIT_SUCCESS;
5007 }
5008 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
5009 if (!modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005010 LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005011 return EXIT_FAILURE;
5012 }
5013
5014 for (i = 0; values[i]; ++i) {
5015 c = 0;
5016 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
Michal Vasko53b7da02018-02-13 15:28:42 +01005017 LOGVAL(ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
PavolVicandb0e8172017-02-20 00:46:09 +01005018 return EXIT_FAILURE;
5019 }
5020 if (info->cardinality >= LY_STMT_CARD_SOME) {
5021 /* there can be multiple instances, so instead of pointer to array,
5022 * we have in modules pointer to pointer to array */
5023 p = (struct lys_module ***)pp;
5024 modules = *p;
5025 if (!modules) {
5026 /* allocate initial array */
5027 *p = modules = calloc(2, sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005028 LY_CHECK_ERR_RETURN(!*p, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005029 } else {
5030 for (c = 0; *modules; modules++, c++);
5031 }
5032 }
5033
5034 if (c) {
5035 /* enlarge the array */
5036 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Michal Vasko53b7da02018-02-13 15:28:42 +01005037 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM(ctx), EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01005038 *p = (struct lys_module **)reallocated;
5039 modules = *p;
5040 modules[c + 1] = NULL;
5041 }
5042
5043 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
5044 if (!modules[c]) {
5045 return EXIT_FAILURE;
5046 }
5047 }
5048
5049 return EXIT_SUCCESS;
5050}