blob: b8a05f118c504d05727c75192789e04feb13042c [file] [log] [blame]
Pavol Vican021488a2016-01-25 23:56:12 +01001/**
2 * @file parser_yang.c
3 * @author Pavol Vican
4 * @brief YANG parser for libyang
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Pavol Vican9a3a7212016-03-23 10:04:00 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
Pavol Vican021488a2016-01-25 23:56:12 +010013 */
14
Pavol Vican5de33492016-02-22 14:03:24 +010015#include <ctype.h>
Pavol Vican7313fc02016-11-14 01:10:31 +010016#include <assert.h>
Pavol Vican021488a2016-01-25 23:56:12 +010017#include "parser_yang.h"
Pavol Vican8e7110b2016-03-22 17:00:26 +010018#include "parser_yang_lex.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010019#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010020#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010021
Pavol Vican082afd02016-10-25 12:39:15 +020022static void yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size);
PavolVican6f000922017-02-10 12:56:59 +010023static int yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres);
Pavol Vican082afd02016-10-25 12:39:15 +020024static void yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size);
Pavol Vican7313fc02016-11-14 01:10:31 +010025static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
Pavol Vican05810b62016-11-23 14:07:22 +010026static void free_yang_common(struct lys_module *module, struct lys_node *node);
Pavol Vican3ad50f82016-12-04 15:00:36 +010027static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +010028 int options, struct unres_schema *unres);
PavolVican5334c892017-02-15 16:29:09 +010029static int yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword);
PavolVicanf3091bf2017-02-19 18:27:01 +010030static void yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node);
Frank Rimplerc4db1c72017-09-12 12:56:39 +000031void lys_iffeature_free(struct ly_ctx *ctx, struct lys_iffeature *iffeature, uint8_t iffeature_size, int shallow,
Radek Krejci5138e9f2017-04-12 13:10:46 +020032 void (*private_destructor)(const struct lys_node *node, void *priv));
Pavol Vican082afd02016-10-25 12:39:15 +020033
Michal Vaskofe7e5a72016-05-02 14:49:23 +020034static int
PavolVican196694c2017-01-27 10:33:09 +010035yang_check_string(struct lys_module *module, const char **target, char *what,
36 char *where, char *value, struct lys_node *node)
Pavol Vican2a064652016-02-02 22:54:34 +010037{
Pavol Vicanbf805472016-01-26 14:24:56 +010038 if (*target) {
PavolVican196694c2017-01-27 10:33:09 +010039 LOGVAL(LYE_TOOMANY, (node) ? LY_VLOG_LYS : LY_VLOG_NONE, node, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010040 free(value);
41 return 1;
42 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010043 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010044 return 0;
45 }
46}
47
Michal Vaskofe7e5a72016-05-02 14:49:23 +020048int
Pavol Vican5f0316a2016-04-05 21:21:11 +020049yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010050{
Pavol Vican6eb14e82016-02-03 12:27:13 +010051 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010052
53 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010054 case MODULE_KEYWORD:
55 module->name = lydict_insert_zc(module->ctx, value);
56 break;
57 case NAMESPACE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010058 ret = yang_check_string(module, &module->ns, "namespace", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +010059 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010060 case ORGANIZATION_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010061 ret = yang_check_string(module, &module->org, "organization", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010062 break;
63 case CONTACT_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +010064 ret = yang_check_string(module, &module->contact, "contact", "module", value, NULL);
Pavol Vican1ca072c2016-02-03 13:03:56 +010065 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020066 default:
67 free(value);
68 LOGINT;
69 ret = EXIT_FAILURE;
70 break;
Pavol Vican2a064652016-02-02 22:54:34 +010071 }
72
Pavol Vican021488a2016-01-25 23:56:12 +010073 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010074}
75
Michal Vaskofe7e5a72016-05-02 14:49:23 +020076int
Pavol Vicand0b64c12016-07-15 09:56:19 +020077yang_check_version(struct lys_module *module, struct lys_submodule *submodule, char *value, int repeat)
78{
79 int ret = EXIT_SUCCESS;
80
81 if (repeat) {
Michal Vasko3767fb22016-07-21 12:10:57 +020082 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "yang version", "module");
83 ret = EXIT_FAILURE;
Pavol Vicand0b64c12016-07-15 09:56:19 +020084 } else {
85 if (!strcmp(value, "1")) {
86 if (submodule) {
87 if (module->version > 1) {
88 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
89 ret = EXIT_FAILURE;
90 }
Radek Krejci29eac3d2017-06-01 16:50:02 +020091 submodule->version = 1;
Pavol Vicand0b64c12016-07-15 09:56:19 +020092 } else {
93 module->version = 1;
94 }
95 } else if (!strcmp(value, "1.1")) {
96 if (submodule) {
97 if (module->version != 2) {
98 LOGVAL(LYE_INVER, LY_VLOG_NONE, NULL);
99 ret = EXIT_FAILURE;
100 }
Radek Krejci29eac3d2017-06-01 16:50:02 +0200101 submodule->version = 2;
Pavol Vicand0b64c12016-07-15 09:56:19 +0200102 } else {
103 module->version = 2;
104 }
105 } else {
106 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "yang-version");
107 ret = EXIT_FAILURE;
Michal Vasko3767fb22016-07-21 12:10:57 +0200108 }
Pavol Vicand0b64c12016-07-15 09:56:19 +0200109 }
110 free(value);
111 return ret;
112}
113
114int
Pavol Vicane024ab72016-07-27 14:27:43 +0200115yang_read_prefix(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +0100116{
Pavol Vican6eb14e82016-02-03 12:27:13 +0100117 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +0100118
Pavol Vican1cc4e192016-10-24 16:38:31 +0200119 if (!imp && lyp_check_identifier(value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +0100120 free(value);
121 return EXIT_FAILURE;
122 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200123
124 if (imp) {
PavolVican196694c2017-01-27 10:33:09 +0100125 ret = yang_check_string(module, &imp->prefix, "prefix", "import", value, NULL);
Pavol Vicane024ab72016-07-27 14:27:43 +0200126 } else {
PavolVican196694c2017-01-27 10:33:09 +0100127 ret = yang_check_string(module, &module->prefix, "prefix", "module", value, NULL);
Pavol Vican2a064652016-02-02 22:54:34 +0100128 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100129
Pavol Vicanbf805472016-01-26 14:24:56 +0100130 return ret;
131}
Pavol Vican6eb14e82016-02-03 12:27:13 +0100132
Pavol Vican1cc4e192016-10-24 16:38:31 +0200133static int
PavolVican7d0b5ab2017-02-01 13:06:53 +0100134yang_fill_import(struct lys_module *module, struct lys_import *imp_old, struct lys_import *imp_new,
135 char *value, struct unres_schema *unres)
Pavol Vican6eb14e82016-02-03 12:27:13 +0100136{
Pavol Vican0da132e2016-03-21 12:03:03 +0100137 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +0200138 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100139
Pavol Vican1cc4e192016-10-24 16:38:31 +0200140 if (!imp_old->prefix) {
Pavol Vicane024ab72016-07-27 14:27:43 +0200141 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "import");
Pavol Vican1cc4e192016-10-24 16:38:31 +0200142 goto error;
143 } else {
144 if (lyp_check_identifier(imp_old->prefix, LY_IDENT_PREFIX, module, NULL)) {
145 goto error;
146 }
Pavol Vicane024ab72016-07-27 14:27:43 +0200147 }
Pavol Vican1cc4e192016-10-24 16:38:31 +0200148 memcpy(imp_new, imp_old, sizeof *imp_old);
Pavol Vican0da132e2016-03-21 12:03:03 +0100149 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200150 rc = lyp_check_import(module, exp, imp_new);
Pavol Vican0da132e2016-03-21 12:03:03 +0100151 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +0200152 module->imp_size++;
PavolVican7d0b5ab2017-02-01 13:06:53 +0100153 if (rc || yang_check_ext_instance(module, &imp_new->ext, imp_new->ext_size, imp_new, unres)) {
Radek Krejci4dcd3392016-06-22 10:28:40 +0200154 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100155 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100156
Pavol Vican6eb14e82016-02-03 12:27:13 +0100157 return EXIT_SUCCESS;
Pavol Vican1cc4e192016-10-24 16:38:31 +0200158
159error:
160 free(value);
161 lydict_remove(module->ctx, imp_old->dsc);
162 lydict_remove(module->ctx, imp_old->ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +0200163 lys_extension_instances_free(module->ctx, imp_old->ext, imp_old->ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +0200164 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100165}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100166
167int
PavolVican196694c2017-01-27 10:33:09 +0100168yang_read_description(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100169{
170 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100171 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100172
PavolVican196694c2017-01-27 10:33:09 +0100173 switch (type) {
174 case MODULE_KEYWORD:
175 ret = yang_check_string(module, &module->dsc, dsc, "module", value, NULL);
176 break;
177 case REVISION_KEYWORD:
178 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value, NULL);
179 break;
180 case IMPORT_KEYWORD:
181 ret = yang_check_string(module, &((struct lys_import *)node)->dsc, dsc, where, value, NULL);
182 break;
183 case INCLUDE_KEYWORD:
184 ret = yang_check_string(module, &((struct lys_include *)node)->dsc, dsc, where, value, NULL);
185 break;
186 case NODE_PRINT:
187 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, node);
188 break;
189 default:
190 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value, NULL);
191 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100192 }
193 return ret;
194}
195
196int
PavolVican196694c2017-01-27 10:33:09 +0100197yang_read_reference(struct lys_module *module, void *node, char *value, char *where, enum yytokentype type)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100198{
199 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100200 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100201
PavolVican196694c2017-01-27 10:33:09 +0100202 switch (type) {
203 case MODULE_KEYWORD:
204 ret = yang_check_string(module, &module->ref, ref, "module", value, NULL);
205 break;
206 case REVISION_KEYWORD:
207 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value, NULL);
208 break;
209 case IMPORT_KEYWORD:
210 ret = yang_check_string(module, &((struct lys_import *)node)->ref, ref, where, value, NULL);
211 break;
212 case INCLUDE_KEYWORD:
213 ret = yang_check_string(module, &((struct lys_include *)node)->ref, ref, where, value, NULL);
214 break;
215 case NODE_PRINT:
216 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, node);
217 break;
218 default:
219 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value, NULL);
220 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +0100221 }
222 return ret;
223}
Pavol Vicanbedff692016-02-03 14:29:17 +0100224
Pavol Vican1eeb1992016-02-09 11:10:45 +0100225int
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100226yang_fill_iffeature(struct lys_module *module, struct lys_iffeature *iffeature, void *parent,
227 char *value, struct unres_schema *unres, int parent_is_feature)
Pavol Vicane1354e92016-02-09 14:02:09 +0100228{
229 const char *exp;
230 int ret;
231
Michal Vasko97b32be2016-07-25 10:59:53 +0200232 if ((module->version != 2) && ((value[0] == '(') || strchr(value, ' '))) {
233 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "if-feature");
234 free(value);
235 return EXIT_FAILURE;
236 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100237
Michal Vasko56d082c2016-10-25 14:00:42 +0200238 if (!(exp = transform_iffeat_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100239 free(value);
240 return EXIT_FAILURE;
241 }
242 free(value);
243
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100244 ret = resolve_iffeature_compile(iffeature, exp, (struct lys_node *)parent, parent_is_feature, unres);
Pavol Vicane1354e92016-02-09 14:02:09 +0100245 lydict_remove(module->ctx, exp);
Pavol Vicane1354e92016-02-09 14:02:09 +0100246
Pavol Vicandf9a95c2016-12-02 23:34:51 +0100247 return (ret) ? EXIT_FAILURE : EXIT_SUCCESS;
Pavol Vicane1354e92016-02-09 14:02:09 +0100248}
249
Pavol Vican4fb66c92016-03-17 10:32:27 +0100250int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100251yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100252{
253 const char *exp;
254
Pavol Vican0adf01d2016-03-22 12:29:33 +0100255 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100256 free(value);
257 if (!exp) {
258 return EXIT_FAILURE;
259 }
Pavol Vican4ffd0ab2016-08-27 16:35:04 +0200260
Pavol Vican0adf01d2016-03-22 12:29:33 +0100261 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100262 lydict_remove(module->ctx, exp);
263 return EXIT_FAILURE;
264 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100265
Pavol Vicanbbdef532016-02-09 14:52:12 +0100266 lydict_remove(module->ctx, exp);
267 return EXIT_SUCCESS;
268}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100269
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100270int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100271yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100272{
273 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100274
Pavol Vicandde090a2016-08-30 15:12:14 +0200275 if (message == ERROR_APP_TAG_KEYWORD) {
PavolVican196694c2017-01-27 10:33:09 +0100276 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100277 } else {
PavolVican196694c2017-01-27 10:33:09 +0100278 ret = yang_check_string(module, &save->emsg, "error_message", what, value, NULL);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100279 }
280 return ret;
281}
Pavol Vicanb5687112016-02-09 22:35:59 +0100282
283int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100284yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100285{
286 if (cont->presence) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100287 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100288 free(value);
289 return EXIT_FAILURE;
290 } else {
291 cont->presence = lydict_insert_zc(module->ctx, value);
292 return EXIT_SUCCESS;
293 }
294}
295
Pavol Vican235dbd42016-02-10 10:34:19 +0100296void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200297yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100298{
299 struct lys_when *retval;
300
301 retval = calloc(1, sizeof *retval);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200302 LY_CHECK_ERR_RETURN(!retval, LOGMEM; free(value), NULL);
Pavol Vican0adf01d2016-03-22 12:29:33 +0100303 retval->cond = transform_schema2json(module, value);
Michal Vasko508a50d2016-09-07 14:50:33 +0200304 if (!retval->cond) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100305 goto error;
306 }
307 switch (type) {
308 case CONTAINER_KEYWORD:
309 if (((struct lys_node_container *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100310 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100311 goto error;
312 }
313 ((struct lys_node_container *)node)->when = retval;
314 break;
Pavol Vicandb7489e2016-08-23 17:23:39 +0200315 case ANYDATA_KEYWORD:
Pavol Vican1f06ba82016-02-10 17:39:50 +0100316 case ANYXML_KEYWORD:
Radek Krejcibf2abff2016-08-23 15:51:52 +0200317 if (((struct lys_node_anydata *)node)->when) {
Pavol Vicandb7489e2016-08-23 17:23:39 +0200318 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", (type == ANYXML_KEYWORD) ? "anyxml" : "anydata");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100319 goto error;
320 }
Radek Krejcibf2abff2016-08-23 15:51:52 +0200321 ((struct lys_node_anydata *)node)->when = retval;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100322 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100323 case CHOICE_KEYWORD:
324 if (((struct lys_node_choice *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100325 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100326 goto error;
327 }
328 ((struct lys_node_choice *)node)->when = retval;
329 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100330 case CASE_KEYWORD:
331 if (((struct lys_node_case *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100332 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100333 goto error;
334 }
335 ((struct lys_node_case *)node)->when = retval;
336 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100337 case LEAF_KEYWORD:
338 if (((struct lys_node_leaf *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100339 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100340 goto error;
341 }
342 ((struct lys_node_leaf *)node)->when = retval;
343 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100344 case LEAF_LIST_KEYWORD:
345 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100346 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100347 goto error;
348 }
349 ((struct lys_node_leaflist *)node)->when = retval;
350 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100351 case LIST_KEYWORD:
352 if (((struct lys_node_list *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100353 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100354 goto error;
355 }
356 ((struct lys_node_list *)node)->when = retval;
357 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100358 case USES_KEYWORD:
359 if (((struct lys_node_uses *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100360 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100361 goto error;
362 }
363 ((struct lys_node_uses *)node)->when = retval;
364 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100365 case AUGMENT_KEYWORD:
366 if (((struct lys_node_augment *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100367 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100368 goto error;
369 }
370 ((struct lys_node_augment *)node)->when = retval;
371 break;
PavolVicanb0317082017-02-19 01:29:22 +0100372 case EXTENSION_INSTANCE:
373 *(struct lys_when **)node = retval;
374 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200375 default:
376 goto error;
377 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100378 }
379 free(value);
380 return retval;
381
382error:
383 free(value);
PavolVicanb0317082017-02-19 01:29:22 +0100384 lydict_remove(module->ctx, retval->cond);
385 free(retval);
Pavol Vican235dbd42016-02-10 10:34:19 +0100386 return NULL;
387}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100388
389void *
Pavol Vican05810b62016-11-23 14:07:22 +0100390yang_read_node(struct lys_module *module, struct lys_node *parent, struct lys_node **root,
391 char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100392{
Pavol Vican05810b62016-11-23 14:07:22 +0100393 struct lys_node *node, **child;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100394
Pavol Vican7cadfe72016-02-11 12:33:34 +0100395 node = calloc(1, sizeof_struct);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200396 LY_CHECK_ERR_RETURN(!node, LOGMEM; free(value), NULL);
397
Michal Vasko3e3228d2017-02-24 14:55:32 +0100398 LOGDBG(LY_LDGYANG, "parsing %s statement \"%s\"", strnodetype(nodetype), value);
PavolVican196694c2017-01-27 10:33:09 +0100399 node->name = lydict_insert_zc(module->ctx, value);
Pavol Vican7cadfe72016-02-11 12:33:34 +0100400 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100401 node->nodetype = nodetype;
PavolVicanbd1d1ae2017-07-20 00:06:00 +0200402 node->parent = parent;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100403
404 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100405 child = (parent) ? &parent->child : root;
406 if (*child) {
407 (*child)->prev->next = node;
408 (*child)->prev = node;
409 } else {
410 *child = node;
411 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100412 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100413 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100414}
415
416int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200417yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100418{
419 int ret;
420
421 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100422 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100423 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100424 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100425 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100426 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100427 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200428 default:
429 free(value);
430 LOGINT;
431 ret = EXIT_FAILURE;
432 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100433 }
434 return ret;
435}
436
437int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200438yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100439{
440 int ret;
441
442 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100443 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100444 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100445 break;
446 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100447 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100448 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100449 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100450 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100451 break;
PavolVican75af21d2016-12-29 20:04:07 +0100452 case ADD_KEYWORD:
453 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +0100454 case DELETE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100455 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100456 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200457 default:
458 free(value);
459 LOGINT;
460 ret = EXIT_FAILURE;
461 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100462 }
463 return ret;
464}
Pavol Vican5de33492016-02-22 14:03:24 +0100465
466int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100467yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100468{
469 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100470 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100471
472 exp = value = (char *) list->keys;
473 while ((value = strpbrk(value, " \t\n"))) {
474 list->keys_size++;
475 while (isspace(*value)) {
476 value++;
477 }
478 }
479 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100480
481 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100482 list->keys = calloc(list->keys_size, sizeof *list->keys);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200483 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM, EXIT_FAILURE);
484
Radek Krejci5c08a992016-11-02 13:30:04 +0100485 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
486 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
487 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100488 }
Pavol Vican5de33492016-02-22 14:03:24 +0100489 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100490}
491
492int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100493yang_fill_unique(struct lys_module *module, struct lys_node_list *list, struct lys_unique *unique, char *value, struct unres_schema *unres)
Pavol Vican85f12022016-03-05 16:30:35 +0100494{
495 int i, j;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200496 char *vaux, c;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200497 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100498
499 /* count the number of unique leafs in the value */
500 vaux = value;
501 while ((vaux = strpbrk(vaux, " \t\n"))) {
502 unique->expr_size++;
503 while (isspace(*vaux)) {
504 vaux++;
505 }
506 }
507 unique->expr_size++;
508 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200509 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM, error);
Pavol Vican85f12022016-03-05 16:30:35 +0100510
511 for (i = 0; i < unique->expr_size; i++) {
512 vaux = strpbrk(value, " \t\n");
Radek Krejci1a9c3612017-04-24 14:49:43 +0200513 if (vaux) {
514 c = *vaux;
515 *vaux = '\0';
Pavol Vican85f12022016-03-05 16:30:35 +0100516 }
517
Radek Krejci1a9c3612017-04-24 14:49:43 +0200518 /* store token into unique structure (includes converting prefix to the module name) */
519 unique->expr[i] = transform_schema2json(module, value);
520 if (vaux) {
521 *vaux = c;
522 }
Pavol Vican85f12022016-03-05 16:30:35 +0100523
524 /* check that the expression does not repeat */
525 for (j = 0; j < i; j++) {
526 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100527 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
PavolVican196694c2017-01-27 10:33:09 +0100528 LOGVAL(LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100529 goto error;
530 }
531 }
532 /* try to resolve leaf */
533 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200534 unique_info = malloc(sizeof *unique_info);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200535 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM, error);
Radek Krejcid09d1a52016-08-11 14:05:45 +0200536 unique_info->list = (struct lys_node *)list;
537 unique_info->expr = unique->expr[i];
538 unique_info->trg_type = &unique->trg_type;
539 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200540 goto error;
541 }
Pavol Vican85f12022016-03-05 16:30:35 +0100542 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200543 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100544 goto error;
545 }
546 }
547
548 /* move to next token */
549 value = vaux;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200550 while(value && isspace(*value)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100551 value++;
552 }
553 }
554
555 return EXIT_SUCCESS;
556
557error:
558 return EXIT_FAILURE;
559}
560
561int
Pavol Vican5de33492016-02-22 14:03:24 +0100562yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
563{
564 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100565 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100566
567 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100568 str = (char *)list->unique[k].expr;
569 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100570 goto error;
571 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100572 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100573 }
574 return EXIT_SUCCESS;
575
576error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100577 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100578 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100579}
580
Pavol Vican07f220f2016-09-02 13:04:37 +0200581int
Pavol Vican81344ac2016-09-02 14:23:06 +0200582yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100583{
Pavol Vican81344ac2016-09-02 14:23:06 +0200584 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
585 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
586 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100587 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200588 if (stype->type->info.lref.path) {
589 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
590 goto error;
591 }
592 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
593 stype->base = LY_TYPE_LEAFREF;
594 return EXIT_SUCCESS;
595
596error:
597 free(value);
598 return EXIT_FAILURE;
599}
600
601int
602yang_read_require_instance(struct yang_type *stype, int req)
603{
604 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
605 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
606 return EXIT_FAILURE;
607 }
608 if (stype->type->info.lref.req) {
609 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
610 return EXIT_FAILURE;
611 }
612 stype->type->info.lref.req = req;
613 stype->base = LY_TYPE_LEAFREF;
614 return EXIT_SUCCESS;
615}
616
617int
Pavol Vican7313fc02016-11-14 01:10:31 +0100618yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct lys_type *type, int tpdftype, struct unres_schema *unres)
Pavol Vican73e7c992016-02-24 12:18:05 +0100619{
Radek Krejcidce5f972017-09-12 15:47:49 +0200620 int rc, ret = -1;
621 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200622 int8_t req;
Pavol Vican73e7c992016-02-24 12:18:05 +0100623 const char *name, *value;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100624 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200625 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200626 struct lys_type *dertype;
627 struct lys_type_enum *enms_sc = NULL;
628 struct lys_type_bit *bits_sc = NULL;
629 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100630 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100631
Pavol Vican0adf01d2016-03-22 12:29:33 +0100632 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100633 if (!value) {
634 goto error;
635 }
636
637 i = parse_identifier(value);
638 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100639 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100640 lydict_remove(module->ctx, value);
641 goto error;
642 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200643 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100644 name = value;
645 if (value[i]) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100646 type->module_name = lydict_insert(module->ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100647 name += i;
648 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100649 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100650 lydict_remove(module->ctx, value);
651 goto error;
652 }
653 ++name;
654 }
655
Pavol Vican7313fc02016-11-14 01:10:31 +0100656 rc = resolve_superior_type(name, type->module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100657 if (rc == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100658 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, type->module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200659 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100660 goto error;
661
Michal Vasko01c6fd22016-05-20 11:43:05 +0200662 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100663 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200664 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200665 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100666 ret = EXIT_FAILURE;
667 goto error;
668 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200669 lydict_remove(module->ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200670
Pavol Vican7313fc02016-11-14 01:10:31 +0100671 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200672 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200673 * 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 +0200674 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
675 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200676 assert(((struct lys_node_grp *)siter)->unres_count);
677 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200678 } else {
679 LOGINT;
680 goto error;
681 }
682 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200683
684 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100685 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
686 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200687 goto error;
688 }
689
Pavol Vican8bd72e42016-08-29 09:53:05 +0200690 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100691 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100692 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100693 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100694 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100695 }
696 switch (base) {
697 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100698 if (type->base == LY_TYPE_BINARY) {
699 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100700 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100701 goto error;
702 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100703 type->info.binary.length = type->info.str.length;
704 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
705 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100706 goto error;
707 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100708 } else if (type->base == LY_TYPE_STRING) {
709 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
710 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100711 goto error;
712 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100713 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100714 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100715 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100716 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100717 break;
718 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100719 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100720 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100721 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100722 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100723 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100724 goto error;
725 }
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 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100728 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100729 goto error;
730 }
Radek Krejci4800f652016-09-08 14:02:52 +0200731
732 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100733 if (type->der->type.der) {
734 type->info.dec64.dig = type->der->type.info.dec64.dig;
735 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200736 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100737 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
738 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200739 goto error;
740 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100741 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
742 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100743 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100744 goto error;
745 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100746 type->info.num.range = type->info.dec64.range;
747 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
748 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100749 goto error;
750 }
751 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100752 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100753 goto error;
754 }
755 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100756 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100757 if (type->base != LY_TYPE_ENUM) {
758 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100759 goto error;
760 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100761 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200762
763 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100764 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200765 /* type is derived directly from buit-in enumeartion type and enum statement is required */
766 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
767 goto error;
768 }
769 } else {
770 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100771 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200772 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
773 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
774 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
775 goto error;
776 }
777
778 /* restricted enumeration type - the name MUST be used in the base type */
779 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100780 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200781 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100782 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200783 break;
784 }
785 }
786 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100787 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200788 goto error;
789 }
790
Pavol Vican7313fc02016-11-14 01:10:31 +0100791 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200792 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100793 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200794 } else {
795 /* check that the assigned value corresponds to the original
796 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100797 if (type->info.enums.enm[i].value != enms_sc[j].value) {
798 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200799 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100800 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
801 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200802 goto error;
803 }
804 }
805 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100806 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100807 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100808 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100809 if (type->base != LY_TYPE_BITS) {
810 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100811 goto error;
812 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100813 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200814
815 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100816 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200817 /* type is derived directly from buit-in bits type and bit statement is required */
818 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
819 goto error;
820 }
821 } else {
822 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100823 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200824 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
825 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
826 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
827 goto error;
828 }
829
830 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100831 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200832 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100833 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200834 break;
835 }
836 }
837 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100838 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200839 goto error;
840 }
841
842 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100843 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200844 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100845 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200846 } else {
847 /* check that the assigned position corresponds to the original
848 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100849 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
850 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200851 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100852 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
853 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200854 goto error;
855 }
856 }
857 }
Pavol Vican03a59442016-03-21 15:23:45 +0100858 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200859
Radek Krejcidce5f972017-09-12 15:47:49 +0200860 for (i = type->info.bits.count; i > 0; i--) {
861 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200862
863 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100864 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200865 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100866 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
867 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
868 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200869 j--;
870 }
Pavol Vican03a59442016-03-21 15:23:45 +0100871 }
872 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100873 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100874 if (type->base == LY_TYPE_INST) {
875 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200876 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100877 goto error;
878 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100879 if ((req = type->info.lref.req)) {
880 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200881 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100882 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200883 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100884 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200885 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
886 goto error;
887 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200888 /* flag resolving for later use */
889 if (!tpdftype) {
890 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
891 if (siter) {
892 /* just a flag - do not resolve */
893 tpdftype = 1;
894 }
895 }
896
Pavol Vican7313fc02016-11-14 01:10:31 +0100897 if (type->info.lref.path) {
898 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200899 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
900 goto error;
901 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100902 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100903 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100904 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100905 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100906 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100907 goto error;
908 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200909 /* try to resolve leafref path only when this is instantiated
910 * leaf, so it is not:
911 * - typedef's type,
912 * - in grouping definition,
913 * - just instantiated in a grouping definition,
914 * because in those cases the nodes referenced in path might not be present
915 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100916 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100917 goto error;
918 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100919 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100920 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100921 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200922 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200923 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100924 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200925 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100926 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200927 goto error;
928 }
Pavol Vican191613a2016-02-26 16:21:32 +0100929 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100930 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100931 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100932 goto error;
933 }
934 break;
935 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100936 if (type->base != LY_TYPE_IDENT) {
937 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100938 goto error;
939 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100940 if (type->der->type.der) {
941 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200942 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
943 goto error;
944 }
945 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100946 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200947 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
948 goto error;
949 }
950 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100951 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100952 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100953 if (type->base != LY_TYPE_UNION) {
954 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100955 goto error;
956 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100957 if (!type->info.uni.types) {
958 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100959 /* this is just a derived type with no additional type specified/required */
960 break;
961 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100962 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100963 goto error;
964 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100965 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100966 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100967 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
968 yang = (struct yang_type *)dertype->der;
969 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100970 dertype->parent = type->parent;
971 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100972 dertype->der = (struct lys_tpdf *)yang;
973 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100974 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100975 base = 0;
976 goto error;
977 } else {
978 lydict_remove(module->ctx, yang->name);
979 free(yang);
980 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100981 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200982 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100983 if (dertype->base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200984 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
985 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100986 } else if (dertype->base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200987 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
988 goto error;
989 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100990 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100991 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
992 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +0100993 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100994 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100995 }
996 break;
Pavol Vicana1827962016-02-29 15:39:42 +0100997
998 default:
999 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +01001000 if (type->base != base) {
1001 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001002 goto error;
1003 }
1004 } else {
1005 LOGINT;
1006 goto error;
1007 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001008 }
1009 return EXIT_SUCCESS;
1010
1011error:
Pavol Vican7313fc02016-11-14 01:10:31 +01001012 if (type->module_name) {
1013 lydict_remove(module->ctx, type->module_name);
1014 type->module_name = NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001015 }
Pavol Vican8bd72e42016-08-29 09:53:05 +02001016 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001017 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001018 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001019 return ret;
1020}
1021
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001022void
1023yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1024{
1025 struct lys_type *stype;
1026 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001027 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001028
1029 for (i = 0; i < type->info.uni.count; ++i) {
1030 stype = &type->info.uni.types[i];
1031 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1032 yang = (struct yang_type *)stype->der;
1033 stype->base = yang->base;
1034 lydict_remove(ctx, yang->name);
1035 free(yang);
1036 } else if (stype->base == LY_TYPE_UNION) {
1037 yang_free_type_union(ctx, stype);
1038 }
1039 }
1040}
1041
Pavol Vican73e7c992016-02-24 12:18:05 +01001042void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001043yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001044{
1045 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001046 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001047
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001048 typ = calloc(1, sizeof *typ);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001049 LY_CHECK_ERR_RETURN(!typ, LOGMEM, NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001050
1051 typ->flags = LY_YANG_STRUCTURE_FLAG;
1052 switch (type) {
1053 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001054 if (((struct lys_node_leaf *)parent)->type.der) {
1055 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1056 goto error;
1057 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001058 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1059 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1060 typ->type = &((struct lys_node_leaf *)parent)->type;
1061 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001062 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001063 if (((struct lys_node_leaflist *)parent)->type.der) {
1064 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1065 goto error;
1066 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001067 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1068 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1069 typ->type = &((struct lys_node_leaflist *)parent)->type;
1070 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001071 case UNION_KEYWORD:
1072 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1073 typ->type = (struct lys_type *)parent;
1074 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001075 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001076 if (((struct lys_tpdf *)parent)->type.der) {
1077 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1078 goto error;
1079 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001080 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1081 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001082 break;
1083 case REPLACE_KEYWORD:
1084 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001085 dev = (struct lys_deviate *)parent;
1086 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001087 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001088 goto error;
1089 }
PavolVican75af21d2016-12-29 20:04:07 +01001090 dev->type = calloc(1, sizeof *dev->type);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001091 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001092 dev->type->der = (struct lys_tpdf *)typ;
1093 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001094 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001095 case EXTENSION_INSTANCE:
1096 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1097 typ->type = parent;
1098 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001099 default:
1100 goto error;
1101 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001102 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001103 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001104 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001105
1106error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001107 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001108 free(typ);
1109 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001110}
1111
1112void *
PavolVicaneef1d912017-02-19 00:19:15 +01001113yang_read_length(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001114{
PavolVicaneef1d912017-02-19 00:19:15 +01001115 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001116
PavolVicaneef1d912017-02-19 00:19:15 +01001117 if (is_ext_instance) {
1118 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001119 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001120 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1121 stype->base = LY_TYPE_STRING;
1122 } else {
1123 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
1124 goto error;
1125 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001126
PavolVicaneef1d912017-02-19 00:19:15 +01001127 if (stype->type->info.str.length) {
1128 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
1129 goto error;
1130 }
1131 length = calloc(1, sizeof *length);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001132 LY_CHECK_ERR_GOTO(!length, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001133 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001134 }
PavolVicaneef1d912017-02-19 00:19:15 +01001135 length->expr = lydict_insert_zc(module->ctx, value);
1136 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001137
1138error:
1139 free(value);
1140 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001141}
Pavol Vican1c203db2016-02-24 14:05:23 +01001142
Pavol Vican6eecf302016-08-10 11:09:05 +02001143int
Radek Krejcib53154b2017-07-19 09:14:13 +02001144yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, void **precomp, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001145{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001146 char *buf;
1147 size_t len;
1148
PavolVicanbd1d1ae2017-07-20 00:06:00 +02001149 if (precomp && lyp_precompile_pattern(value, (pcre**)&precomp[0], (pcre_extra**)&precomp[1])) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001150 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001151 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001152 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001153
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001154 len = strlen(value);
1155 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Radek Krejcia8d111f2017-05-31 13:57:37 +02001156 LY_CHECK_ERR_RETURN(!buf, LOGMEM; free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001157
1158 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001159 strcpy(&buf[1], value);
1160 free(value);
1161
Pavol Vican6eecf302016-08-10 11:09:05 +02001162 pattern->expr = lydict_insert_zc(module->ctx, buf);
1163 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001164}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001165
1166void *
PavolVicaneef1d912017-02-19 00:19:15 +01001167yang_read_range(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001168{
PavolVicaneef1d912017-02-19 00:19:15 +01001169 struct lys_restr * range;
1170
1171 if (is_ext_instance) {
1172 range = (struct lys_restr *)stype;
1173 } else {
1174 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
1175 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
1176 goto error;
1177 }
1178 stype->base = LY_TYPE_DEC64;
1179 if (stype->type->info.dec64.range) {
1180 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
1181 goto error;
1182 }
1183 range = calloc(1, sizeof *range);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001184 LY_CHECK_ERR_GOTO(!range, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001185 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001186 }
PavolVicaneef1d912017-02-19 00:19:15 +01001187 range->expr = lydict_insert_zc(module->ctx, value);
1188 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001189
1190error:
1191 free(value);
1192 return NULL;
1193}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001194
1195int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001196yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001197{
Pavol Vican6b072512016-04-04 10:50:21 +02001198 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1199 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001200 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001201 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001202 goto error;
1203 }
1204 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001205 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001206 goto error;
1207 }
1208 /* range check */
1209 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001210 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001211 goto error;
1212 }
1213 typ->type->info.dec64.dig = value;
1214 return EXIT_SUCCESS;
1215
1216error:
1217 return EXIT_FAILURE;
1218}
Pavol Vican79a763d2016-02-25 15:41:27 +01001219
Pavol Vican874715f2016-10-25 14:52:08 +02001220int
1221yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001222{
Pavol Vican874715f2016-10-25 14:52:08 +02001223 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001224
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001225 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001226 if (!value[0]) {
1227 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1228 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1229 free(value);
1230 goto error;
1231 }
1232
Pavol Vican79a763d2016-02-25 15:41:27 +01001233 enm->name = lydict_insert_zc(module->ctx, value);
1234
1235 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1236 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001237 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001238 goto error;
1239 }
1240
Pavol Vican874715f2016-10-25 14:52:08 +02001241 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001242 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001243 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001244 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
1245 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001246 goto error;
1247 }
1248 }
1249
Pavol Vican874715f2016-10-25 14:52:08 +02001250 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001251
1252error:
Pavol Vican874715f2016-10-25 14:52:08 +02001253 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001254}
1255
1256int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001257yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001258{
1259 int i, j;
1260
1261 if (!assign) {
1262 /* assign value automatically */
1263 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001264 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001265 goto error;
1266 }
1267 enm->value = *value;
1268 enm->flags |= LYS_AUTOASSIGNED;
1269 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001270 } else if (typ->type->info.enums.enm == enm) {
1271 /* change value, which is assigned automatically, if first enum has value. */
1272 *value = typ->type->info.enums.enm[0].value;
1273 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001274 }
1275
1276 /* check that the value is unique */
1277 j = typ->type->info.enums.count-1;
1278 for (i = 0; i < j; i++) {
1279 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001280 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001281 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1282 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001283 goto error;
1284 }
1285 }
1286
1287 return EXIT_SUCCESS;
1288
1289error:
1290 return EXIT_FAILURE;
1291}
Pavol Vican9887c682016-02-29 11:32:01 +01001292
Pavol Vican59e8dee2016-10-25 15:29:38 +02001293int
1294yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001295{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001296 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001297
PavolVicane87cb932016-12-30 15:36:18 +01001298 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001299 bit->name = lydict_insert_zc(module->ctx, value);
1300 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001301 goto error;
1302 }
Pavol Vican9887c682016-02-29 11:32:01 +01001303
Pavol Vican59e8dee2016-10-25 15:29:38 +02001304 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001305 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001306 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001307 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001308 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001309 goto error;
1310 }
1311 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001312 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001313
1314error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001315 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001316}
1317
1318int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001319yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001320{
1321 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001322
1323 if (!assign) {
1324 /* assign value automatically */
1325 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001326 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001327 goto error;
1328 }
1329 bit->pos = (uint32_t)*value;
1330 bit->flags |= LYS_AUTOASSIGNED;
1331 (*value)++;
1332 }
1333
1334 j = typ->type->info.bits.count - 1;
1335 /* check that the value is unique */
1336 for (i = 0; i < j; i++) {
1337 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001338 LOGVAL(LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name, typ->type->info.bits.bit[i].name);
Pavol Vican9887c682016-02-29 11:32:01 +01001339 goto error;
1340 }
1341 }
1342
Pavol Vican9887c682016-02-29 11:32:01 +01001343 return EXIT_SUCCESS;
1344
1345error:
1346 return EXIT_FAILURE;
1347}
Pavol Vican0df02b02016-03-01 10:28:50 +01001348
Pavol Vican3ad50f82016-12-04 15:00:36 +01001349int
1350yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001351{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001352 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001353 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001354 free(value);
1355 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001356 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001357 }
1358 aug->parent = parent;
1359 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001360 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001361}
Pavol Vican220e5a12016-03-03 14:19:43 +01001362
PavolVican6f000922017-02-10 12:56:59 +01001363void *
PavolVican75af21d2016-12-29 20:04:07 +01001364yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001365{
PavolVican75af21d2016-12-29 20:04:07 +01001366 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001367 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001368 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001369 }
PavolVican75af21d2016-12-29 20:04:07 +01001370 dev->deviate = calloc(1, sizeof *dev->deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001371 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001372 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1373 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001374 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001375}
1376
1377void *
PavolVican75af21d2016-12-29 20:04:07 +01001378yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001379{
PavolVican75af21d2016-12-29 20:04:07 +01001380 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001381
PavolVican4b80d042017-02-23 14:30:27 +01001382 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001383 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1384 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001385 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001386 }
PavolVican75af21d2016-12-29 20:04:07 +01001387 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1388 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001389 LY_CHECK_ERR_RETURN(!deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001390 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1391 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001392 }
PavolVican75af21d2016-12-29 20:04:07 +01001393 dev->deviate[dev->deviate_size].mod = mod;
1394 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001395}
1396
1397int
PavolVican75af21d2016-12-29 20:04:07 +01001398yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001399{
1400 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001401 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001402
Pavol Vican85f12022016-03-05 16:30:35 +01001403 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001404 if (dev_target->nodetype == LYS_LEAFLIST) {
1405 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1406 } else if (dev_target->nodetype == LYS_LEAF) {
1407 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001408 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001409 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1410 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001411 goto error;
1412 }
1413
PavolVican75af21d2016-12-29 20:04:07 +01001414 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001415 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001416 if (!ly_strequal(*stritem, deviate->units, 1)) {
1417 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001418 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001419 goto error;
1420 }
1421 /* remove current units value of the target */
1422 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001423 *stritem = NULL;
1424 /* remove its extensions */
1425 j = -1;
1426 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1427 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1428 --j;
1429 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001430 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001431 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001432 /* check that there is no current value */
1433 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001434 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1435 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001436 goto error;
1437 }
1438 } else { /* replace */
1439 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001440 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1441 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001442 goto error;
1443 }
1444 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001445 /* remove current units value of the target ... */
1446 lydict_remove(ctx, *stritem);
1447
1448 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001449 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001450 }
1451
Pavol Vican85f12022016-03-05 16:30:35 +01001452 return EXIT_SUCCESS;
1453
1454error:
1455 return EXIT_FAILURE;
1456}
1457
1458int
PavolVican75af21d2016-12-29 20:04:07 +01001459yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001460{
Pavol Vican85f12022016-03-05 16:30:35 +01001461 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001462 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001463
1464 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001465 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001466 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1467 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001468 goto error;
1469 }
1470
PavolVican75af21d2016-12-29 20:04:07 +01001471 list = (struct lys_node_list *)dev_target;
1472 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001473 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001474 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001475 LY_CHECK_ERR_GOTO(!unique, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001476 list->unique = unique;
1477 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001478 }
1479
1480 return EXIT_SUCCESS;
1481
1482error:
1483 return EXIT_FAILURE;
1484}
1485
1486int
PavolVican75af21d2016-12-29 20:04:07 +01001487yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1488 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001489{
1490 struct lys_node *node;
1491 struct lys_node_choice *choice;
1492 struct lys_node_leaf *leaf;
1493 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001494 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001495 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001496
Pavol Vican38321d02016-08-16 14:56:02 +02001497 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001498 if (dev_target->nodetype == LYS_CHOICE) {
1499 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001500 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1501 if (rc || !node) {
1502 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1503 goto error;
1504 }
PavolVican75af21d2016-12-29 20:04:07 +01001505 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001506 if (!choice->dflt || (choice->dflt != node)) {
1507 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1508 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1509 goto error;
1510 }
PavolVican6f000922017-02-10 12:56:59 +01001511 choice->dflt = NULL;
1512 /* remove extensions of this default instance from the target node */
1513 j = -1;
1514 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1515 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1516 --j;
1517 }
Pavol Vican38321d02016-08-16 14:56:02 +02001518 } else { /* add or replace */
1519 choice->dflt = node;
1520 if (!choice->dflt) {
1521 /* default branch not found */
1522 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1523 goto error;
1524 }
1525 }
PavolVican75af21d2016-12-29 20:04:07 +01001526 } else if (dev_target->nodetype == LYS_LEAF) {
1527 leaf = (struct lys_node_leaf *)dev_target;
1528 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001529 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1530 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1531 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1532 goto error;
1533 }
1534 /* remove value */
1535 lydict_remove(ctx, leaf->dflt);
1536 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001537 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001538 /* remove extensions of this default instance from the target node */
1539 j = -1;
1540 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1541 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1542 --j;
1543 }
Pavol Vican38321d02016-08-16 14:56:02 +02001544 } else { /* add (already checked) and replace */
1545 /* remove value */
1546 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001547 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001548
1549 /* set new value */
1550 leaf->dflt = lydict_insert(ctx, value, u);
1551
1552 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001553 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001554 }
1555 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001556 llist = (struct lys_node_leaflist *)dev_target;
1557 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001558 /* find and remove the value in target list */
1559 for (i = 0; i < llist->dflt_size; i++) {
1560 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1561 /* match, remove the value */
1562 lydict_remove(llist->module->ctx, llist->dflt[i]);
1563 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001564 /* remove extensions of this default instance from the target node */
1565 j = -1;
1566 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1567 if (dev_target->ext[j]->insubstmt_index == i) {
1568 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1569 --j;
1570 } else if (dev_target->ext[j]->insubstmt_index > i) {
1571 /* decrease the substatement index of the extension because of the changed array of defaults */
1572 dev_target->ext[j]->insubstmt_index--;
1573 }
1574 }
Pavol Vican38321d02016-08-16 14:56:02 +02001575 break;
1576 }
1577 }
1578 if (i == llist->dflt_size) {
1579 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1580 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1581 goto error;
1582 }
1583 } else {
1584 /* add or replace, anyway we place items into the deviate's list
1585 which propagates to the target */
1586 /* we just want to check that the value isn't already in the list */
1587 for (i = 0; i < llist->dflt_size; i++) {
1588 if (ly_strequal(llist->dflt[i], value, 1)) {
1589 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1590 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1591 goto error;
1592 }
1593 }
1594 /* store it in target node */
1595 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1596
1597 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001598 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001599 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001600 }
1601 }
1602
1603 return EXIT_SUCCESS;
1604error:
1605 return EXIT_FAILURE;
1606}
1607
Pavol Vican38321d02016-08-16 14:56:02 +02001608int
PavolVican75af21d2016-12-29 20:04:07 +01001609yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1610 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001611{
PavolVican75af21d2016-12-29 20:04:07 +01001612 int i;
1613 struct lys_node_leaflist *llist;
1614 const char **dflt;
1615
1616 /* check target node type */
1617 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1618 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1619 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1620 goto error;
1621 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1622 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1623 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1624 goto error;
1625 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1626 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1627 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001628 goto error;
1629 }
1630
PavolVican75af21d2016-12-29 20:04:07 +01001631 if (deviate->mod == LY_DEVIATE_ADD) {
1632 /* check that there is no current value */
1633 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1634 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1635 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1636 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1637 goto error;
1638 }
Pavol Vican85f12022016-03-05 16:30:35 +01001639
PavolVican75af21d2016-12-29 20:04:07 +01001640 /* check collision with mandatory/min-elements */
1641 if ((dev_target->flags & LYS_MAND_TRUE) ||
1642 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1643 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1644 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1645 "Adding the \"default\" statement is forbidden on %s statement.",
1646 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1647 goto error;
1648 }
1649 } else if (deviate->mod == LY_DEVIATE_RPL) {
1650 /* check that there was a value before */
1651 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1652 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1653 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1654 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1655 goto error;
1656 }
1657 }
Pavol Vican85f12022016-03-05 16:30:35 +01001658
PavolVican75af21d2016-12-29 20:04:07 +01001659 if (dev_target->nodetype == LYS_LEAFLIST) {
1660 /* reallocate default list in the target */
1661 llist = (struct lys_node_leaflist *)dev_target;
1662 if (deviate->mod == LY_DEVIATE_ADD) {
1663 /* reallocate (enlarge) the unique array of the target */
1664 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001665 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001666 llist->dflt = dflt;
1667 } else if (deviate->mod == LY_DEVIATE_RPL) {
1668 /* reallocate (replace) the unique array of the target */
1669 for (i = 0; i < llist->dflt_size; i++) {
1670 lydict_remove(llist->module->ctx, llist->dflt[i]);
1671 }
1672 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001673 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001674 llist->dflt = dflt;
1675 llist->dflt_size = 0;
1676 }
1677 }
1678
1679 for (i = 0; i < deviate->dflt_size; ++i) {
1680 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1681 goto error;
1682 }
1683 }
Pavol Vican85f12022016-03-05 16:30:35 +01001684
1685 return EXIT_SUCCESS;
1686
1687error:
1688 return EXIT_FAILURE;
1689}
1690
1691int
PavolVican75af21d2016-12-29 20:04:07 +01001692yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001693{
Radek Krejcie00d2312016-08-12 15:27:49 +02001694 struct lys_node *parent;
1695
Pavol Vican85f12022016-03-05 16:30:35 +01001696 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001697 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001698 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1699 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001700 goto error;
1701 }
1702
PavolVican75af21d2016-12-29 20:04:07 +01001703 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001704 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001705 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001706 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1707 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001708 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001709 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001710 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001711 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1712 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1713 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1714 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001715 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001716 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1717 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1718 goto error;
1719 }
Pavol Vican85f12022016-03-05 16:30:35 +01001720 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001721 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001722 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001723 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1724 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001725 goto error;
1726 }
Pavol Vican85f12022016-03-05 16:30:35 +01001727 }
1728
Pavol Vican85f12022016-03-05 16:30:35 +01001729 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001730 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001731
1732 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001733 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001734
Radek Krejcie00d2312016-08-12 15:27:49 +02001735 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001736 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001737 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1738 parent = parent->parent) {
1739 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1740 /* stop also on presence containers */
1741 break;
1742 }
1743 }
1744 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1745 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1746 if (lyp_check_mandatory_choice(parent)) {
1747 goto error;
1748 }
1749 }
1750
Pavol Vican85f12022016-03-05 16:30:35 +01001751 return EXIT_SUCCESS;
1752
1753error:
1754 return EXIT_FAILURE;
1755}
1756
1757int
PavolVican75af21d2016-12-29 20:04:07 +01001758yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001759{
Pavol Vican09adcc32016-08-25 10:51:36 +02001760 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001761
1762 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001763 if (dev_target->nodetype == LYS_LEAFLIST) {
1764 max = &((struct lys_node_leaflist *)dev_target)->max;
1765 min = &((struct lys_node_leaflist *)dev_target)->min;
1766 } else if (dev_target->nodetype == LYS_LIST) {
1767 max = &((struct lys_node_list *)dev_target)->max;
1768 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001769 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001770 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1771 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"%s\" property.", (type) ? "max-elements" : "min-elements");
Pavol Vican85f12022016-03-05 16:30:35 +01001772 goto error;
1773 }
1774
PavolVican75af21d2016-12-29 20:04:07 +01001775 ui32val = (type) ? max : min;
1776 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001777 /* check that there is no current value */
1778 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001779 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1780 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001781 goto error;
1782 }
PavolVican75af21d2016-12-29 20:04:07 +01001783 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001784 /* unfortunately, there is no way to check reliably that there
1785 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001786 }
1787
1788 /* add (already checked) and replace */
1789 /* set new value specified in deviation */
1790 *ui32val = value;
1791
Pavol Vican09adcc32016-08-25 10:51:36 +02001792 /* check min-elements is smaller than max-elements */
1793 if (*max && *min > *max) {
1794 if (type) {
1795 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1796 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1797 } else {
1798 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1799 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1800 }
1801 goto error;
1802 }
1803
Pavol Vican85f12022016-03-05 16:30:35 +01001804 return EXIT_SUCCESS;
1805
1806error:
1807 return EXIT_FAILURE;
1808}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001809
1810int
PavolVican75af21d2016-12-29 20:04:07 +01001811yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1812 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001813{
PavolVican75af21d2016-12-29 20:04:07 +01001814 int i, j, erase_must = 1;
1815 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001816 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001817
PavolVican75af21d2016-12-29 20:04:07 +01001818 /* check target node type */
1819 switch (dev_target->nodetype) {
1820 case LYS_LEAF:
1821 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1822 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001823 break;
PavolVican75af21d2016-12-29 20:04:07 +01001824 case LYS_CONTAINER:
1825 trg_must = &((struct lys_node_container *)dev_target)->must;
1826 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1827 break;
1828 case LYS_LEAFLIST:
1829 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1830 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1831 break;
1832 case LYS_LIST:
1833 trg_must = &((struct lys_node_list *)dev_target)->must;
1834 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1835 break;
1836 case LYS_ANYXML:
1837 case LYS_ANYDATA:
1838 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1839 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1840 break;
1841 default:
1842 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1843 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1844 goto error;
1845 }
1846
1847 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001848 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001849
1850 if (deviate->mod == LY_DEVIATE_ADD) {
1851 /* reallocate the must array of the target */
1852 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001853 LY_CHECK_ERR_GOTO(!must, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001854 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001855 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001856 free(deviate->must);
1857 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001858 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001859 erase_must = 0;
1860 } else if (deviate->mod == LY_DEVIATE_DEL) {
1861 /* find must to delete, we are ok with just matching conditions */
1862 for (j = 0; j < deviate->must_size; ++j) {
1863 for (i = 0; i < *trg_must_size; i++) {
1864 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1865 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001866 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001867 /* ... and maintain the array */
1868 (*trg_must_size)--;
1869 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001870 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001871 }
1872 if (!(*trg_must_size)) {
1873 free(*trg_must);
1874 *trg_must = NULL;
1875 } else {
PavolVican214408f2017-02-03 11:54:05 +01001876 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001877 }
1878
1879 i = -1; /* set match flag */
1880 break;
1881 }
1882 }
1883 if (i != -1) {
1884 /* no match found */
1885 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1886 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1887 goto error;
1888 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001889 }
1890 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001891
PavolVican6f000922017-02-10 12:56:59 +01001892 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1893 goto error;
1894 }
PavolVican75af21d2016-12-29 20:04:07 +01001895 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02001896 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && *trg_must_size
1897 && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001898 goto error;
1899 }
1900
PavolVican75af21d2016-12-29 20:04:07 +01001901 return EXIT_SUCCESS;
1902error:
1903 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1904 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001905 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001906 }
1907 free(deviate->must);
1908 }
1909 return EXIT_FAILURE;
1910}
1911
1912int
1913yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1914 struct lys_node_list *list, int index, char * value)
1915{
PavolVican6f000922017-02-10 12:56:59 +01001916 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001917
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001918 /* find unique structures to delete */
1919 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001920 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001921 continue;
1922 }
1923
PavolVican75af21d2016-12-29 20:04:07 +01001924 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1925 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001926 break;
1927 }
1928 }
1929
PavolVican75af21d2016-12-29 20:04:07 +01001930 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001931 /* we have a match, free the unique structure ... */
1932 for (j = 0; j < list->unique[i].expr_size; j++) {
1933 lydict_remove(module->ctx, list->unique[i].expr[j]);
1934 }
1935 free(list->unique[i].expr);
1936 /* ... and maintain the array */
1937 list->unique_size--;
1938 if (i != list->unique_size) {
1939 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1940 list->unique[i].expr = list->unique[list->unique_size].expr;
1941 }
1942
1943 if (!list->unique_size) {
1944 free(list->unique);
1945 list->unique = NULL;
1946 } else {
1947 list->unique[list->unique_size].expr_size = 0;
1948 list->unique[list->unique_size].expr = NULL;
1949 }
1950
PavolVican6f000922017-02-10 12:56:59 +01001951 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001952 i = -1; /* set match flag */
1953 break;
1954 }
1955 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001956
1957 if (i != -1) {
1958 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001959 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1960 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001961 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001962 }
1963
PavolVican6f000922017-02-10 12:56:59 +01001964 /* remove extensions of this unique instance from the target node */
1965 j = -1;
1966 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1967 if (list->ext[j]->insubstmt_index == k) {
1968 lyp_ext_instance_rm(module->ctx, &list->ext, &list->ext_size, j);
1969 --j;
1970 } else if (list->ext[j]->insubstmt_index > k) {
1971 /* decrease the substatement index of the extension because of the changed array of uniques */
1972 list->ext[j]->insubstmt_index--;
1973 }
1974 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001975 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001976}
Pavol Vican021488a2016-01-25 23:56:12 +01001977
PavolVican75af21d2016-12-29 20:04:07 +01001978int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01001979{
PavolVican75af21d2016-12-29 20:04:07 +01001980 struct lys_node_list *list;
1981 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01001982 uint i = 0;
1983 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01001984
PavolVican75af21d2016-12-29 20:04:07 +01001985 if (yang_read_deviate_unique(deviate, dev_target)) {
1986 goto error;
1987 }
1988 list = (struct lys_node_list *)dev_target;
1989 last_unique = &list->unique[list->unique_size];
1990 for (i = 0; i < deviate->unique_size; ++i) {
1991 str = (char *) deviate->unique[i].expr;
1992 if (deviate->mod == LY_DEVIATE_ADD) {
1993 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
1994 free(str);
1995 goto error;
1996 }
1997 list->unique_size++;
1998 } else if (deviate->mod == LY_DEVIATE_DEL) {
1999 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
2000 free(str);
2001 goto error;
2002 }
2003 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2004 free(str);
2005 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002006 }
2007 }
PavolVican75af21d2016-12-29 20:04:07 +01002008 free(str);
2009 }
2010 if (deviate->mod == LY_DEVIATE_ADD) {
2011 free(deviate->unique);
2012 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002013 }
Pavol Vican38321d02016-08-16 14:56:02 +02002014
Pavol Vican38321d02016-08-16 14:56:02 +02002015
PavolVican75af21d2016-12-29 20:04:07 +01002016 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002017error:
PavolVican75af21d2016-12-29 20:04:07 +01002018 if (deviate->mod == LY_DEVIATE_ADD) {
2019 for (i = i + 1; i < deviate->unique_size; ++i) {
2020 free(deviate->unique[i].expr);
2021 }
2022 free(deviate->unique);
2023 deviate->unique = last_unique;
2024
2025 }
Pavol Vican021488a2016-01-25 23:56:12 +01002026 return EXIT_FAILURE;
2027}
2028
Pavol Vicanec423c92016-10-24 21:33:43 +02002029static int
2030yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2031 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002032{
Pavol Vican55870412016-03-10 12:36:21 +01002033 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002034 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002035 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002036
Pavol Vicanec423c92016-10-24 21:33:43 +02002037 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002038 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002039 if (!rc) {
2040 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002041 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002042 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2043 &trg->inc[trg->inc_size], unres)) {
2044 ret = -1;
2045 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002046 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002047 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002048 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002049 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002050 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002051
Pavol Vicanec423c92016-10-24 21:33:43 +02002052 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002053 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002054}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002055
PavolVicanc1807262017-01-31 18:00:27 +01002056struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002057yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002058{
2059 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2060 LYEXT_PAR parent_type;
2061 uint8_t *size;
2062
2063 switch (type) {
2064 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002065 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002066 ext = &((struct lys_module *)node)->ext;
2067 size = &((struct lys_module *)node)->ext_size;
2068 parent_type = LYEXT_PAR_MODULE;
2069 break;
PavolVican22e88682017-02-14 22:38:18 +01002070 case BELONGS_TO_KEYWORD:
2071 if (is_ext_instance) {
2072 ext = &((struct lys_ext_instance *)node)->ext;
2073 size = &((struct lys_ext_instance *)node)->ext_size;
2074 parent_type = LYEXT_PAR_EXTINST;
2075 } else {
2076 ext = &((struct lys_module *)node)->ext;
2077 size = &((struct lys_module *)node)->ext_size;
2078 parent_type = LYEXT_PAR_MODULE;
2079 }
2080 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002081 case IMPORT_KEYWORD:
2082 ext = &((struct lys_import *)node)->ext;
2083 size = &((struct lys_import *)node)->ext_size;
2084 parent_type = LYEXT_PAR_IMPORT;
2085 break;
2086 case INCLUDE_KEYWORD:
2087 ext = &((struct lys_include *)node)->ext;
2088 size = &((struct lys_include *)node)->ext_size;
2089 parent_type = LYEXT_PAR_INCLUDE;
2090 break;
PavolVican171717d2017-02-01 14:49:55 +01002091 case REVISION_KEYWORD:
2092 ext = &((struct lys_revision *)node)->ext;
2093 size = &((struct lys_revision *)node)->ext_size;
2094 parent_type = LYEXT_PAR_REVISION;
2095 break;
PavolVican70ce7452017-02-01 15:39:39 +01002096 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002097 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002098 case LEAF_KEYWORD:
2099 case LEAF_LIST_KEYWORD:
2100 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002101 case CHOICE_KEYWORD:
2102 case CASE_KEYWORD:
2103 case ANYXML_KEYWORD:
2104 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002105 case USES_KEYWORD:
2106 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002107 case ACTION_KEYWORD:
2108 case RPC_KEYWORD:
2109 case INPUT_KEYWORD:
2110 case OUTPUT_KEYWORD:
2111 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002112 ext = &((struct lys_node *)node)->ext;
2113 size = &((struct lys_node *)node)->ext_size;
2114 parent_type = LYEXT_PAR_NODE;
2115 break;
PavolVican19dc6152017-02-06 12:04:15 +01002116 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002117 if (is_ext_instance) {
2118 ext = &((struct lys_ext_instance *)node)->ext;
2119 size = &((struct lys_ext_instance *)node)->ext_size;
2120 parent_type = LYEXT_PAR_EXTINST;
2121 } else {
2122 ext = &((struct lys_ext *)node)->ext;
2123 size = &((struct lys_ext *)node)->ext_size;
2124 parent_type = LYEXT_PAR_EXT;
2125 }
2126 break;
PavolVican19dc6152017-02-06 12:04:15 +01002127 case EXTENSION_KEYWORD:
2128 ext = &((struct lys_ext *)node)->ext;
2129 size = &((struct lys_ext *)node)->ext_size;
2130 parent_type = LYEXT_PAR_EXT;
2131 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002132 case FEATURE_KEYWORD:
2133 ext = &((struct lys_feature *)node)->ext;
2134 size = &((struct lys_feature *)node)->ext_size;
2135 parent_type = LYEXT_PAR_FEATURE;
2136 break;
PavolVican8fa31242017-02-07 11:04:26 +01002137 case IDENTITY_KEYWORD:
2138 ext = &((struct lys_ident *)node)->ext;
2139 size = &((struct lys_ident *)node)->ext_size;
2140 parent_type = LYEXT_PAR_IDENT;
2141 break;
2142 case IF_FEATURE_KEYWORD:
2143 ext = &((struct lys_iffeature *)node)->ext;
2144 size = &((struct lys_iffeature *)node)->ext_size;
2145 parent_type = LYEXT_PAR_IFFEATURE;
2146 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002147 case TYPEDEF_KEYWORD:
2148 ext = &((struct lys_tpdf *)node)->ext;
2149 size = &((struct lys_tpdf *)node)->ext_size;
2150 parent_type = LYEXT_PAR_TPDF;
2151 break;
PavolVican056fcd12017-02-07 15:36:53 +01002152 case TYPE_KEYWORD:
2153 ext = &((struct yang_type *)node)->type->ext;
2154 size = &((struct yang_type *)node)->type->ext_size;
2155 parent_type = LYEXT_PAR_TYPE;
2156 break;
2157 case LENGTH_KEYWORD:
2158 case PATTERN_KEYWORD:
2159 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002160 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002161 ext = &((struct lys_restr *)node)->ext;
2162 size = &((struct lys_restr *)node)->ext_size;
2163 parent_type = LYEXT_PAR_RESTR;
2164 break;
PavolVican59ba4602017-02-08 11:53:32 +01002165 case WHEN_KEYWORD:
2166 ext = &((struct lys_when *)node)->ext;
2167 size = &((struct lys_when *)node)->ext_size;
2168 parent_type = LYEXT_PAR_RESTR;
2169 break;
PavolVican056fcd12017-02-07 15:36:53 +01002170 case ENUM_KEYWORD:
2171 ext = &((struct lys_type_enum *)node)->ext;
2172 size = &((struct lys_type_enum *)node)->ext_size;
2173 parent_type = LYEXT_PAR_TYPE_ENUM;
2174 break;
2175 case BIT_KEYWORD:
2176 ext = &((struct lys_type_bit *)node)->ext;
2177 size = &((struct lys_type_bit *)node)->ext_size;
2178 parent_type = LYEXT_PAR_TYPE_BIT;
2179 break;
PavolVican77374ee2017-02-08 15:18:45 +01002180 case REFINE_KEYWORD:
2181 ext = &((struct lys_type_bit *)node)->ext;
2182 size = &((struct lys_type_bit *)node)->ext_size;
2183 parent_type = LYEXT_PAR_REFINE;
2184 break;
PavolVican6f000922017-02-10 12:56:59 +01002185 case DEVIATION_KEYWORD:
2186 ext = &((struct lys_deviation *)node)->ext;
2187 size = &((struct lys_deviation *)node)->ext_size;
2188 parent_type = LYEXT_PAR_DEVIATION;
2189 break;
2190 case NOT_SUPPORTED_KEYWORD:
2191 case ADD_KEYWORD:
2192 case DELETE_KEYWORD:
2193 case REPLACE_KEYWORD:
2194 ext = &((struct lys_deviate *)node)->ext;
2195 size = &((struct lys_deviate *)node)->ext_size;
2196 parent_type = LYEXT_PAR_DEVIATE;
2197 break;
PavolVicandefa4852017-02-10 13:13:23 +01002198 case EXTENSION_INSTANCE:
2199 ext = &((struct lys_ext_instance *)node)->ext;
2200 size = &((struct lys_ext_instance *)node)->ext_size;
2201 parent_type = LYEXT_PAR_EXTINST;
2202 break;
PavolVicanc1807262017-01-31 18:00:27 +01002203 default:
2204 LOGINT;
2205 return NULL;
2206 }
2207
2208 instance = calloc(1, sizeof *instance);
2209 if (!instance) {
2210 goto error;
2211 }
2212 instance->parent_type = parent_type;
2213 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2214 if (!tmp) {
2215 goto error;
2216 }
2217 tmp[*size] = instance;
2218 *ext = tmp;
2219 (*size)++;
2220 return instance;
2221
2222error:
2223 LOGMEM;
2224 free(instance);
2225 return NULL;
2226}
2227
2228void *
2229yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002230 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002231{
2232 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002233 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002234
2235 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002236 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002237 if (!instance) {
2238 return NULL;
2239 }
PavolVicanc1807262017-01-31 18:00:27 +01002240 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002241 case YANG_VERSION_KEYWORD:
2242 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002243 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002244 break;
PavolVicanc1807262017-01-31 18:00:27 +01002245 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002246 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002247 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002248 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002249 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002250 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002251 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002252 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002253 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002254 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002255 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002256 break;
2257 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002258 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002259 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002260 break;
2261 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002262 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002263 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002264 break;
PavolVican171717d2017-02-01 14:49:55 +01002265 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002266 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002267 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002268 break;
2269 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002270 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002271 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002272 break;
PavolVican19dc6152017-02-06 12:04:15 +01002273 case YIN_ELEMENT_KEYWORD:
2274 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002275 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002276 break;
2277 case STATUS_KEYWORD:
2278 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002279 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002280 break;
PavolVican8fa31242017-02-07 11:04:26 +01002281 case BASE_KEYWORD:
2282 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002283 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002284 if (backup_type == IDENTITY_KEYWORD) {
2285 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002286 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002287 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2288 }
PavolVican8fa31242017-02-07 11:04:26 +01002289 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002290 case DEFAULT_KEYWORD:
2291 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002292 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002293 switch (backup_type) {
2294 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002295 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002296 break;
2297 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002298 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002299 break;
2300 case ADD_KEYWORD:
2301 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2302 break;
2303 default:
2304 /* nothing changes */
2305 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002306 }
PavolVicandf9e7972017-02-07 11:41:38 +01002307 break;
2308 case UNITS_KEYWORD:
2309 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002310 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002311 break;
PavolVican056fcd12017-02-07 15:36:53 +01002312 case REQUIRE_INSTANCE_KEYWORD:
2313 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002314 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002315 break;
2316 case PATH_KEYWORD:
2317 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002318 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002319 break;
2320 case ERROR_MESSAGE_KEYWORD:
2321 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002322 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002323 break;
2324 case ERROR_APP_TAG_KEYWORD:
2325 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002326 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002327 break;
2328 case MODIFIER_KEYWORD:
2329 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002330 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002331 break;
2332 case FRACTION_DIGITS_KEYWORD:
2333 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002334 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002335 break;
2336 case VALUE_KEYWORD:
2337 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002338 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002339 break;
2340 case POSITION_KEYWORD:
2341 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002342 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002343 break;
PavolVican5b910842017-02-08 13:08:47 +01002344 case PRESENCE_KEYWORD:
2345 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002346 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002347 break;
2348 case CONFIG_KEYWORD:
2349 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002350 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002351 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002352 case MANDATORY_KEYWORD:
2353 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002354 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002355 break;
2356 case MIN_ELEMENTS_KEYWORD:
2357 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002358 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002359 break;
2360 case MAX_ELEMENTS_KEYWORD:
2361 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002362 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002363 break;
2364 case ORDERED_BY_KEYWORD:
2365 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002366 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002367 break;
2368 case KEY_KEYWORD:
2369 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002370 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002371 break;
2372 case UNIQUE_KEYWORD:
2373 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002374 stmt = LY_STMT_UNIQUE;
2375 switch (backup_type) {
2376 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002377 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002378 break;
2379 case ADD_KEYWORD:
2380 case DELETE_KEYWORD:
2381 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002382 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002383 break;
2384 default:
2385 /* nothing changes */
2386 break;
PavolVican6f000922017-02-10 12:56:59 +01002387 }
PavolVican3feb2f92017-02-08 13:44:39 +01002388 break;
PavolVicanc1807262017-01-31 18:00:27 +01002389 default:
2390 LOGINT;
2391 return NULL;
2392 }
2393 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002394 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002395 if (!instance) {
2396 return NULL;
2397 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002398 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002399 switch (actual_type) {
2400 case ARGUMENT_KEYWORD:
2401 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002402 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002403 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002404 case BELONGS_TO_KEYWORD:
2405 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002406 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002407 break;
PavolVican19dc6152017-02-06 12:04:15 +01002408 default:
2409 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2410 break;
2411 }
PavolVicanc1807262017-01-31 18:00:27 +01002412 }
2413 instance->flags |= LYEXT_OPT_YANG;
2414 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2415 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002416 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2417 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2418 }
PavolVicanc1807262017-01-31 18:00:27 +01002419 return instance;
2420}
2421
PavolVican05c4f9b2017-09-07 13:33:54 +02002422static int
2423check_status_flag(struct lys_node *node, struct lys_node *parent)
2424{
2425 char *str;
2426
2427 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2428 /* status is not inherited by specification, but it not make sense to have
2429 * current in deprecated or deprecated in obsolete, so we print warning
2430 * and fix the schema by inheriting */
2431 if (!(node->flags & (LYS_STATUS_MASK))) {
2432 /* status not explicitely specified on the current node -> inherit */
2433 str = lys_path(parent);
2434 LOGWRN("Missing status in %s subtree (%s), inheriting.",
2435 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2436 free(str);
2437 node->flags |= parent->flags & LYS_STATUS_MASK;
2438 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2439 /* invalid combination of statuses */
2440 switch (node->flags & LYS_STATUS_MASK) {
2441 case 0:
2442 case LYS_STATUS_CURR:
2443 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
2444 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2445 break;
2446 case LYS_STATUS_DEPRC:
2447 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
2448 "obsolete", parent->name);
2449 break;
2450 }
2451 return EXIT_FAILURE;
2452 }
2453 }
2454
2455 return EXIT_SUCCESS;
2456}
2457
Pavol Vicanf4717e62016-03-16 11:30:01 +01002458int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002459store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002460{
Pavol Vicanec598812016-11-30 14:13:38 +01002461 switch (node->nodetype) {
2462 case LYS_CONTAINER:
2463 case LYS_LEAF:
2464 case LYS_LEAFLIST:
2465 case LYS_LIST:
2466 case LYS_CHOICE:
2467 case LYS_ANYDATA:
2468 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002469 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002470 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002471 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002472 if (!(node->flags & LYS_CONFIG_MASK)) {
2473 /* get config flag from parent */
2474 if (node->parent) {
2475 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2476 } else {
2477 /* default config is true */
2478 node->flags |= LYS_CONFIG_W;
2479 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002480 }
2481 }
Pavol Vicanec598812016-11-30 14:13:38 +01002482 break;
2483 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002484 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002485 if (!(node->flags & LYS_CONFIG_MASK)) {
2486 /* get config flag from parent */
2487 if (node->parent) {
2488 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2489 } else {
2490 /* default config is true */
2491 node->flags |= LYS_CONFIG_W;
2492 }
2493 }
2494 }
2495 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002496 default:
2497 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002498 }
Pavol Vicanec598812016-11-30 14:13:38 +01002499
Radek Krejci7212e0a2017-03-08 15:58:22 +01002500 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002501}
2502
2503int
Pavol Vican9d50a772016-10-14 22:23:36 +02002504yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2505 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002506{
Pavol Vican974377b2016-03-23 00:38:53 +01002507 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002508 YY_BUFFER_STATE bp;
2509 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002510 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002511 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002512 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002513
Pavol Vican8e7110b2016-03-22 17:00:26 +01002514 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002515 yylex_init(&scanner);
2516 bp = yy_scan_buffer((char *)data, size, scanner);
2517 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002518 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002519 param.module = module;
2520 param.submodule = submodule;
2521 param.unres = unres;
2522 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002523 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002524 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002525 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002526 trg = (submodule) ? (struct lys_module *)submodule : module;
2527 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2528 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2529 trg->inc_size = 0;
2530 trg->imp_size = 0;
2531 }
PavolVican22e88682017-02-14 22:38:18 +01002532 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2533 }
2534 yy_delete_buffer(bp, scanner);
2535 yylex_destroy(scanner);
2536 return ret;
2537}
2538
2539int
2540yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2541 char *ext_name, struct lys_ext_instance_complex *ext)
2542{
2543 unsigned int size;
2544 YY_BUFFER_STATE bp;
2545 yyscan_t scanner = NULL;
2546 int ret = 0;
2547 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002548 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002549
PavolVicandb0e8172017-02-20 00:46:09 +01002550 if (!data) {
2551 return EXIT_SUCCESS;
2552 }
PavolVican22e88682017-02-14 22:38:18 +01002553 size = strlen(data) + 2;
2554 yylex_init(&scanner);
2555 bp = yy_scan_buffer((char *)data, size, scanner);
2556 yy_switch_to_buffer(bp, scanner);
2557 memset(&param, 0, sizeof param);
2558 param.module = module;
2559 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002560 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002561 param.actual_node = (void **)ext;
2562 param.data_node = (void **)ext_name;
2563 param.flags |= EXT_INSTANCE_SUBSTMT;
2564 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002565 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002566 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002567 } else {
2568 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002569 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002570 ret = -1;
2571 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002572 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002573 yy_delete_buffer(bp, scanner);
2574 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002575 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002576}
2577
2578struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002579yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002580{
2581
PavolVican9e81c6a2017-02-09 13:09:07 +01002582 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002583 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002584 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002585 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002586
2587 unres = calloc(1, sizeof *unres);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002588 LY_CHECK_ERR_GOTO(!unres, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002589
2590 module = calloc(1, sizeof *module);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002591 LY_CHECK_ERR_GOTO(!module, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002592
2593 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002594 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002595 module->type = 0;
2596 module->implemented = (implement ? 1 : 0);
2597
Radek Krejci9e757e02017-03-08 17:18:09 +01002598 /* add into the list of processed modules */
2599 if (lyp_check_circmod_add(module)) {
2600 goto error;
2601 }
2602
PavolVican9e81c6a2017-02-09 13:09:07 +01002603 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2604 if (ret == -1) {
Pavol Vican05810b62016-11-23 14:07:22 +01002605 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002606 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002607 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002608 assert(!unres->count);
2609 } else {
2610 if (yang_check_sub_module(module, unres, node)) {
2611 goto error;
2612 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002613
Michal Vasko7b460e52017-02-10 14:50:26 +01002614 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002615 goto error;
2616 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002617 }
2618
PavolVicanfe83b152017-02-19 03:19:29 +01002619 lyp_sort_revisions(module);
2620
Pavol Vican8e7110b2016-03-22 17:00:26 +01002621 if (revision) {
2622 /* check revision of the parsed model */
2623 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2624 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2625 module->name, module->rev[0].date, revision);
2626 goto error;
2627 }
2628 }
2629
PavolVican9e81c6a2017-02-09 13:09:07 +01002630 /* add into context if not already there */
2631 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002632 /* check correctness of includes */
2633 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002634 goto error;
2635 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002636
PavolVicanfd6f6952017-02-14 00:09:42 +01002637 /* remove our submodules from the parsed submodules list */
2638 lyp_del_includedup(module);
2639
2640
PavolVican6f000922017-02-10 12:56:59 +01002641 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002642 goto error;
2643 }
2644
PavolVican9e81c6a2017-02-09 13:09:07 +01002645 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002646 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002647 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002648
2649 if (module->deviation_size && !module->implemented) {
2650 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2651 /* deviations always causes target to be made implemented,
2652 * but augents and leafrefs not, so we have to apply them now */
2653 if (lys_set_implemented(module)) {
2654 goto error;
2655 }
2656 }
2657 } else {
2658 tmp_mod = module;
2659
2660 /* get the model from the context */
Radek Krejcidfb00d62017-09-06 09:39:35 +02002661 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision, 0);
PavolVican9e81c6a2017-02-09 13:09:07 +01002662 assert(module);
2663
2664 /* free what was parsed */
2665 lys_free(tmp_mod, NULL, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002666 }
2667
Michal Vasko44ab1462017-05-18 13:18:36 +02002668 unres_schema_free(NULL, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002669 lyp_check_circmod_pop(ctx);
Michal Vaskobe136f62017-09-21 12:08:39 +02002670 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2671 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002672 return module;
2673
2674error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002675 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002676 unres_schema_free(module, &unres, 1);
Radek Krejcif505cd12017-06-13 10:32:48 +02002677 if (!module) {
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002678 if (ly_vecode != LYVE_SUBMODULE) {
2679 LOGERR(ly_errno, "Module parsing failed.");
2680 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002681 return NULL;
2682 }
2683
Radek Krejcif505cd12017-06-13 10:32:48 +02002684 if (module->name) {
2685 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
2686 } else {
2687 LOGERR(ly_errno, "Module parsing failed.");
2688 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002689
Radek Krejci9e757e02017-03-08 17:18:09 +01002690 lyp_check_circmod_pop(ctx);
Michal Vaskocf0489e2017-02-13 11:57:45 +01002691 lyp_del_includedup(module);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002692 lys_sub_module_remove_devs_augs(module);
2693 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002694 return NULL;
2695}
2696
2697struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002698yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002699{
2700 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002701 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002702
2703 submodule = calloc(1, sizeof *submodule);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002704 LY_CHECK_ERR_GOTO(!submodule, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002705
2706 submodule->ctx = module->ctx;
2707 submodule->type = 1;
Radek Krejci29eac3d2017-06-01 16:50:02 +02002708 submodule->implemented = module->implemented;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002709 submodule->belongsto = module;
2710
Radek Krejci9e757e02017-03-08 17:18:09 +01002711 /* add into the list of processed modules */
2712 if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2713 goto error;
2714 }
2715
PavolVican9e81c6a2017-02-09 13:09:07 +01002716 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002717 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002718 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002719 goto error;
2720 }
2721
PavolVicanfe83b152017-02-19 03:19:29 +01002722 lyp_sort_revisions((struct lys_module *)submodule);
2723
Pavol Vican7313fc02016-11-14 01:10:31 +01002724 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002725 goto error;
2726 }
2727
Radek Krejci9e757e02017-03-08 17:18:09 +01002728 lyp_check_circmod_pop(module->ctx);
2729
Pavol Vican8e7110b2016-03-22 17:00:26 +01002730 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002731 return submodule;
2732
2733error:
2734 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002735 unres_schema_free((struct lys_module *)submodule, &unres, 0);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002736
2737 if (!submodule || !submodule->name) {
2738 free(submodule);
2739 LOGERR(ly_errno, "Submodule parsing failed.");
2740 return NULL;
2741 }
2742
2743 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2744
Radek Krejci9e757e02017-03-08 17:18:09 +01002745 lyp_check_circmod_pop(module->ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002746 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2747 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002748 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002749 return NULL;
2750}
Pavol Vican8760bb72016-04-07 09:44:01 +02002751
2752static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002753read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2754{
2755 int k = 0, j;
2756
2757 while (in_index < size) {
2758 if (input[in_index] == ' ') {
2759 k++;
2760 } else if (input[in_index] == '\t') {
2761 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2762 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002763 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2764 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2765 k += 8;
2766 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002767 } else {
2768 break;
2769 }
2770 ++in_index;
2771 if (k >= indent) {
2772 for (j = k - indent; j > 0; --j) {
2773 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002774 if (j > 1) {
2775 ++(*out_index);
2776 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002777 }
2778 break;
2779 }
2780 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002781 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002782}
2783
2784char *
PavolVican1bc22062017-01-19 15:09:04 +01002785yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002786 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002787
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002788 while (i < size) {
2789 switch (input[i]) {
2790 case '\n':
2791 out_index -= space;
2792 output[out_index] = '\n';
2793 space = 0;
2794 i = read_indent(input, indent, size, i + 1, &out_index, output);
2795 break;
2796 case ' ':
2797 case '\t':
2798 output[out_index] = input[i];
2799 ++space;
2800 break;
2801 case '\\':
2802 if (input[i + 1] == 'n') {
2803 out_index -= space;
2804 output[out_index] = '\n';
2805 space = 0;
2806 i = read_indent(input, indent, size, i + 2, &out_index, output);
2807 } else if (input[i + 1] == 't') {
2808 output[out_index] = '\t';
2809 ++i;
2810 ++space;
2811 } else if (input[i + 1] == '\\') {
2812 output[out_index] = '\\';
2813 ++i;
2814 } else if ((i + 1) != size && input[i + 1] == '"') {
2815 output[out_index] = '"';
2816 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002817 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002818 /* backslash must not be followed by any other character */
2819 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2820 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002821 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002822 break;
2823 default:
2824 output[out_index] = input[i];
2825 space = 0;
2826 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002827 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002828 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002829 ++out_index;
2830 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002831 output[out_index] = '\0';
2832 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002833 output = realloc(output, out_index + 1);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002834 LY_CHECK_ERR_RETURN(!output, LOGMEM, NULL);
Pavol Vican8760bb72016-04-07 09:44:01 +02002835 }
Pavol Vican3f598892016-09-28 15:41:07 +02002836 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002837}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002838
2839/* free function */
2840
PavolVicana0fdbf32017-02-15 17:59:02 +01002841void
2842yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002843{
2844 struct yang_type *stype = (struct yang_type *)type->der;
Radek Krejcidce5f972017-09-12 15:47:49 +02002845 unsigned int i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002846
2847 if (!stype) {
2848 return ;
2849 }
PavolVicane87cb932016-12-30 15:36:18 +01002850 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2851 lydict_remove(ctx, stype->name);
2852 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2853 for (i = 0; i < type->info.ident.count; ++i) {
2854 free(type->info.ident.ref[i]);
2855 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002856 }
PavolVicane87cb932016-12-30 15:36:18 +01002857 if (stype->base == LY_TYPE_UNION) {
2858 for (i = 0; i < type->info.uni.count; ++i) {
2859 yang_type_free(ctx, &type->info.uni.types[i]);
2860 }
2861 free(type->info.uni.types);
2862 type->base = LY_TYPE_DER;
2863 } else {
2864 type->base = stype->base;
2865 }
2866 free(stype);
2867 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002868 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02002869 lys_type_free(ctx, type, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002870 type->base = LY_TYPE_DER;
PavolVican575a9342017-02-15 18:14:39 +01002871 type->ext_size = 0;
2872 type->ext = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002873}
2874
2875static void
Radek Krejcia2ac9262017-09-12 16:39:04 +02002876yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint16_t start, uint16_t size)
Pavol Vican7313fc02016-11-14 01:10:31 +01002877{
2878 uint8_t i;
2879
2880 assert(ctx);
2881 if (!tpdf) {
2882 return;
2883 }
2884
2885 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002886 lydict_remove(ctx, tpdf[i].name);
2887 lydict_remove(ctx, tpdf[i].dsc);
2888 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002889
Pavol Vicancee10802016-11-22 15:48:35 +01002890 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002891
Pavol Vicancee10802016-11-22 15:48:35 +01002892 lydict_remove(ctx, tpdf[i].units);
2893 lydict_remove(ctx, tpdf[i].dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002894 lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
Pavol Vican7313fc02016-11-14 01:10:31 +01002895 }
2896}
2897
Pavol Vican1cc4e192016-10-24 16:38:31 +02002898static void
2899yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2900{
2901 uint8_t i;
2902
2903 for (i = start; i < size; ++i){
2904 free((char *)imp[i].module);
2905 lydict_remove(ctx, imp[i].prefix);
2906 lydict_remove(ctx, imp[i].dsc);
2907 lydict_remove(ctx, imp[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002908 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002909 }
2910}
2911
Pavol Vicanec423c92016-10-24 21:33:43 +02002912static void
2913yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2914{
2915 uint8_t i;
2916
2917 for (i = start; i < size; ++i){
2918 free((char *)inc[i].submodule);
2919 lydict_remove(ctx, inc[i].dsc);
2920 lydict_remove(ctx, inc[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002921 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
Pavol Vicanec423c92016-10-24 21:33:43 +02002922 }
2923}
2924
Pavol Vican36e27272016-11-22 15:47:28 +01002925static void
2926yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2927{
2928 uint32_t i;
2929 uint8_t j;
2930
2931 /* free base name */
2932 for (i = start; i < size; ++i) {
2933 for (j = 0; j < ident[i].base_size; ++j) {
2934 free(ident[i].base[j]);
2935 }
2936 }
2937}
2938
Pavol Vican05810b62016-11-23 14:07:22 +01002939static void
2940yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2941{
2942 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2943 free(grp->tpdf);
2944}
2945
2946static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002947yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2948{
2949 uint8_t i;
2950
2951 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2952 free(cont->tpdf);
2953 lydict_remove(ctx, cont->presence);
2954
Pavol Vicanfda8c802016-12-03 02:00:42 +01002955 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002956 lys_restr_free(ctx, &cont->must[i], NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002957 }
2958 free(cont->must);
2959
Radek Krejci5138e9f2017-04-12 13:10:46 +02002960 lys_when_free(ctx, cont->when, NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002961}
2962
2963static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002964yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2965{
2966 uint8_t i;
2967
2968 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002969 lys_restr_free(ctx, &leaf->must[i], NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002970 }
2971 free(leaf->must);
2972
Radek Krejci5138e9f2017-04-12 13:10:46 +02002973 lys_when_free(ctx, leaf->when, NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002974
2975 yang_type_free(ctx, &leaf->type);
2976 lydict_remove(ctx, leaf->units);
2977 lydict_remove(ctx, leaf->dflt);
2978}
2979
2980static void
Pavol Vican36aff862016-11-26 17:07:05 +01002981yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2982{
2983 uint8_t i;
2984
2985 for (i = 0; i < leaflist->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002986 lys_restr_free(ctx, &leaflist->must[i], NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002987 }
2988 free(leaflist->must);
2989
2990 for (i = 0; i < leaflist->dflt_size; i++) {
2991 lydict_remove(ctx, leaflist->dflt[i]);
2992 }
2993 free(leaflist->dflt);
2994
Radek Krejci5138e9f2017-04-12 13:10:46 +02002995 lys_when_free(ctx, leaflist->when, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002996
2997 yang_type_free(ctx, &leaflist->type);
2998 lydict_remove(ctx, leaflist->units);
2999}
3000
3001static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003002yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3003{
3004 uint8_t i;
3005
3006 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3007 free(list->tpdf);
3008
3009 for (i = 0; i < list->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003010 lys_restr_free(ctx, &list->must[i], NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003011 }
3012 free(list->must);
3013
Radek Krejci5138e9f2017-04-12 13:10:46 +02003014 lys_when_free(ctx, list->when, NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003015
3016 for (i = 0; i < list->unique_size; ++i) {
3017 free(list->unique[i].expr);
3018 }
3019 free(list->unique);
3020
3021 free(list->keys);
3022}
3023
3024static void
Pavol Vican36ace102016-11-28 11:46:59 +01003025yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3026{
3027 free(choice->dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003028 lys_when_free(ctx, choice->when, NULL);
Pavol Vican36ace102016-11-28 11:46:59 +01003029}
3030
3031static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003032yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3033{
3034 uint8_t i;
3035
3036 for (i = 0; i < anydata->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003037 lys_restr_free(ctx, &anydata->must[i], NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003038 }
3039 free(anydata->must);
3040
Radek Krejci5138e9f2017-04-12 13:10:46 +02003041 lys_when_free(ctx, anydata->when, NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003042}
3043
3044static void
Pavol Vican78729392016-11-28 17:18:22 +01003045yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3046{
3047 uint8_t i;
3048
3049 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3050 free(inout->tpdf);
3051
3052 for (i = 0; i < inout->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003053 lys_restr_free(ctx, &inout->must[i], NULL);
Pavol Vican78729392016-11-28 17:18:22 +01003054 }
3055 free(inout->must);
3056}
3057
3058static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003059yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3060{
3061 uint8_t i;
3062
3063 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3064 free(notif->tpdf);
3065
3066 for (i = 0; i < notif->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003067 lys_restr_free(ctx, &notif->must[i], NULL);
Pavol Vican29bf8802016-11-28 20:44:57 +01003068 }
3069 free(notif->must);
3070}
3071
3072static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003073yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3074{
3075 int i, j;
3076
3077 for (i = 0; i < uses->refine_size; i++) {
3078 lydict_remove(ctx, uses->refine[i].target_name);
3079 lydict_remove(ctx, uses->refine[i].dsc);
3080 lydict_remove(ctx, uses->refine[i].ref);
3081
3082 for (j = 0; j < uses->refine[i].must_size; j++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003083 lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003084 }
3085 free(uses->refine[i].must);
3086
3087 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3088 lydict_remove(ctx, uses->refine[i].dflt[j]);
3089 }
3090 free(uses->refine[i].dflt);
3091
3092 if (uses->refine[i].target_type & LYS_CONTAINER) {
3093 lydict_remove(ctx, uses->refine[i].mod.presence);
3094 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003095 lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003096 }
3097 free(uses->refine);
3098
Radek Krejci5138e9f2017-04-12 13:10:46 +02003099 lys_when_free(ctx, uses->when, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003100}
3101
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003102static void
Pavol Vican05810b62016-11-23 14:07:22 +01003103yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3104{
3105 struct lys_node *tmp, *child, *sibling;
3106
3107 if (!node) {
3108 return;
3109 }
3110 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003111
3112 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003113 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003114 sibling = tmp->next;
3115 /* common part */
3116 lydict_remove(ctx, tmp->name);
3117 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003118 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003119 lydict_remove(ctx, tmp->dsc);
3120 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003121 }
3122
3123 switch (tmp->nodetype) {
3124 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003125 case LYS_RPC:
3126 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003127 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3128 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003129 case LYS_CONTAINER:
3130 yang_free_container(ctx, (struct lys_node_container *)tmp);
3131 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003132 case LYS_LEAF:
3133 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3134 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003135 case LYS_LEAFLIST:
3136 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3137 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003138 case LYS_LIST:
3139 yang_free_list(ctx, (struct lys_node_list *)tmp);
3140 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003141 case LYS_CHOICE:
3142 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3143 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003144 case LYS_CASE:
Radek Krejci5138e9f2017-04-12 13:10:46 +02003145 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
Pavol Vicana420bac2016-11-28 14:51:54 +01003146 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003147 case LYS_ANYXML:
3148 case LYS_ANYDATA:
3149 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3150 break;
Pavol Vican78729392016-11-28 17:18:22 +01003151 case LYS_INPUT:
3152 case LYS_OUTPUT:
3153 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3154 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003155 case LYS_NOTIF:
3156 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3157 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003158 case LYS_USES:
3159 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3160 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003161 default:
3162 break;
3163 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003164 lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
Pavol Vican05810b62016-11-23 14:07:22 +01003165 yang_free_nodes(ctx, child);
3166 free(tmp);
3167 tmp = sibling;
3168 }
3169}
3170
Pavol Vican3ad50f82016-12-04 15:00:36 +01003171static void
3172yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3173{
3174 lydict_remove(ctx, aug->target_name);
3175 lydict_remove(ctx, aug->dsc);
3176 lydict_remove(ctx, aug->ref);
3177
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003178 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003179 lys_when_free(ctx, aug->when, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003180 yang_free_nodes(ctx, aug->child);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003181 lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003182}
3183
PavolVican75af21d2016-12-29 20:04:07 +01003184static void
3185yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3186{
3187 uint i, j;
3188
3189 for (i = index; i < dev->deviate_size; ++i) {
3190 lydict_remove(ctx, dev->deviate[i].units);
3191
3192 if (dev->deviate[i].type) {
3193 yang_type_free(ctx, dev->deviate[i].type);
3194 }
3195
3196 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3197 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3198 }
3199 free(dev->deviate[i].dflt);
3200
3201 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003202 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003203 }
3204 free(dev->deviate[i].must);
3205
3206 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3207 free(dev->deviate[i].unique[j].expr);
3208 }
3209 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003210 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003211 }
3212}
3213
PavolVicandb0e8172017-02-20 00:46:09 +01003214void
3215yang_free_ext_data(struct yang_ext_substmt *substmt)
3216{
3217 int i;
3218
3219 if (!substmt) {
3220 return;
3221 }
3222
3223 free(substmt->ext_substmt);
3224 if (substmt->ext_modules) {
3225 for (i = 0; substmt->ext_modules[i]; ++i) {
3226 free(substmt->ext_modules[i]);
3227 }
3228 free(substmt->ext_modules);
3229 }
3230 free(substmt);
3231}
3232
Pavol Vican7313fc02016-11-14 01:10:31 +01003233/* free common item from module and submodule */
3234static void
Pavol Vican05810b62016-11-23 14:07:22 +01003235free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003236{
PavolVican75af21d2016-12-29 20:04:07 +01003237 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003238 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3239 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003240 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003241 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003242 for (i = 0; i < module->augment_size; ++i) {
3243 yang_free_augment(module->ctx, &module->augment[i]);
3244 }
3245 module->augment_size = 0;
3246 for (i = 0; i < module->deviation_size; ++i) {
3247 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3248 free(module->deviation[i].deviate);
3249 }
3250 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003251}
3252
Pavol Vican1cc4e192016-10-24 16:38:31 +02003253/* check function*/
3254
3255int
PavolVicanc1807262017-01-31 18:00:27 +01003256yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3257 void *parent, struct unres_schema *unres)
3258{
3259 struct unres_ext *info;
3260 uint i;
3261
3262 for (i = 0; i < size; ++i) {
3263 info = malloc(sizeof *info);
Radek Krejcia8d111f2017-05-31 13:57:37 +02003264 LY_CHECK_ERR_RETURN(!info, LOGMEM, EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003265 info->data.yang = (*ext)[i]->parent;
3266 info->datatype = LYS_IN_YANG;
3267 info->parent = parent;
3268 info->mod = module;
3269 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003270 info->substmt = (*ext)[i]->insubstmt;
3271 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003272 info->ext_index = i;
3273 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3274 return EXIT_FAILURE;
3275 }
3276 }
3277
3278 return EXIT_SUCCESS;
3279}
3280
3281int
Pavol Vicanec423c92016-10-24 21:33:43 +02003282yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003283{
3284 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003285 struct lys_include *inc;
3286 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003287 char *s;
3288
3289 imp = module->imp;
3290 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003291 inc = module->inc;
3292 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003293
3294 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003295 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003296 module->imp_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003297 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM, error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003298 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003299
Pavol Vicanec423c92016-10-24 21:33:43 +02003300 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003301 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003302 module->inc_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003303 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM, error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003304 }
3305
3306 for (i = 0; i < imp_size; ++i) {
3307 s = (char *) imp[i].module;
3308 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003309 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003310 ++i;
3311 goto error;
3312 }
3313 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003314 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003315 s = (char *) inc[j].submodule;
3316 inc[j].submodule = NULL;
3317 if (yang_fill_include(module, s, &inc[j], unres)) {
3318 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003319 goto error;
3320 }
3321 }
3322 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003323 free(imp);
3324
3325 return EXIT_SUCCESS;
3326
3327error:
3328 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003329 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003330 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003331 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003332 return EXIT_FAILURE;
3333}
Pavol Vican7313fc02016-11-14 01:10:31 +01003334
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003335static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003336yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003337{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003338 struct lys_iffeature *iffeature;
3339 uint8_t *ptr_size, size, i;
3340 char *s;
3341 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003342
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003343 switch (type) {
3344 case FEATURE_KEYWORD:
3345 iffeature = ((struct lys_feature *)parent)->iffeature;
3346 size = ((struct lys_feature *)parent)->iffeature_size;
3347 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3348 parent_is_feature = 1;
3349 break;
3350 case IDENTITY_KEYWORD:
3351 iffeature = ((struct lys_ident *)parent)->iffeature;
3352 size = ((struct lys_ident *)parent)->iffeature_size;
3353 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3354 break;
3355 case ENUM_KEYWORD:
3356 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3357 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3358 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3359 break;
3360 case BIT_KEYWORD:
3361 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3362 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3363 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3364 break;
3365 case REFINE_KEYWORD:
3366 iffeature = ((struct lys_refine *)ptr)->iffeature;
3367 size = ((struct lys_refine *)ptr)->iffeature_size;
3368 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3369 break;
3370 default:
3371 iffeature = ((struct lys_node *)parent)->iffeature;
3372 size = ((struct lys_node *)parent)->iffeature_size;
3373 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3374 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003375 }
3376
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003377 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003378 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003379 s = (char *)iffeature[i].features;
3380 iffeature[i].features = NULL;
3381 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3382 *ptr_size = size;
3383 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003384 }
PavolVican8fa31242017-02-07 11:04:26 +01003385 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3386 *ptr_size = size;
3387 return EXIT_FAILURE;
3388 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003389 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003390 }
3391
3392 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003393}
3394
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003395static int
3396yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3397{
3398 uint size, i;
3399 int rc;
3400 struct lys_ident **ref;
3401 const char *value;
3402 char *expr;
3403
3404 ref = type->info.ident.ref;
3405 size = type->info.ident.count;
3406 type->info.ident.count = 0;
3407 type->info.ident.ref = NULL;
3408 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3409
3410 for (i = 0; i < size; ++i) {
3411 expr = (char *)ref[i];
3412 /* store in the JSON format */
3413 value = transform_schema2json(module, expr);
3414 free(expr);
3415
3416 if (!value) {
3417 goto error;
3418 }
3419 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3420 lydict_remove(module->ctx, value);
3421
3422 if (rc == -1) {
3423 goto error;
3424 }
3425 }
3426 free(ref);
3427
3428 return EXIT_SUCCESS;
3429error:
3430 for (i = i+1; i < size; ++i) {
3431 free(ref[i]);
3432 }
3433 free(ref);
3434 return EXIT_FAILURE;
3435}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003436
Pavol Vican7313fc02016-11-14 01:10:31 +01003437int
PavolVican056fcd12017-02-07 15:36:53 +01003438yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3439 void *parent, struct unres_schema *unres)
3440{
Radek Krejcidce5f972017-09-12 15:47:49 +02003441 unsigned int i;
PavolVican056fcd12017-02-07 15:36:53 +01003442
3443 type->parent = parent;
3444 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3445 return EXIT_FAILURE;
3446 }
3447 switch (stype->base) {
3448 case LY_TYPE_ENUM:
3449 for (i = 0; i < type->info.enums.count; ++i) {
3450 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3451 return EXIT_FAILURE;
3452 }
3453 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3454 &type->info.enums.enm[i], unres)) {
3455 return EXIT_FAILURE;
3456 }
3457 }
3458 break;
3459 case LY_TYPE_BITS:
3460 for (i = 0; i < type->info.bits.count; ++i) {
3461 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3462 return EXIT_FAILURE;
3463 }
3464 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3465 &type->info.bits.bit[i], unres)) {
3466 return EXIT_FAILURE;
3467 }
3468 }
3469 break;
3470 case LY_TYPE_IDENT:
3471 if (yang_check_identityref(module, type, unres)) {
3472 return EXIT_FAILURE;
3473 }
3474 break;
3475 case LY_TYPE_STRING:
3476 if (type->info.str.length && yang_check_ext_instance(module, &type->info.str.length->ext,
3477 type->info.str.length->ext_size, type->info.str.length, unres)) {
3478 return EXIT_FAILURE;
3479 }
3480 for (i = 0; i < type->info.str.pat_count; ++i) {
3481 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3482 &type->info.str.patterns[i], unres)) {
3483 return EXIT_FAILURE;
3484 }
3485 }
3486 break;
3487 case LY_TYPE_DEC64:
3488 if (type->info.dec64.range && yang_check_ext_instance(module, &type->info.dec64.range->ext,
3489 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3490 return EXIT_FAILURE;
3491 }
3492 break;
3493 case LY_TYPE_UNION:
3494 for (i = 0; i < type->info.uni.count; ++i) {
3495 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3496 parent, unres)) {
3497 return EXIT_FAILURE;
3498 }
3499 }
Radek Krejci57b41682017-03-07 12:33:24 +01003500 break;
PavolVican056fcd12017-02-07 15:36:53 +01003501 default:
3502 /* nothing checks */
3503 break;
3504 }
3505 return EXIT_SUCCESS;
3506}
3507
3508int
Pavol Vican7313fc02016-11-14 01:10:31 +01003509yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3510{
3511 struct lys_tpdf *tpdf;
Radek Krejcidaa547a2017-09-22 15:56:27 +02003512 uint8_t *ptr_tpdf_size = NULL;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003513 uint16_t i, tpdf_size, *ptr_tpdf_size16 = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01003514
3515 if (!parent) {
3516 tpdf = module->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003517 //ptr_tpdf_size = &module->tpdf_size;
3518 ptr_tpdf_size16 = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003519 } else {
3520 switch (parent->nodetype) {
3521 case LYS_GROUPING:
3522 tpdf = ((struct lys_node_grp *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003523 ptr_tpdf_size16 = &((struct lys_node_grp *)parent)->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003524 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003525 case LYS_CONTAINER:
3526 tpdf = ((struct lys_node_container *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003527 ptr_tpdf_size16 = &((struct lys_node_container *)parent)->tpdf_size;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003528 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003529 case LYS_LIST:
3530 tpdf = ((struct lys_node_list *)parent)->tpdf;
3531 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3532 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003533 case LYS_RPC:
3534 case LYS_ACTION:
3535 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003536 ptr_tpdf_size16 = &((struct lys_node_rpc_action *)parent)->tpdf_size;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003537 break;
Pavol Vican78729392016-11-28 17:18:22 +01003538 case LYS_INPUT:
3539 case LYS_OUTPUT:
3540 tpdf = ((struct lys_node_inout *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003541 ptr_tpdf_size16 = &((struct lys_node_inout *)parent)->tpdf_size;
Pavol Vican78729392016-11-28 17:18:22 +01003542 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003543 case LYS_NOTIF:
3544 tpdf = ((struct lys_node_notif *)parent)->tpdf;
Radek Krejcia2ac9262017-09-12 16:39:04 +02003545 ptr_tpdf_size16 = &((struct lys_node_notif *)parent)->tpdf_size;
Pavol Vican29bf8802016-11-28 20:44:57 +01003546 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003547 default:
3548 LOGINT;
3549 return EXIT_FAILURE;
3550 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003551 }
3552
Radek Krejcia2ac9262017-09-12 16:39:04 +02003553 if (ptr_tpdf_size16) {
3554 tpdf_size = *ptr_tpdf_size16;
3555 *ptr_tpdf_size16 = 0;
3556 } else {
3557 tpdf_size = *ptr_tpdf_size;
3558 *ptr_tpdf_size = 0;
3559 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003560
3561 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003562 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3563 goto error;
3564 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003565
PavolVican056fcd12017-02-07 15:36:53 +01003566 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3567 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003568 }
PavolVicandf9e7972017-02-07 11:41:38 +01003569 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3570 goto error;
3571 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003572 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003573 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003574 }
3575
Radek Krejcia2ac9262017-09-12 16:39:04 +02003576 if (ptr_tpdf_size16) {
3577 (*ptr_tpdf_size16)++;
3578 } else {
3579 (*ptr_tpdf_size)++;
3580 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003581 /* check default value*/
Michal Vasko15a43372017-09-25 14:12:42 +02003582 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)
3583 && 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 +01003584 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003585 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003586 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003587 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003588
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003589 return EXIT_SUCCESS;
3590
3591error:
3592 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3593 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003594}
3595
3596static int
Pavol Vican36e27272016-11-22 15:47:28 +01003597yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3598{
3599 uint32_t i, size, base_size;
3600 uint8_t j;
3601
3602 size = module->ident_size;
3603 module->ident_size = 0;
3604 for (i = 0; i < size; ++i) {
3605 base_size = module->ident[i].base_size;
3606 module->ident[i].base_size = 0;
3607 for (j = 0; j < base_size; ++j) {
3608 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3609 ++j;
3610 module->ident_size = size;
3611 goto error;
3612 }
3613 }
3614 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003615 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3616 goto error;
3617 }
PavolVican8fa31242017-02-07 11:04:26 +01003618 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3619 goto error;
3620 }
Pavol Vican36e27272016-11-22 15:47:28 +01003621 }
3622
PavolVican8fa31242017-02-07 11:04:26 +01003623
Pavol Vican36e27272016-11-22 15:47:28 +01003624 return EXIT_SUCCESS;
3625
3626error:
3627 for (; j< module->ident[i].base_size; ++j) {
3628 free(module->ident[i].base[j]);
3629 }
3630 yang_free_ident_base(module->ident, i + 1, size);
3631 return EXIT_FAILURE;
3632}
3633
3634static int
PavolVican38104a32017-02-08 12:25:23 +01003635yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3636{
3637 uint i;
3638
3639 for (i = 0; i < size; ++i) {
3640 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3641 return EXIT_FAILURE;
3642 }
3643 }
3644 return EXIT_SUCCESS;
3645}
3646
3647static int
PavolVicane87cb932016-12-30 15:36:18 +01003648yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003649 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003650{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003651 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003652 goto error;
3653 }
3654
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003655 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003656 goto error;
3657 }
3658
Radek Krejci7212e0a2017-03-08 15:58:22 +01003659 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003660 *child = NULL;
3661 goto error;
3662 }
3663 *child = NULL;
3664
PavolVican59ba4602017-02-08 11:53:32 +01003665 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3666 goto error;
3667 }
PavolVican38104a32017-02-08 12:25:23 +01003668 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3669 goto error;
3670 }
3671
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003672 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003673 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (cont->when || cont->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003674 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003675 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003676 goto error;
3677 }
3678 } else {
3679 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3680 goto error;
3681 }
3682 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003683 }
3684
3685 return EXIT_SUCCESS;
3686error:
3687 return EXIT_FAILURE;
3688}
3689
3690static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003691yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003692{
PavolVican056fcd12017-02-07 15:36:53 +01003693 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003694 yang_type_free(module->ctx, &leaf->type);
3695 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003696 }
PavolVicana08d3652016-12-29 21:07:47 +01003697 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3698 yang_type_free(module->ctx, &leaf->type);
3699 goto error;
3700 }
3701
Pavol Vicanfda8c802016-12-03 02:00:42 +01003702 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003703 yang_type_free(module->ctx, &leaf->type);
3704 goto error;
3705 }
3706
Michal Vasko15a43372017-09-25 14:12:42 +02003707 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003708 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003709 goto error;
3710 }
3711
PavolVican59ba4602017-02-08 11:53:32 +01003712 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3713 goto error;
3714 }
PavolVican38104a32017-02-08 12:25:23 +01003715 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3716 goto error;
3717 }
Michal Vasko89afc112017-03-16 13:57:28 +01003718
Pavol Vicana69aff22016-11-24 18:23:50 +01003719 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003720 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaf->when || leaf->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003721 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003722 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003723 goto error;
3724 }
3725 } else {
3726 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3727 goto error;
3728 }
3729 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003730 }
3731
3732 return EXIT_SUCCESS;
3733error:
3734 return EXIT_FAILURE;
3735}
3736
3737static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003738yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3739 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003740{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003741 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003742
PavolVican056fcd12017-02-07 15:36:53 +01003743 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003744 yang_type_free(module->ctx, &leaflist->type);
3745 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003746 }
PavolVicana08d3652016-12-29 21:07:47 +01003747 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3748 yang_type_free(module->ctx, &leaflist->type);
3749 goto error;
3750 }
3751
Pavol Vicanfda8c802016-12-03 02:00:42 +01003752 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003753 yang_type_free(module->ctx, &leaflist->type);
3754 goto error;
3755 }
3756
Pavol Vican36aff862016-11-26 17:07:05 +01003757 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003758 /* check for duplicity in case of configuration data,
3759 * in case of status data duplicities are allowed */
3760 if (leaflist->flags & LYS_CONFIG_W) {
3761 for (j = i +1; j < leaflist->dflt_size; ++j) {
3762 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003763 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3764 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003765 goto error;
3766 }
3767 }
3768 }
3769 /* check default value (if not defined, there still could be some restrictions
3770 * that need to be checked against a default value from a derived type) */
Michal Vasko15a43372017-09-25 14:12:42 +02003771 if (!(options & LYS_PARSE_OPT_INGRP) && !(module->ctx->models.flags & LY_CTX_TRUSTED) &&
Radek Krejciab08f0f2017-03-09 16:37:15 +01003772 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3773 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003774 goto error;
3775 }
3776 }
3777
PavolVican59ba4602017-02-08 11:53:32 +01003778 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3779 goto error;
3780 }
PavolVican38104a32017-02-08 12:25:23 +01003781 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3782 goto error;
3783 }
PavolVican59ba4602017-02-08 11:53:32 +01003784
Pavol Vican36aff862016-11-26 17:07:05 +01003785 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003786 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (leaflist->when || leaflist->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003787 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003788 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003789 goto error;
3790 }
3791 } else {
3792 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3793 goto error;
3794 }
3795 }
Pavol Vican36aff862016-11-26 17:07:05 +01003796 }
3797
3798 return EXIT_SUCCESS;
3799error:
3800 return EXIT_FAILURE;
3801}
3802
3803static int
PavolVicane87cb932016-12-30 15:36:18 +01003804yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003805 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003806{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003807 struct lys_node *node;
3808
Pavol Vicand8136a42016-11-27 13:28:04 +01003809 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3810 goto error;
3811 }
3812
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003813 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3814 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003815 }
3816
Pavol Vicanfda8c802016-12-03 02:00:42 +01003817 if (list->flags & LYS_CONFIG_R) {
3818 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3819 * ignore oredering MASK - 0x7F
3820 */
3821 list->flags &= 0x7F;
3822 }
3823 /* check - if list is configuration, key statement is mandatory
3824 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003825 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 +01003826 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3827 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3828 goto error;
3829 }
3830
Radek Krejci7212e0a2017-03-08 15:58:22 +01003831 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003832 *child = NULL;
3833 goto error;
3834 }
3835 *child = NULL;
3836
Pavol Vicand8136a42016-11-27 13:28:04 +01003837 if (list->keys && yang_read_key(module, list, unres)) {
3838 goto error;
3839 }
3840
3841 if (yang_read_unique(module, list, unres)) {
3842 goto error;
3843 }
3844
PavolVican59ba4602017-02-08 11:53:32 +01003845 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3846 goto error;
3847 }
PavolVican38104a32017-02-08 12:25:23 +01003848 if (yang_check_must(module, list->must, list->must_size, unres)) {
3849 goto error;
3850 }
Michal Vasko89afc112017-03-16 13:57:28 +01003851
Pavol Vicand8136a42016-11-27 13:28:04 +01003852 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003853 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (list->when || list->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003854 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003855 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003856 goto error;
3857 }
3858 } else {
3859 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3860 goto error;
3861 }
3862 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003863 }
3864
3865 return EXIT_SUCCESS;
3866error:
3867 return EXIT_FAILURE;
3868}
3869
3870static int
PavolVicane87cb932016-12-30 15:36:18 +01003871yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003872 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003873{
3874 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003875
PavolVicana08d3652016-12-29 21:07:47 +01003876 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3877 free(choice->dflt);
3878 choice->dflt = NULL;
3879 goto error;
3880 }
3881
Radek Krejci7212e0a2017-03-08 15:58:22 +01003882 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003883 *child = NULL;
3884 free(choice->dflt);
3885 choice->dflt = NULL;
3886 goto error;
3887 }
3888 *child = NULL;
3889
Pavol Vican36ace102016-11-28 11:46:59 +01003890 if (choice->dflt) {
3891 value = (char *)choice->dflt;
3892 choice->dflt = NULL;
3893 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3894 free(value);
3895 goto error;
3896 }
3897 free(value);
3898 }
3899
PavolVican59ba4602017-02-08 11:53:32 +01003900 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3901 goto error;
3902 }
3903
Pavol Vican36ace102016-11-28 11:46:59 +01003904 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003905 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && choice->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01003906 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003907 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003908 goto error;
3909 }
3910 } else {
3911 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3912 goto error;
3913 }
3914 }
Pavol Vican36ace102016-11-28 11:46:59 +01003915 }
3916
3917 return EXIT_SUCCESS;
3918error:
3919 return EXIT_FAILURE;
3920}
3921
3922static int
PavolVicane87cb932016-12-30 15:36:18 +01003923yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003924 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003925{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003926 struct lys_node *node;
3927
3928 if (rpc->nodetype == LYS_ACTION) {
3929 for (node = rpc->parent; node; node = lys_parent(node)) {
3930 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003931 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003932 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003933 goto error;
3934 }
3935 }
3936 }
3937 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3938 goto error;
3939 }
3940
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003941 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3942 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003943 }
3944
Radek Krejci7212e0a2017-03-08 15:58:22 +01003945 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003946 *child = NULL;
3947 goto error;
3948 }
3949 *child = NULL;
3950
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003951 return EXIT_SUCCESS;
3952error:
3953 return EXIT_FAILURE;
3954}
3955
3956static int
PavolVicane87cb932016-12-30 15:36:18 +01003957yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003958 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01003959{
Pavol Vican29bf8802016-11-28 20:44:57 +01003960 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3961 goto error;
3962 }
3963
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003964 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3965 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003966 }
3967
Radek Krejci7212e0a2017-03-08 15:58:22 +01003968 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003969 *child = NULL;
3970 goto error;
3971 }
3972 *child = NULL;
3973
Michal Vasko89afc112017-03-16 13:57:28 +01003974 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
3975 goto error;
3976 }
3977
3978 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02003979 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01003980 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003981 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003982 goto error;
3983 }
3984 } else {
3985 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
3986 goto error;
3987 }
PavolVican38104a32017-02-08 12:25:23 +01003988 }
Pavol Vican29bf8802016-11-28 20:44:57 +01003989 }
3990
3991 return EXIT_SUCCESS;
3992error:
3993 return EXIT_FAILURE;
3994}
3995
3996static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003997yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003998{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003999 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004000
Pavol Vican3ad50f82016-12-04 15:00:36 +01004001 child = augment->child;
4002 augment->child = NULL;
4003
PavolVicana08d3652016-12-29 21:07:47 +01004004 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
4005 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01004006 goto error;
4007 }
4008
Radek Krejci7212e0a2017-03-08 15:58:22 +01004009 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004010 goto error;
4011 }
4012
PavolVicanfa9510e2017-02-08 17:20:46 +01004013 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4014 goto error;
4015 }
4016
PavolVican59ba4602017-02-08 11:53:32 +01004017 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4018 goto error;
4019 }
4020
Pavol Vican3ad50f82016-12-04 15:00:36 +01004021 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004022 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && augment->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004023 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004024 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004025 goto error;
4026 }
4027 } else {
4028 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4029 goto error;
4030 }
4031 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004032 }
4033
4034 return EXIT_SUCCESS;
4035error:
4036 return EXIT_FAILURE;
4037}
4038
4039static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004040yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004041{
4042 uint i, size;
4043
4044 size = uses->augment_size;
4045 uses->augment_size = 0;
4046
4047 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004048 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004049 }
4050
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004051 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004052 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4053 goto error;
4054 }
4055 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4056 goto error;
4057 }
4058 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 +01004059 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004060 }
4061 }
4062
Pavol Vican3ad50f82016-12-04 15:00:36 +01004063 for (i = 0; i < size; ++i) {
4064 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004065 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004066 goto error;
4067 }
4068 }
4069
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004070 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4071 goto error;
4072 }
4073
PavolVican59ba4602017-02-08 11:53:32 +01004074 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4075 goto error;
4076 }
4077
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004078 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004079 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && uses->when) {
Michal Vasko89afc112017-03-16 13:57:28 +01004080 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004081 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004082 goto error;
4083 }
4084 } else {
4085 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4086 goto error;
4087 }
4088 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004089 }
4090
4091 return EXIT_SUCCESS;
4092error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004093 for (i = uses->augment_size; i < size; ++i) {
4094 yang_free_augment(module->ctx, &uses->augment[i]);
4095 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004096 return EXIT_FAILURE;
4097}
4098
4099static int
PavolVican59ba4602017-02-08 11:53:32 +01004100yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004101 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004102{
4103 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4104 goto error;
4105 }
4106
Radek Krejci7212e0a2017-03-08 15:58:22 +01004107 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004108 *child = NULL;
4109 goto error;
4110 }
4111 *child = NULL;
4112
4113 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4114 goto error;
4115 }
PavolVican38104a32017-02-08 12:25:23 +01004116 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4117 goto error;
4118 }
PavolVican59ba4602017-02-08 11:53:32 +01004119
4120 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004121 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (anydata->when || anydata->must_size)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004122 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004123 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004124 goto error;
4125 }
4126 } else {
4127 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4128 goto error;
4129 }
4130 }
PavolVican59ba4602017-02-08 11:53:32 +01004131 }
Michal Vasko89afc112017-03-16 13:57:28 +01004132
PavolVican59ba4602017-02-08 11:53:32 +01004133 return EXIT_SUCCESS;
4134error:
4135 return EXIT_FAILURE;
4136}
4137
4138static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004139yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004140 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004141{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004142 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01004143
4144 while (node) {
4145 sibling = node->next;
4146 child = node->child;
4147 node->next = NULL;
4148 node->child = NULL;
PavolVicanbd1d1ae2017-07-20 00:06:00 +02004149 node->parent = NULL;
Pavol Vican05810b62016-11-23 14:07:22 +01004150 node->prev = node;
4151
PavolVican05c4f9b2017-09-07 13:33:54 +02004152 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node) ||
4153 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004154 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004155 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004156 goto error;
4157 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004158 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004159 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4160 goto error;
4161 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004162
Pavol Vican05810b62016-11-23 14:07:22 +01004163 switch (node->nodetype) {
4164 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004165 if (yang_check_typedef(module, node, unres)) {
4166 goto error;
4167 }
4168 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004169 goto error;
4170 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004171 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004172 child = NULL;
4173 goto error;
4174 }
Pavol Vican05810b62016-11-23 14:07:22 +01004175 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004176 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004177 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004178 goto error;
4179 }
4180 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004181 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004182 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004183 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004184 goto error;
4185 }
4186 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004187 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004188 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004189 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004190 goto error;
4191 }
4192 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004193 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004194 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004195 goto error;
4196 }
4197 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004198 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004199 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004200 goto error;
4201 }
4202 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004203 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004204 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004205 goto error;
4206 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004207 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004208 child = NULL;
4209 goto error;
4210 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004211 if (((struct lys_node_case *)node)->when) {
4212 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4213 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4214 goto error;
4215 }
4216 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004217 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004218 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004219 goto error;
4220 }
4221 } else {
4222 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4223 goto error;
4224 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004225 }
4226 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004227 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004228 case LYS_ANYDATA:
4229 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004230 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004231 goto error;
4232 }
4233 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004234 case LYS_RPC:
4235 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004236 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004237 goto error;
4238 }
4239 break;
Pavol Vican78729392016-11-28 17:18:22 +01004240 case LYS_INPUT:
4241 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004242 if (yang_check_typedef(module, node, unres)) {
4243 goto error;
4244 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004245 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004246 child = NULL;
4247 goto error;
4248 }
PavolVican38104a32017-02-08 12:25:23 +01004249 if (((struct lys_node_inout *)node)->must_size) {
4250 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4251 goto error;
4252 }
4253 /* check XPath dependencies */
Michal Vasko15a43372017-09-25 14:12:42 +02004254 if (!(module->ctx->models.flags & LY_CTX_TRUSTED) && (options & LYS_PARSE_OPT_INGRP)) {
Michal Vasko364918a2017-03-17 13:23:46 +01004255 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004256 goto error;
4257 }
4258 } else {
4259 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4260 goto error;
4261 }
PavolVican38104a32017-02-08 12:25:23 +01004262 }
Pavol Vican78729392016-11-28 17:18:22 +01004263 }
Pavol Vican78729392016-11-28 17:18:22 +01004264 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004265 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004266 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004267 goto error;
4268 }
4269 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004270 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004271 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004272 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004273 goto error;
4274 }
4275 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004276 default:
4277 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01004278 goto error;
4279 }
Pavol Vican05810b62016-11-23 14:07:22 +01004280 node = sibling;
4281 }
4282
4283 return EXIT_SUCCESS;
4284error:
4285 yang_free_nodes(module->ctx, sibling);
4286 yang_free_nodes(module->ctx, child);
4287 return EXIT_FAILURE;
4288}
4289
4290static int
PavolVican75af21d2016-12-29 20:04:07 +01004291yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4292 struct lys_node *dev_target, struct ly_set *dflt_check)
4293{
4294 struct lys_node_leaflist *llist;
4295 struct lys_type *type;
4296 struct lys_tpdf *tmp_parent;
4297 int i, j;
4298
PavolVican6f000922017-02-10 12:56:59 +01004299 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4300 goto error;
4301 }
PavolVican75af21d2016-12-29 20:04:07 +01004302 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4303 goto error;
4304 }
4305 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4306 goto error;
4307 }
4308 if (deviate->dflt_size) {
4309 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4310 goto error;
4311 }
4312 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4313 /* consolidate the final list in the target after removing items from it */
4314 llist = (struct lys_node_leaflist *)dev_target;
4315 for (i = j = 0; j < llist->dflt_size; j++) {
4316 llist->dflt[i] = llist->dflt[j];
4317 if (llist->dflt[i]) {
4318 i++;
4319 }
4320 }
4321 llist->dflt_size = i + 1;
4322 }
4323 }
4324
4325 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4326 goto error;
4327 }
4328
4329 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4330 goto error;
4331 }
4332
4333 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4334 goto error;
4335 }
4336
4337 if ((deviate->flags & LYS_CONFIG_MASK)) {
4338 /* add and replace are the same in this case */
4339 /* remove current config value of the target ... */
4340 dev_target->flags &= ~LYS_CONFIG_MASK;
4341
4342 /* ... and replace it with the value specified in deviation */
4343 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4344 }
4345
4346 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4347 goto error;
4348 }
4349
4350 if (deviate->type) {
4351 /* check target node type */
4352 if (dev_target->nodetype == LYS_LEAF) {
4353 type = &((struct lys_node_leaf *)dev_target)->type;
4354 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4355 type = &((struct lys_node_leaflist *)dev_target)->type;
4356 } else {
4357 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4358 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
4359 goto error;
4360 }
4361 /* remove type and initialize it */
4362 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004363 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004364 memcpy(type, deviate->type, sizeof *deviate->type);
4365 free(deviate->type);
4366 deviate->type = type;
4367 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004368 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4369 goto error;
4370 }
4371
PavolVican75af21d2016-12-29 20:04:07 +01004372 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4373 goto error;
4374 }
4375 }
4376
4377 return EXIT_SUCCESS;
4378error:
4379 if (deviate->type) {
4380 yang_type_free(module->ctx, deviate->type);
4381 deviate->type = NULL;
4382 }
4383 return EXIT_FAILURE;
4384}
4385
4386static int
4387yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4388{
4389 int rc;
4390 uint i;
4391 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004392 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004393 unsigned int u;
4394 const char *value, *target_name;
4395 struct lys_node_leaflist *llist;
4396 struct lys_node_leaf *leaf;
4397 struct unres_schema tmp_unres;
4398 struct lys_module *mod;
4399
4400 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004401 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4402 if (rc == -1) {
PavolVican75af21d2016-12-29 20:04:07 +01004403 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004404 ly_set_free(set);
PavolVican75af21d2016-12-29 20:04:07 +01004405 goto error;
4406 }
Michal Vasko50576712017-07-28 12:28:33 +02004407 dev_target = set->set.s[0];
4408 ly_set_free(set);
4409
PavolVican75af21d2016-12-29 20:04:07 +01004410 if (dev_target->module == lys_main_module(module)) {
4411 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4412 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4413 goto error;
4414 }
4415
4416 if (!dflt_check) {
4417 LOGMEM;
4418 goto error;
4419 }
4420
4421 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4422 /* you cannot remove a key leaf */
4423 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4424 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4425 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4426 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4427 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
PavolVican4b80d042017-02-23 14:30:27 +01004428 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01004429 }
4430 }
4431 }
4432 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004433 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004434 lys_node_unlink(dev_target);
Radek Krejci9cf034c2017-08-24 17:10:35 +02004435 if (parent && parent->nodetype == LYS_AUGMENT) {
4436 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4437 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4438 * path), so we need to remember the augment as an addition */
4439 dev_target->parent = parent;
4440 }
PavolVican75af21d2016-12-29 20:04:07 +01004441 dev->orig_node = dev_target;
4442 } else {
4443 /* store a shallow copy of the original node */
4444 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004445 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004446 /* just to be safe */
4447 if (tmp_unres.count) {
4448 LOGINT;
4449 goto error;
4450 }
4451 }
4452
PavolVican6f000922017-02-10 12:56:59 +01004453 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
4454 goto error;
4455 }
4456
Michal Vasko15a43372017-09-25 14:12:42 +02004457 if (!(module->ctx->models.flags & LY_CTX_TRUSTED)) {
4458 for (i = 0; i < dev->deviate_size; ++i) {
4459 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4460 yang_free_deviate(module->ctx, dev, i + 1);
4461 dev->deviate_size = i+1;
4462 goto error; // missing free unresolve type in deviate
PavolVican75af21d2016-12-29 20:04:07 +01004463 }
4464 }
Michal Vasko15a43372017-09-25 14:12:42 +02004465 /* now check whether default value, if any, matches the type */
4466 for (u = 0; u < dflt_check->number; ++u) {
4467 value = NULL;
4468 rc = EXIT_SUCCESS;
4469 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4470 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4471 target_name = leaf->name;
4472 value = leaf->dflt;
4473 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4474 } else { /* LYS_LEAFLIST */
4475 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4476 target_name = llist->name;
4477 for (i = 0; i < llist->dflt_size; i++) {
4478 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4479 (struct lys_node *)(&llist->dflt[i]));
4480 if (rc == -1) {
4481 value = llist->dflt[i];
4482 break;
4483 }
4484 }
4485 }
4486 if (rc == -1) {
4487 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4488 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
4489 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4490 target_name);
4491 goto error;
4492 }
PavolVican75af21d2016-12-29 20:04:07 +01004493 }
Michal Vasko15a43372017-09-25 14:12:42 +02004494 ly_set_free(dflt_check);
PavolVican75af21d2016-12-29 20:04:07 +01004495 }
PavolVican75af21d2016-12-29 20:04:07 +01004496
Radek Krejci29eac3d2017-06-01 16:50:02 +02004497 /* mark all the affected modules as deviated and implemented */
4498 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004499 mod = lys_node_module(parent);
4500 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004501 mod->deviated = 1; /* main module */
4502 parent->module->deviated = 1; /* possible submodule */
4503 if (lys_set_implemented(mod)) {
4504 LOGERR(ly_errno, "Setting the deviated module \"%s\" implemented failed.", mod->name);
4505 goto error;
4506 }
4507 }
PavolVican75af21d2016-12-29 20:04:07 +01004508 }
PavolVican75af21d2016-12-29 20:04:07 +01004509
4510 return EXIT_SUCCESS;
4511error:
4512 ly_set_free(dflt_check);
4513 return EXIT_FAILURE;
4514}
4515
4516static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004517yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4518{
PavolVican75af21d2016-12-29 20:04:07 +01004519 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004520
4521 aug_size = module->augment_size;
4522 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004523 dev_size = module->deviation_size;
4524 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004525
PavolVican6f87bf92017-02-15 19:38:55 +01004526 if (yang_check_typedef(module, NULL, unres)) {
4527 goto error;
4528 }
4529
PavolVicanc1807262017-01-31 18:00:27 +01004530 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4531 goto error;
4532 }
4533
PavolVican171717d2017-02-01 14:49:55 +01004534 /* check extension in revision */
4535 for (i = 0; i < module->rev_size; ++i) {
4536 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4537 goto error;
4538 }
4539 }
4540
PavolVican19dc6152017-02-06 12:04:15 +01004541 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004542 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004543 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4544 goto error;
4545 }
4546 }
4547
Pavol Vican7a7916f2016-11-21 23:38:30 +01004548 /* check features */
4549 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004550 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4551 goto error;
4552 }
PavolVican5393d3f2017-02-06 23:30:55 +01004553 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4554 goto error;
4555 }
4556
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004557 /* check for circular dependencies */
4558 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4559 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004560 }
4561 }
Pavol Vican36e27272016-11-22 15:47:28 +01004562 erase_identities = 0;
4563 if (yang_check_identities(module, unres)) {
4564 goto error;
4565 }
Pavol Vican05810b62016-11-23 14:07:22 +01004566 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004567 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004568 goto error;
4569 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004570
PavolVican75af21d2016-12-29 20:04:07 +01004571 /* check deviation */
4572 for (i = 0; i < dev_size; ++i) {
4573 module->deviation_size++;
4574 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4575 goto error;
4576 }
4577 }
4578
Pavol Vican3ad50f82016-12-04 15:00:36 +01004579 /* check augments */
4580 for (i = 0; i < aug_size; ++i) {
4581 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004582 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004583 goto error;
4584 }
4585 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4586 goto error;
4587 }
4588 }
4589
Pavol Vican7313fc02016-11-14 01:10:31 +01004590 return EXIT_SUCCESS;
4591error:
Pavol Vican36e27272016-11-22 15:47:28 +01004592 if (erase_identities) {
4593 yang_free_ident_base(module->ident, 0, module->ident_size);
4594 }
Pavol Vican05810b62016-11-23 14:07:22 +01004595 if (erase_nodes) {
4596 yang_free_nodes(module->ctx, node);
4597 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004598 for (i = module->augment_size; i < aug_size; ++i) {
4599 yang_free_augment(module->ctx, &module->augment[i]);
4600 }
PavolVican75af21d2016-12-29 20:04:07 +01004601 for (i = module->deviation_size; i < dev_size; ++i) {
4602 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4603 free(module->deviation[i].deviate);
4604 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004605 return EXIT_FAILURE;
4606}
PavolVican22e88682017-02-14 22:38:18 +01004607
4608int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004609yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004610 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4611{
4612 int c;
4613 const char **str, ***p = NULL;
4614 void *reallocated;
4615 struct lyext_substmt *info;
4616
4617 c = 0;
4618 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004619 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004620 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4621 if (info->cardinality < LY_STMT_CARD_SOME) {
4622 str++;
4623 } else {
4624 /* get the index in the array to add new item */
4625 p = (const char ***)str;
4626 for (c = 0; p[0][c + 1]; c++);
4627 str = p[1];
4628 }
4629 str[c] = lydict_insert_zc(module->ctx, value);
4630 } else {
4631 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4632 if (!str) {
4633 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004634 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004635 }
4636 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
4637 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004638 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004639 }
4640
4641 if (info->cardinality >= LY_STMT_CARD_SOME) {
4642 /* there can be multiple instances, str is actually const char *** */
4643 p = (const char ***)str;
4644 if (!p[0]) {
4645 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004646 p[0] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004647 LY_CHECK_ERR_GOTO(!p[0], LOGMEM, error);
PavolVican22e88682017-02-14 22:38:18 +01004648 if (stmt == LY_STMT_BELONGSTO) {
4649 /* allocate another array for the belongs-to's prefixes */
4650 p[1] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004651 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004652 } else if (stmt == LY_STMT_ARGUMENT) {
4653 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004654 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004655 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004656 /* default value of yin element */
4657 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004658 }
4659 } else {
4660 /* get the index in the array to add new item */
4661 for (c = 0; p[0][c]; c++);
4662 }
4663 str = p[0];
4664 }
4665
4666 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004667 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004668
PavolVican50809742017-02-18 21:22:54 +01004669 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004670 /* enlarge the array(s) */
4671 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4672 if (!reallocated) {
4673 LOGMEM;
4674 lydict_remove(module->ctx, p[0][c]);
4675 p[0][c] = NULL;
4676 return EXIT_FAILURE;
4677 }
4678 p[0] = reallocated;
4679 p[0][c + 1] = NULL;
4680
4681 if (stmt == LY_STMT_BELONGSTO) {
4682 /* enlarge the second belongs-to's array with prefixes */
4683 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4684 if (!reallocated) {
4685 LOGMEM;
4686 lydict_remove(module->ctx, p[1][c]);
4687 p[1][c] = NULL;
4688 return EXIT_FAILURE;
4689 }
4690 p[1] = reallocated;
4691 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004692 } else if (stmt == LY_STMT_ARGUMENT) {
4693 /* enlarge the second argument's array with yin element */
4694 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4695 if (!reallocated) {
4696 LOGMEM;
4697 ((uint8_t *)p[1])[c] = 0;
4698 return EXIT_FAILURE;
4699 }
4700 p[1] = reallocated;
4701 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004702 }
4703 }
4704 }
4705
4706 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004707
4708error:
4709 free(value);
4710 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004711}
PavolVican5334c892017-02-15 16:29:09 +01004712
4713static int
4714yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4715{
4716 int c = 0, decrement = 0;
4717 const char **str, ***p = NULL;
4718 struct lyext_substmt *info;
4719
4720
4721 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4722 stmt = LY_STMT_BELONGSTO;
4723 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004724 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4725 stmt = LY_STMT_ARGUMENT;
4726 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004727 }
4728
4729 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4730 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4731 return 0;
4732 } else {
4733 p = (const char ***)str;
4734 /* get the index in the array */
4735 for (c = 0; p[0][c]; c++);
4736 return c + decrement;
4737 }
4738}
PavolVicana0fdbf32017-02-15 17:59:02 +01004739
4740void **
PavolVicanfe83b152017-02-19 03:19:29 +01004741yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4742 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004743{
4744 int c;
4745 void **data, ***p = NULL;
4746 void *reallocated;
4747 struct lyext_substmt *info;
4748
4749 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4750 if (!data) {
4751 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4752 return NULL;
4753 }
4754 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
4755 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4756 return NULL;
4757 }
4758
4759 c = 0;
4760 if (info->cardinality >= LY_STMT_CARD_SOME) {
4761 /* there can be multiple instances, so instead of pointer to array,
4762 * we have in data pointer to pointer to array */
4763 p = (void ***)data;
4764 data = *p;
4765 if (!data) {
4766 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004767 *p = data = calloc(2, sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004768 LY_CHECK_ERR_RETURN(!data, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004769 } else {
4770 for (c = 0; *data; data++, c++);
4771 }
4772 }
4773
PavolVicaneef1d912017-02-19 00:19:15 +01004774 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004775 /* enlarge the array */
4776 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004777 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004778 *p = reallocated;
4779 data = *p;
4780 data[c + 1] = NULL;
4781 }
4782
PavolVicanfe83b152017-02-19 03:19:29 +01004783 if (index) {
4784 *index = c;
4785 return data;
4786 } else {
4787 return &data[c];
4788 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004789}
PavolVicanff0f7f42017-02-16 11:35:42 +01004790
4791int
4792yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4793 LY_STMT stmt, uint16_t value, uint16_t mask)
4794{
4795 uint16_t *data;
4796 struct lyext_substmt *info;
4797
4798 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4799 if (!data) {
4800 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4801 return EXIT_FAILURE;
4802 }
4803 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
4804 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4805 return EXIT_FAILURE;
4806 }
4807
4808 *data |= value;
4809 return EXIT_SUCCESS;
4810}
PavolVican8e8dfd12017-02-16 13:51:41 +01004811
4812int
PavolVican6a852a62017-02-16 15:36:01 +01004813yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4814 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004815{
PavolVican6a852a62017-02-16 15:36:01 +01004816 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004817 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004818 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004819
4820 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4821 if (!val) {
4822 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4823 return EXIT_FAILURE;
4824 }
PavolVican6a852a62017-02-16 15:36:01 +01004825 if (stmt == LY_STMT_DIGITS) {
4826 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
4827 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4828 return EXIT_FAILURE;
4829 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004830
PavolVican6a852a62017-02-16 15:36:01 +01004831 if (info->cardinality >= LY_STMT_CARD_SOME) {
4832 /* there can be multiple instances */
4833 pp = (uint8_t**)val;
4834 if (!(*pp)) {
4835 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Radek Krejcia8d111f2017-05-31 13:57:37 +02004836 LY_CHECK_ERR_RETURN(!*pp, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004837 } else {
4838 for (i = 0; (*pp)[i]; i++);
4839 }
4840 val = &(*pp)[i];
4841 }
4842
4843 /* stored value */
4844 *val = value;
4845
4846 if (i) {
4847 /* enlarge the array */
4848 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004849 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004850 *pp = reallocated;
4851 (*pp)[i + 1] = 0;
4852 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004853 } else {
PavolVican6a852a62017-02-16 15:36:01 +01004854 if (*val) {
4855 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4856 return EXIT_FAILURE;
4857 }
4858
4859 if (stmt == LY_STMT_REQINSTANCE) {
4860 *val = (value == 1) ? 1 : 2;
4861 } else if (stmt == LY_STMT_MODIFIER) {
4862 *val = 1;
4863 } else {
4864 LOGINT;
4865 return EXIT_FAILURE;
4866 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004867 }
4868
4869 return EXIT_SUCCESS;
4870}
PavolVican3f47b292017-02-16 20:38:16 +01004871
PavolVicanf3091bf2017-02-19 18:27:01 +01004872int
4873yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4874 struct lys_node *node, LY_STMT stmt)
4875{
4876 struct lyext_substmt *info;
4877 struct lys_node **snode, *siter;
4878
4879 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
4880 if (!snode) {
4881 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4882 return EXIT_FAILURE;
4883 }
4884 if (info->cardinality < LY_STMT_CARD_SOME) {
4885 LY_TREE_FOR(node, siter) {
4886 if (stmt == lys_snode2stmt(siter->nodetype)) {
4887 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4888 return EXIT_FAILURE;
4889 }
4890 }
4891 }
4892
4893 return EXIT_SUCCESS;
4894}
PavolVicandb0e8172017-02-20 00:46:09 +01004895
4896int
4897yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
4898 char *parent_name, char **values, int implemented)
4899{
4900 int c, i;
4901 struct lys_module **modules, ***p, *reallocated, **pp;
4902 struct lyext_substmt *info;
4903
4904 if (!values) {
4905 return EXIT_SUCCESS;
4906 }
4907 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
4908 if (!modules) {
4909 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
4910 return EXIT_FAILURE;
4911 }
4912
4913 for (i = 0; values[i]; ++i) {
4914 c = 0;
4915 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
4916 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
4917 return EXIT_FAILURE;
4918 }
4919 if (info->cardinality >= LY_STMT_CARD_SOME) {
4920 /* there can be multiple instances, so instead of pointer to array,
4921 * we have in modules pointer to pointer to array */
4922 p = (struct lys_module ***)pp;
4923 modules = *p;
4924 if (!modules) {
4925 /* allocate initial array */
4926 *p = modules = calloc(2, sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004927 LY_CHECK_ERR_RETURN(!*p, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01004928 } else {
4929 for (c = 0; *modules; modules++, c++);
4930 }
4931 }
4932
4933 if (c) {
4934 /* enlarge the array */
4935 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004936 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01004937 *p = (struct lys_module **)reallocated;
4938 modules = *p;
4939 modules[c + 1] = NULL;
4940 }
4941
4942 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
4943 if (!modules[c]) {
4944 return EXIT_FAILURE;
4945 }
4946 }
4947
4948 return EXIT_SUCCESS;
4949}