blob: 14c07761f5dafc461030610ee33ab2ee51b3e507 [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;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100402
403 /* insert the node into the schema tree */
Pavol Vican05810b62016-11-23 14:07:22 +0100404 child = (parent) ? &parent->child : root;
405 if (*child) {
406 (*child)->prev->next = node;
407 (*child)->prev = node;
408 } else {
409 *child = node;
410 node->prev = node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100411 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100412 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100413}
414
415int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200416yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100417{
418 int ret;
419
420 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100421 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100422 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100423 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100424 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100425 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100426 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200427 default:
428 free(value);
429 LOGINT;
430 ret = EXIT_FAILURE;
431 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100432 }
433 return ret;
434}
435
436int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200437yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100438{
439 int ret;
440
441 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100442 case LEAF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100443 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100444 break;
445 case LEAF_LIST_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100446 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value, node);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100447 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100448 case TYPEDEF_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100449 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value, NULL);
Pavol Vican0df02b02016-03-01 10:28:50 +0100450 break;
PavolVican75af21d2016-12-29 20:04:07 +0100451 case ADD_KEYWORD:
452 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +0100453 case DELETE_KEYWORD:
PavolVican196694c2017-01-27 10:33:09 +0100454 ret = yang_check_string(module, &((struct lys_deviate *) node)->units, "units", "deviate", value, NULL);
Pavol Vican021488a2016-01-25 23:56:12 +0100455 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200456 default:
457 free(value);
458 LOGINT;
459 ret = EXIT_FAILURE;
460 break;
Pavol Vican021488a2016-01-25 23:56:12 +0100461 }
462 return ret;
463}
Pavol Vican5de33492016-02-22 14:03:24 +0100464
465int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100466yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100467{
468 char *exp, *value;
Radek Krejci5c08a992016-11-02 13:30:04 +0100469 struct lys_node *node;
Pavol Vican5de33492016-02-22 14:03:24 +0100470
471 exp = value = (char *) list->keys;
472 while ((value = strpbrk(value, " \t\n"))) {
473 list->keys_size++;
474 while (isspace(*value)) {
475 value++;
476 }
477 }
478 list->keys_size++;
Radek Krejci5c08a992016-11-02 13:30:04 +0100479
480 list->keys_str = lydict_insert_zc(module->ctx, exp);
Pavol Vican5de33492016-02-22 14:03:24 +0100481 list->keys = calloc(list->keys_size, sizeof *list->keys);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200482 LY_CHECK_ERR_RETURN(!list->keys, LOGMEM, EXIT_FAILURE);
483
Radek Krejci5c08a992016-11-02 13:30:04 +0100484 for (node = list->parent; node && node->nodetype != LYS_GROUPING; node = lys_parent(node));
485 if (!node && unres_schema_add_node(module, unres, list, UNRES_LIST_KEYS, NULL) == -1) {
486 return EXIT_FAILURE;
Pavol Vican5de33492016-02-22 14:03:24 +0100487 }
Pavol Vican5de33492016-02-22 14:03:24 +0100488 return EXIT_SUCCESS;
Pavol Vican5de33492016-02-22 14:03:24 +0100489}
490
491int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100492yang_fill_unique(struct lys_module *module, struct lys_node_list *list, struct lys_unique *unique, char *value, struct unres_schema *unres)
Pavol Vican85f12022016-03-05 16:30:35 +0100493{
494 int i, j;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200495 char *vaux, c;
Radek Krejcid09d1a52016-08-11 14:05:45 +0200496 struct unres_list_uniq *unique_info;
Pavol Vican85f12022016-03-05 16:30:35 +0100497
498 /* count the number of unique leafs in the value */
499 vaux = value;
500 while ((vaux = strpbrk(vaux, " \t\n"))) {
501 unique->expr_size++;
502 while (isspace(*vaux)) {
503 vaux++;
504 }
505 }
506 unique->expr_size++;
507 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200508 LY_CHECK_ERR_GOTO(!unique->expr, LOGMEM, error);
Pavol Vican85f12022016-03-05 16:30:35 +0100509
510 for (i = 0; i < unique->expr_size; i++) {
511 vaux = strpbrk(value, " \t\n");
Radek Krejci1a9c3612017-04-24 14:49:43 +0200512 if (vaux) {
513 c = *vaux;
514 *vaux = '\0';
Pavol Vican85f12022016-03-05 16:30:35 +0100515 }
516
Radek Krejci1a9c3612017-04-24 14:49:43 +0200517 /* store token into unique structure (includes converting prefix to the module name) */
518 unique->expr[i] = transform_schema2json(module, value);
519 if (vaux) {
520 *vaux = c;
521 }
Pavol Vican85f12022016-03-05 16:30:35 +0100522
523 /* check that the expression does not repeat */
524 for (j = 0; j < i; j++) {
525 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100526 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
PavolVican196694c2017-01-27 10:33:09 +0100527 LOGVAL(LYE_SPEC, LY_VLOG_LYS, list, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100528 goto error;
529 }
530 }
531 /* try to resolve leaf */
532 if (unres) {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200533 unique_info = malloc(sizeof *unique_info);
Radek Krejcia8d111f2017-05-31 13:57:37 +0200534 LY_CHECK_ERR_GOTO(!unique_info, LOGMEM, error);
Radek Krejcid09d1a52016-08-11 14:05:45 +0200535 unique_info->list = (struct lys_node *)list;
536 unique_info->expr = unique->expr[i];
537 unique_info->trg_type = &unique->trg_type;
538 if (unres_schema_add_node(module, unres, unique_info, UNRES_LIST_UNIQ, NULL) == -1) {
Pavol Vican18b10212016-04-11 15:41:52 +0200539 goto error;
540 }
Pavol Vican85f12022016-03-05 16:30:35 +0100541 } else {
Radek Krejcid09d1a52016-08-11 14:05:45 +0200542 if (resolve_unique((struct lys_node *)list, unique->expr[i], &unique->trg_type)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100543 goto error;
544 }
545 }
546
547 /* move to next token */
548 value = vaux;
Radek Krejci1a9c3612017-04-24 14:49:43 +0200549 while(value && isspace(*value)) {
Pavol Vican85f12022016-03-05 16:30:35 +0100550 value++;
551 }
552 }
553
554 return EXIT_SUCCESS;
555
556error:
557 return EXIT_FAILURE;
558}
559
560int
Pavol Vican5de33492016-02-22 14:03:24 +0100561yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
562{
563 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100564 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100565
566 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100567 str = (char *)list->unique[k].expr;
568 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100569 goto error;
570 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100571 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100572 }
573 return EXIT_SUCCESS;
574
575error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100576 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100577 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100578}
579
Pavol Vican07f220f2016-09-02 13:04:37 +0200580int
Pavol Vican81344ac2016-09-02 14:23:06 +0200581yang_read_leafref_path(struct lys_module *module, struct yang_type *stype, char *value)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100582{
Pavol Vican81344ac2016-09-02 14:23:06 +0200583 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
584 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
585 goto error;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100586 }
Pavol Vican81344ac2016-09-02 14:23:06 +0200587 if (stype->type->info.lref.path) {
588 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "path", "type");
589 goto error;
590 }
591 stype->type->info.lref.path = lydict_insert_zc(module->ctx, value);
592 stype->base = LY_TYPE_LEAFREF;
593 return EXIT_SUCCESS;
594
595error:
596 free(value);
597 return EXIT_FAILURE;
598}
599
600int
601yang_read_require_instance(struct yang_type *stype, int req)
602{
603 if (stype->base && (stype->base != LY_TYPE_LEAFREF)) {
604 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
605 return EXIT_FAILURE;
606 }
607 if (stype->type->info.lref.req) {
608 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "require-instance", "type");
609 return EXIT_FAILURE;
610 }
611 stype->type->info.lref.req = req;
612 stype->base = LY_TYPE_LEAFREF;
613 return EXIT_SUCCESS;
614}
615
616int
Pavol Vican7313fc02016-11-14 01:10:31 +0100617yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct lys_type *type, int tpdftype, struct unres_schema *unres)
Pavol Vican73e7c992016-02-24 12:18:05 +0100618{
Radek Krejcidce5f972017-09-12 15:47:49 +0200619 int rc, ret = -1;
620 unsigned int i, j;
Pavol Vican81344ac2016-09-02 14:23:06 +0200621 int8_t req;
Pavol Vican73e7c992016-02-24 12:18:05 +0100622 const char *name, *value;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100623 LY_DATA_TYPE base = 0, base_tmp;
Radek Krejci3a5501d2016-07-18 22:03:34 +0200624 struct lys_node *siter;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200625 struct lys_type *dertype;
626 struct lys_type_enum *enms_sc = NULL;
627 struct lys_type_bit *bits_sc = NULL;
628 struct lys_type_bit bit_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100629 struct yang_type *yang;
Pavol Vican73e7c992016-02-24 12:18:05 +0100630
Pavol Vican0adf01d2016-03-22 12:29:33 +0100631 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100632 if (!value) {
633 goto error;
634 }
635
636 i = parse_identifier(value);
637 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100638 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100639 lydict_remove(module->ctx, value);
640 goto error;
641 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200642 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100643 name = value;
644 if (value[i]) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100645 type->module_name = lydict_insert(module->ctx, value, i);
Pavol Vican73e7c992016-02-24 12:18:05 +0100646 name += i;
647 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100648 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100649 lydict_remove(module->ctx, value);
650 goto error;
651 }
652 ++name;
653 }
654
Pavol Vican7313fc02016-11-14 01:10:31 +0100655 rc = resolve_superior_type(name, type->module_name, module, parent, &type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100656 if (rc == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100657 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, type->module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200658 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100659 goto error;
660
Michal Vasko01c6fd22016-05-20 11:43:05 +0200661 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100662 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200663 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200664 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100665 ret = EXIT_FAILURE;
666 goto error;
667 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200668 lydict_remove(module->ctx, value);
Radek Krejcic13db382016-08-16 10:52:42 +0200669
Pavol Vican7313fc02016-11-14 01:10:31 +0100670 if (type->base == LY_TYPE_ERR) {
Radek Krejcic13db382016-08-16 10:52:42 +0200671 /* resolved type in grouping, decrease the grouping's nacm number to indicate that one less
Radek Krejci9b6aad22016-09-20 15:55:51 +0200672 * 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 +0200673 for (siter = parent; siter && (siter->nodetype != LYS_GROUPING); siter = lys_parent(siter));
674 if (siter) {
Radek Krejci93def382017-05-24 15:33:48 +0200675 assert(((struct lys_node_grp *)siter)->unres_count);
676 ((struct lys_node_grp *)siter)->unres_count--;
Radek Krejcic13db382016-08-16 10:52:42 +0200677 } else {
678 LOGINT;
679 goto error;
680 }
681 }
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200682
683 /* check status */
Pavol Vican7313fc02016-11-14 01:10:31 +0100684 if (lyp_check_status(type->parent->flags, type->parent->module, type->parent->name,
685 type->der->flags, type->der->module, type->der->name, parent)) {
Pavol Vicanfdab9f92016-09-07 15:23:27 +0200686 goto error;
687 }
688
Pavol Vican8bd72e42016-08-29 09:53:05 +0200689 base = typ->base;
PavolVicane87cb932016-12-30 15:36:18 +0100690 base_tmp = type->base;
Pavol Vican7313fc02016-11-14 01:10:31 +0100691 type->base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100692 if (base == 0) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100693 base = type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100694 }
695 switch (base) {
696 case LY_TYPE_STRING:
Pavol Vican7313fc02016-11-14 01:10:31 +0100697 if (type->base == LY_TYPE_BINARY) {
698 if (type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100699 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100700 goto error;
701 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100702 type->info.binary.length = type->info.str.length;
703 if (type->info.binary.length && lyp_check_length_range(type->info.binary.length->expr, type)) {
704 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100705 goto error;
706 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100707 } else if (type->base == LY_TYPE_STRING) {
708 if (type->info.str.length && lyp_check_length_range(type->info.str.length->expr, type)) {
709 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100710 goto error;
711 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100712 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100713 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100714 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100715 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100716 break;
717 case LY_TYPE_DEC64:
Pavol Vican7313fc02016-11-14 01:10:31 +0100718 if (type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100719 /* mandatory sub-statement(s) check */
Pavol Vican7313fc02016-11-14 01:10:31 +0100720 if (!type->info.dec64.dig && !type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100721 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100722 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100723 goto error;
724 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100725 if (type->info.dec64.dig && type->der->type.der) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100726 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100727 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100728 goto error;
729 }
Radek Krejci4800f652016-09-08 14:02:52 +0200730
731 /* copy fraction-digits specification from parent type for easier internal use */
Pavol Vican7313fc02016-11-14 01:10:31 +0100732 if (type->der->type.der) {
733 type->info.dec64.dig = type->der->type.info.dec64.dig;
734 type->info.dec64.div = type->der->type.info.dec64.div;
Radek Krejci4800f652016-09-08 14:02:52 +0200735 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100736 if (type->info.dec64.range && lyp_check_length_range(type->info.dec64.range->expr, type)) {
737 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.dec64.range->expr, "range");
Pavol Vican3c8ee2b2016-09-29 13:18:13 +0200738 goto error;
739 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100740 } else if (type->base >= LY_TYPE_INT8 && type->base <=LY_TYPE_UINT64) {
741 if (type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100742 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100743 goto error;
744 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100745 type->info.num.range = type->info.dec64.range;
746 if (type->info.num.range && lyp_check_length_range(type->info.num.range->expr, type)) {
747 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100748 goto error;
749 }
750 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100751 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100752 goto error;
753 }
754 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100755 case LY_TYPE_ENUM:
Pavol Vican7313fc02016-11-14 01:10:31 +0100756 if (type->base != LY_TYPE_ENUM) {
757 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100758 goto error;
759 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100760 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200761
762 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100763 if (!type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200764 /* type is derived directly from buit-in enumeartion type and enum statement is required */
765 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
766 goto error;
767 }
768 } else {
769 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100770 if (module->version < 2 && type->info.enums.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200771 /* type is not directly derived from built-in enumeration type and enum statement is prohibited
772 * in YANG 1.0, since YANG 1.1 enum statements can be used to restrict the base enumeration type */
773 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
774 goto error;
775 }
776
777 /* restricted enumeration type - the name MUST be used in the base type */
778 enms_sc = dertype->info.enums.enm;
Pavol Vican7313fc02016-11-14 01:10:31 +0100779 for(i = 0; i < type->info.enums.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200780 for (j = 0; j < dertype->info.enums.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100781 if (ly_strequal(enms_sc[j].name, type->info.enums.enm[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200782 break;
783 }
784 }
785 if (j == dertype->info.enums.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100786 LOGVAL(LYE_ENUM_INNAME, LY_VLOG_NONE, NULL, type->info.enums.enm[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200787 goto error;
788 }
789
Pavol Vican7313fc02016-11-14 01:10:31 +0100790 if (type->info.enums.enm[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200791 /* automatically assign value from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100792 type->info.enums.enm[i].value = enms_sc[j].value;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200793 } else {
794 /* check that the assigned value corresponds to the original
795 * value of the enum in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100796 if (type->info.enums.enm[i].value != enms_sc[j].value) {
797 /* type->info.enums.enm[i].value - assigned value in restricted enum
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200798 * enms_sc[j].value - value assigned to the corresponding enum (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100799 LOGVAL(LYE_ENUM_INVAL, LY_VLOG_NONE, NULL, type->info.enums.enm[i].value,
800 type->info.enums.enm[i].name, enms_sc[j].value);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200801 goto error;
802 }
803 }
804 }
Pavol Vican79a763d2016-02-25 15:41:27 +0100805 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100806 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100807 case LY_TYPE_BITS:
Pavol Vican7313fc02016-11-14 01:10:31 +0100808 if (type->base != LY_TYPE_BITS) {
809 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100810 goto error;
811 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100812 dertype = &type->der->type;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200813
814 if (!dertype->der) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100815 if (!type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200816 /* type is derived directly from buit-in bits type and bit statement is required */
817 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
818 goto error;
819 }
820 } else {
821 for (; !dertype->info.enums.count; dertype = &dertype->der->type);
Pavol Vican7313fc02016-11-14 01:10:31 +0100822 if (module->version < 2 && type->info.bits.count) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200823 /* type is not directly derived from buit-in bits type and bit statement is prohibited,
824 * since YANG 1.1 the bit statements can be used to restrict the base bits type */
825 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
826 goto error;
827 }
828
829 bits_sc = dertype->info.bits.bit;
Pavol Vican7313fc02016-11-14 01:10:31 +0100830 for (i = 0; i < type->info.bits.count; i++) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200831 for (j = 0; j < dertype->info.bits.count; j++) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100832 if (ly_strequal(bits_sc[j].name, type->info.bits.bit[i].name, 1)) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200833 break;
834 }
835 }
836 if (j == dertype->info.bits.count) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100837 LOGVAL(LYE_BITS_INNAME, LY_VLOG_NONE, NULL, type->info.bits.bit[i].name);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200838 goto error;
839 }
840
841 /* restricted bits type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100842 if (type->info.bits.bit[i].flags & LYS_AUTOASSIGNED) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200843 /* automatically assign position from base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100844 type->info.bits.bit[i].pos = bits_sc[j].pos;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200845 } else {
846 /* check that the assigned position corresponds to the original
847 * position of the bit in the base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100848 if (type->info.bits.bit[i].pos != bits_sc[j].pos) {
849 /* type->info.bits.bit[i].pos - assigned position in restricted bits
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200850 * bits_sc[j].pos - position assigned to the corresponding bit (detected above) in base type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100851 LOGVAL(LYE_BITS_INVAL, LY_VLOG_NONE, NULL, type->info.bits.bit[i].pos,
852 type->info.bits.bit[i].name, bits_sc[j].pos);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200853 goto error;
854 }
855 }
856 }
Pavol Vican03a59442016-03-21 15:23:45 +0100857 }
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200858
Radek Krejcidce5f972017-09-12 15:47:49 +0200859 for (i = type->info.bits.count; i > 0; i--) {
860 j = i - 1;
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200861
862 /* keep them ordered by position */
Pavol Vican7313fc02016-11-14 01:10:31 +0100863 while (j && type->info.bits.bit[j - 1].pos > type->info.bits.bit[j].pos) {
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200864 /* switch them */
Pavol Vican7313fc02016-11-14 01:10:31 +0100865 memcpy(&bit_tmp, &type->info.bits.bit[j], sizeof bit_tmp);
866 memcpy(&type->info.bits.bit[j], &type->info.bits.bit[j - 1], sizeof bit_tmp);
867 memcpy(&type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican8ad2e0d2016-08-09 12:56:19 +0200868 j--;
869 }
Pavol Vican03a59442016-03-21 15:23:45 +0100870 }
871 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100872 case LY_TYPE_LEAFREF:
Pavol Vican7313fc02016-11-14 01:10:31 +0100873 if (type->base == LY_TYPE_INST) {
874 if (type->info.lref.path) {
Pavol Vican81344ac2016-09-02 14:23:06 +0200875 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100876 goto error;
877 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100878 if ((req = type->info.lref.req)) {
879 type->info.inst.req = req;
Pavol Vican81344ac2016-09-02 14:23:06 +0200880 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100881 } else if (type->base == LY_TYPE_LEAFREF) {
Pavol Vican92626d72016-09-21 09:36:09 +0200882 /* require-instance only YANG 1.1 */
Pavol Vican7313fc02016-11-14 01:10:31 +0100883 if (type->info.lref.req && (module->version < 2)) {
Pavol Vican92626d72016-09-21 09:36:09 +0200884 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "require-instance");
885 goto error;
886 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200887 /* flag resolving for later use */
888 if (!tpdftype) {
889 for (siter = parent; siter && siter->nodetype != LYS_GROUPING; siter = lys_parent(siter));
890 if (siter) {
891 /* just a flag - do not resolve */
892 tpdftype = 1;
893 }
894 }
895
Pavol Vican7313fc02016-11-14 01:10:31 +0100896 if (type->info.lref.path) {
897 if (type->der->type.der) {
Pavol Vican894ee0f2016-08-30 15:29:46 +0200898 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "path");
899 goto error;
900 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100901 value = type->info.lref.path;
Pavol Vican191613a2016-02-26 16:21:32 +0100902 /* store in the JSON format */
Pavol Vican7313fc02016-11-14 01:10:31 +0100903 type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100904 lydict_remove(module->ctx, value);
Pavol Vican7313fc02016-11-14 01:10:31 +0100905 if (!type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100906 goto error;
907 }
Radek Krejci3a5501d2016-07-18 22:03:34 +0200908 /* try to resolve leafref path only when this is instantiated
909 * leaf, so it is not:
910 * - typedef's type,
911 * - in grouping definition,
912 * - just instantiated in a grouping definition,
913 * because in those cases the nodes referenced in path might not be present
914 * and it is not a bug. */
Pavol Vican7313fc02016-11-14 01:10:31 +0100915 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100916 goto error;
917 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100918 } else if (!type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100919 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100920 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200921 } else {
Radek Krejci3a5501d2016-07-18 22:03:34 +0200922 /* copy leafref definition into the derived type */
Pavol Vican7313fc02016-11-14 01:10:31 +0100923 type->info.lref.path = lydict_insert(module->ctx, type->der->type.info.lref.path, 0);
Radek Krejci3a5501d2016-07-18 22:03:34 +0200924 /* and resolve the path at the place we are (if not in grouping/typedef) */
Pavol Vican7313fc02016-11-14 01:10:31 +0100925 if (!tpdftype && unres_schema_add_node(module, unres, type, UNRES_TYPE_LEAFREF, parent) == -1) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200926 goto error;
927 }
Pavol Vican191613a2016-02-26 16:21:32 +0100928 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100929 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100930 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100931 goto error;
932 }
933 break;
934 case LY_TYPE_IDENT:
Pavol Vican7313fc02016-11-14 01:10:31 +0100935 if (type->base != LY_TYPE_IDENT) {
936 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100937 goto error;
938 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100939 if (type->der->type.der) {
940 if (type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200941 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "base");
942 goto error;
943 }
944 } else {
Pavol Vican7313fc02016-11-14 01:10:31 +0100945 if (!type->info.ident.ref) {
Pavol Vican07f220f2016-09-02 13:04:37 +0200946 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
947 goto error;
948 }
949 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100950 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100951 case LY_TYPE_UNION:
Pavol Vican7313fc02016-11-14 01:10:31 +0100952 if (type->base != LY_TYPE_UNION) {
953 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100954 goto error;
955 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100956 if (!type->info.uni.types) {
957 if (type->der->type.der) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100958 /* this is just a derived type with no additional type specified/required */
959 break;
960 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100961 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100962 goto error;
963 }
Pavol Vican7313fc02016-11-14 01:10:31 +0100964 for (i = 0; i < type->info.uni.count; i++) {
PavolVican811f03b2016-12-29 23:03:20 +0100965 dertype = &type->info.uni.types[i];
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100966 if (dertype->base == LY_TYPE_DER || dertype->base == LY_TYPE_ERR) {
967 yang = (struct yang_type *)dertype->der;
968 dertype->der = NULL;
PavolVicane87cb932016-12-30 15:36:18 +0100969 dertype->parent = type->parent;
970 if (yang_check_type(module, parent, yang, dertype, tpdftype, unres)) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100971 dertype->der = (struct lys_tpdf *)yang;
972 ret = EXIT_FAILURE;
PavolVican811f03b2016-12-29 23:03:20 +0100973 type->base = base_tmp;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100974 base = 0;
975 goto error;
976 } else {
977 lydict_remove(module->ctx, yang->name);
978 free(yang);
979 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100980 }
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200981 if (module->version < 2) {
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100982 if (dertype->base == LY_TYPE_EMPTY) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200983 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
984 goto error;
Pavol Vicancf2af4d2016-12-21 14:13:06 +0100985 } else if (dertype->base == LY_TYPE_LEAFREF) {
Pavol Vican8e00e7a2016-09-20 11:07:48 +0200986 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
987 goto error;
988 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100989 }
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100990 if ((dertype->base == LY_TYPE_INST) || (dertype->base == LY_TYPE_LEAFREF)
991 || ((dertype->base == LY_TYPE_UNION) && dertype->info.uni.has_ptr_type)) {
Radek Krejcia726f9b2017-02-28 09:56:44 +0100992 type->info.uni.has_ptr_type = 1;
Michal Vaskoe3886bb2017-01-02 11:33:28 +0100993 }
Pavol Vicana4f045a2016-02-29 15:01:20 +0100994 }
995 break;
Pavol Vicana1827962016-02-29 15:39:42 +0100996
997 default:
998 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
Pavol Vican7313fc02016-11-14 01:10:31 +0100999 if (type->base != base) {
1000 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +01001001 goto error;
1002 }
1003 } else {
1004 LOGINT;
1005 goto error;
1006 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001007 }
1008 return EXIT_SUCCESS;
1009
1010error:
Pavol Vican7313fc02016-11-14 01:10:31 +01001011 if (type->module_name) {
1012 lydict_remove(module->ctx, type->module_name);
1013 type->module_name = NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001014 }
Pavol Vican8bd72e42016-08-29 09:53:05 +02001015 if (base) {
PavolVicane87cb932016-12-30 15:36:18 +01001016 type->base = base_tmp;
Pavol Vican8bd72e42016-08-29 09:53:05 +02001017 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001018 return ret;
1019}
1020
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001021void
1022yang_free_type_union(struct ly_ctx *ctx, struct lys_type *type)
1023{
1024 struct lys_type *stype;
1025 struct yang_type *yang;
Radek Krejcidce5f972017-09-12 15:47:49 +02001026 unsigned int i;
Pavol Vicancf2af4d2016-12-21 14:13:06 +01001027
1028 for (i = 0; i < type->info.uni.count; ++i) {
1029 stype = &type->info.uni.types[i];
1030 if (stype->base == LY_TYPE_DER || stype->base == LY_TYPE_ERR) {
1031 yang = (struct yang_type *)stype->der;
1032 stype->base = yang->base;
1033 lydict_remove(ctx, yang->name);
1034 free(yang);
1035 } else if (stype->base == LY_TYPE_UNION) {
1036 yang_free_type_union(ctx, stype);
1037 }
1038 }
1039}
1040
Pavol Vican73e7c992016-02-24 12:18:05 +01001041void *
Pavol Vican5f0316a2016-04-05 21:21:11 +02001042yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +01001043{
1044 struct yang_type *typ;
PavolVican75af21d2016-12-29 20:04:07 +01001045 struct lys_deviate *dev;
Pavol Vican73e7c992016-02-24 12:18:05 +01001046
Pavol Vicand01d8ae2016-03-01 10:45:59 +01001047 typ = calloc(1, sizeof *typ);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001048 LY_CHECK_ERR_RETURN(!typ, LOGMEM, NULL);
Pavol Vican73e7c992016-02-24 12:18:05 +01001049
1050 typ->flags = LY_YANG_STRUCTURE_FLAG;
1051 switch (type) {
1052 case LEAF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001053 if (((struct lys_node_leaf *)parent)->type.der) {
1054 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf");
1055 goto error;
1056 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001057 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
1058 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
1059 typ->type = &((struct lys_node_leaf *)parent)->type;
1060 break;
Pavol Vicana55992a2016-03-01 13:37:17 +01001061 case LEAF_LIST_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001062 if (((struct lys_node_leaflist *)parent)->type.der) {
1063 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, parent, "type", "leaf-list");
1064 goto error;
1065 }
Pavol Vicana55992a2016-03-01 13:37:17 +01001066 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
1067 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
1068 typ->type = &((struct lys_node_leaflist *)parent)->type;
1069 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +01001070 case UNION_KEYWORD:
1071 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1072 typ->type = (struct lys_type *)parent;
1073 break;
Pavol Vican0df02b02016-03-01 10:28:50 +01001074 case TYPEDEF_KEYWORD:
Pavol Vican85427f02016-09-26 15:21:05 +02001075 if (((struct lys_tpdf *)parent)->type.der) {
1076 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "typedef");
1077 goto error;
1078 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001079 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
1080 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001081 break;
1082 case REPLACE_KEYWORD:
1083 /* deviation replace type*/
PavolVican75af21d2016-12-29 20:04:07 +01001084 dev = (struct lys_deviate *)parent;
1085 if (dev->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001086 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +01001087 goto error;
1088 }
PavolVican75af21d2016-12-29 20:04:07 +01001089 dev->type = calloc(1, sizeof *dev->type);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001090 LY_CHECK_ERR_GOTO(!dev->type, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001091 dev->type->der = (struct lys_tpdf *)typ;
1092 typ->type = dev->type;
Pavol Vican4766aca2016-03-07 12:42:36 +01001093 break;
PavolVicana0fdbf32017-02-15 17:59:02 +01001094 case EXTENSION_INSTANCE:
1095 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
1096 typ->type = parent;
1097 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +02001098 default:
1099 goto error;
1100 break;
Pavol Vican73e7c992016-02-24 12:18:05 +01001101 }
Pavol Vican5f0316a2016-04-05 21:21:11 +02001102 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +01001103 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +01001104
1105error:
Pavol Vican5f0316a2016-04-05 21:21:11 +02001106 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +01001107 free(typ);
1108 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001109}
1110
1111void *
PavolVicaneef1d912017-02-19 00:19:15 +01001112yang_read_length(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vican73e7c992016-02-24 12:18:05 +01001113{
PavolVicaneef1d912017-02-19 00:19:15 +01001114 struct lys_restr *length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001115
PavolVicaneef1d912017-02-19 00:19:15 +01001116 if (is_ext_instance) {
1117 length = (struct lys_restr *)stype;
Pavol Vican73e7c992016-02-24 12:18:05 +01001118 } else {
PavolVicaneef1d912017-02-19 00:19:15 +01001119 if (stype->base == 0 || stype->base == LY_TYPE_STRING) {
1120 stype->base = LY_TYPE_STRING;
1121 } else {
1122 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
1123 goto error;
1124 }
Pavol Vican73e7c992016-02-24 12:18:05 +01001125
PavolVicaneef1d912017-02-19 00:19:15 +01001126 if (stype->type->info.str.length) {
1127 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
1128 goto error;
1129 }
1130 length = calloc(1, sizeof *length);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001131 LY_CHECK_ERR_GOTO(!length, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001132 stype->type->info.str.length = length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001133 }
PavolVicaneef1d912017-02-19 00:19:15 +01001134 length->expr = lydict_insert_zc(module->ctx, value);
1135 return length;
Pavol Vican73e7c992016-02-24 12:18:05 +01001136
1137error:
1138 free(value);
1139 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +01001140}
Pavol Vican1c203db2016-02-24 14:05:23 +01001141
Pavol Vican6eecf302016-08-10 11:09:05 +02001142int
1143yang_read_pattern(struct lys_module *module, struct lys_restr *pattern, char *value, char modifier)
Pavol Vican1c203db2016-02-24 14:05:23 +01001144{
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001145 char *buf;
1146 size_t len;
1147
Michal Vasko0aee5c12016-06-17 14:27:26 +02001148 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001149 free(value);
Pavol Vican6eecf302016-08-10 11:09:05 +02001150 return EXIT_FAILURE;
Pavol Vican1c203db2016-02-24 14:05:23 +01001151 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001152
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001153 len = strlen(value);
1154 buf = malloc((len + 2) * sizeof *buf); /* modifier byte + value + terminating NULL byte */
Radek Krejcia8d111f2017-05-31 13:57:37 +02001155 LY_CHECK_ERR_RETURN(!buf, LOGMEM; free(value), EXIT_FAILURE);
Pavol Vican6eecf302016-08-10 11:09:05 +02001156
1157 buf[0] = modifier;
Radek Krejci0d23e7a2016-08-04 12:46:17 +02001158 strcpy(&buf[1], value);
1159 free(value);
1160
Pavol Vican6eecf302016-08-10 11:09:05 +02001161 pattern->expr = lydict_insert_zc(module->ctx, buf);
1162 return EXIT_SUCCESS;
Pavol Vican1c203db2016-02-24 14:05:23 +01001163}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001164
1165void *
PavolVicaneef1d912017-02-19 00:19:15 +01001166yang_read_range(struct lys_module *module, struct yang_type *stype, char *value, int is_ext_instance)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001167{
PavolVicaneef1d912017-02-19 00:19:15 +01001168 struct lys_restr * range;
1169
1170 if (is_ext_instance) {
1171 range = (struct lys_restr *)stype;
1172 } else {
1173 if (stype->base != 0 && stype->base != LY_TYPE_DEC64) {
1174 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
1175 goto error;
1176 }
1177 stype->base = LY_TYPE_DEC64;
1178 if (stype->type->info.dec64.range) {
1179 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
1180 goto error;
1181 }
1182 range = calloc(1, sizeof *range);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001183 LY_CHECK_ERR_GOTO(!range, LOGMEM, error);
PavolVicaneef1d912017-02-19 00:19:15 +01001184 stype->type->info.dec64.range = range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001185 }
PavolVicaneef1d912017-02-19 00:19:15 +01001186 range->expr = lydict_insert_zc(module->ctx, value);
1187 return range;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001188
1189error:
1190 free(value);
1191 return NULL;
1192}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001193
1194int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001195yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001196{
Pavol Vican6b072512016-04-04 10:50:21 +02001197 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1198 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001199 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001200 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001201 goto error;
1202 }
1203 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001204 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001205 goto error;
1206 }
1207 /* range check */
1208 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001209 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001210 goto error;
1211 }
1212 typ->type->info.dec64.dig = value;
1213 return EXIT_SUCCESS;
1214
1215error:
1216 return EXIT_FAILURE;
1217}
Pavol Vican79a763d2016-02-25 15:41:27 +01001218
Pavol Vican874715f2016-10-25 14:52:08 +02001219int
1220yang_read_enum(struct lys_module *module, struct yang_type *typ, struct lys_type_enum *enm, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001221{
Pavol Vican874715f2016-10-25 14:52:08 +02001222 int i, j;
Pavol Vican79a763d2016-02-25 15:41:27 +01001223
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01001224 typ->base = LY_TYPE_ENUM;
Pavol Vicanc6662412016-08-30 08:06:28 +02001225 if (!value[0]) {
1226 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "enum name");
1227 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Enum name must not be empty.");
1228 free(value);
1229 goto error;
1230 }
1231
Pavol Vican79a763d2016-02-25 15:41:27 +01001232 enm->name = lydict_insert_zc(module->ctx, value);
1233
1234 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1235 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001236 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001237 goto error;
1238 }
1239
Pavol Vican874715f2016-10-25 14:52:08 +02001240 j = typ->type->info.enums.count - 1;
Pavol Vican79a763d2016-02-25 15:41:27 +01001241 /* check the name uniqueness */
Pavol Vican874715f2016-10-25 14:52:08 +02001242 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001243 if (ly_strequal(typ->type->info.enums.enm[i].name, enm->name, 1)) {
1244 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001245 goto error;
1246 }
1247 }
1248
Pavol Vican874715f2016-10-25 14:52:08 +02001249 return EXIT_SUCCESS;
Pavol Vican79a763d2016-02-25 15:41:27 +01001250
1251error:
Pavol Vican874715f2016-10-25 14:52:08 +02001252 return EXIT_FAILURE;
Pavol Vican79a763d2016-02-25 15:41:27 +01001253}
1254
1255int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001256yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001257{
1258 int i, j;
1259
1260 if (!assign) {
1261 /* assign value automatically */
1262 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001263 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001264 goto error;
1265 }
1266 enm->value = *value;
1267 enm->flags |= LYS_AUTOASSIGNED;
1268 (*value)++;
Pavol Vican5de389c2016-08-30 08:55:15 +02001269 } else if (typ->type->info.enums.enm == enm) {
1270 /* change value, which is assigned automatically, if first enum has value. */
1271 *value = typ->type->info.enums.enm[0].value;
1272 (*value)++;
Pavol Vican79a763d2016-02-25 15:41:27 +01001273 }
1274
1275 /* check that the value is unique */
1276 j = typ->type->info.enums.count-1;
1277 for (i = 0; i < j; i++) {
1278 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001279 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Radek Krejcie663e012016-08-01 17:12:34 +02001280 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name,
1281 typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001282 goto error;
1283 }
1284 }
1285
1286 return EXIT_SUCCESS;
1287
1288error:
1289 return EXIT_FAILURE;
1290}
Pavol Vican9887c682016-02-29 11:32:01 +01001291
Pavol Vican59e8dee2016-10-25 15:29:38 +02001292int
1293yang_read_bit(struct lys_module *module, struct yang_type *typ, struct lys_type_bit *bit, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001294{
Pavol Vican59e8dee2016-10-25 15:29:38 +02001295 int i, j;
Pavol Vican9887c682016-02-29 11:32:01 +01001296
PavolVicane87cb932016-12-30 15:36:18 +01001297 typ->base = LY_TYPE_BITS;
Pavol Vican59e8dee2016-10-25 15:29:38 +02001298 bit->name = lydict_insert_zc(module->ctx, value);
1299 if (lyp_check_identifier(bit->name, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001300 goto error;
1301 }
Pavol Vican9887c682016-02-29 11:32:01 +01001302
Pavol Vican59e8dee2016-10-25 15:29:38 +02001303 j = typ->type->info.bits.count - 1;
Pavol Vican9887c682016-02-29 11:32:01 +01001304 /* check the name uniqueness */
Pavol Vican59e8dee2016-10-25 15:29:38 +02001305 for (i = 0; i < j; i++) {
PavolVican4b80d042017-02-23 14:30:27 +01001306 if (ly_strequal(typ->type->info.bits.bit[i].name, bit->name, 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001307 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001308 goto error;
1309 }
1310 }
Pavol Vican59e8dee2016-10-25 15:29:38 +02001311 return EXIT_SUCCESS;
Pavol Vican9887c682016-02-29 11:32:01 +01001312
1313error:
Pavol Vican59e8dee2016-10-25 15:29:38 +02001314 return EXIT_FAILURE;
Pavol Vican9887c682016-02-29 11:32:01 +01001315}
1316
1317int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001318yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001319{
1320 int i,j;
Pavol Vican9887c682016-02-29 11:32:01 +01001321
1322 if (!assign) {
1323 /* assign value automatically */
1324 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001325 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001326 goto error;
1327 }
1328 bit->pos = (uint32_t)*value;
1329 bit->flags |= LYS_AUTOASSIGNED;
1330 (*value)++;
1331 }
1332
1333 j = typ->type->info.bits.count - 1;
1334 /* check that the value is unique */
1335 for (i = 0; i < j; i++) {
1336 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Radek Krejcie663e012016-08-01 17:12:34 +02001337 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 +01001338 goto error;
1339 }
1340 }
1341
Pavol Vican9887c682016-02-29 11:32:01 +01001342 return EXIT_SUCCESS;
1343
1344error:
1345 return EXIT_FAILURE;
1346}
Pavol Vican0df02b02016-03-01 10:28:50 +01001347
Pavol Vican3ad50f82016-12-04 15:00:36 +01001348int
1349yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001350{
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001351 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001352 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001353 free(value);
1354 if (!aug->target_name) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01001355 return EXIT_FAILURE;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001356 }
1357 aug->parent = parent;
1358 aug->module = module;
Pavol Vican3ad50f82016-12-04 15:00:36 +01001359 return EXIT_SUCCESS;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001360}
Pavol Vican220e5a12016-03-03 14:19:43 +01001361
PavolVican6f000922017-02-10 12:56:59 +01001362void *
PavolVican75af21d2016-12-29 20:04:07 +01001363yang_read_deviate_unsupported(struct lys_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001364{
PavolVican75af21d2016-12-29 20:04:07 +01001365 if (dev->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001366 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican6f000922017-02-10 12:56:59 +01001367 return NULL;
Pavol Vican220e5a12016-03-03 14:19:43 +01001368 }
PavolVican75af21d2016-12-29 20:04:07 +01001369 dev->deviate = calloc(1, sizeof *dev->deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001370 LY_CHECK_ERR_RETURN(!dev->deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001371 dev->deviate[dev->deviate_size].mod = LY_DEVIATE_NO;
1372 dev->deviate_size = 1;
PavolVican6f000922017-02-10 12:56:59 +01001373 return dev->deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001374}
1375
1376void *
PavolVican75af21d2016-12-29 20:04:07 +01001377yang_read_deviate(struct lys_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican220e5a12016-03-03 14:19:43 +01001378{
PavolVican75af21d2016-12-29 20:04:07 +01001379 struct lys_deviate *deviate;
Pavol Vican220e5a12016-03-03 14:19:43 +01001380
PavolVican4b80d042017-02-23 14:30:27 +01001381 if (dev->deviate_size && dev->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001382 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1383 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
PavolVican75af21d2016-12-29 20:04:07 +01001384 return NULL;
Pavol Vican85f12022016-03-05 16:30:35 +01001385 }
PavolVican75af21d2016-12-29 20:04:07 +01001386 if (!(dev->deviate_size % LY_YANG_ARRAY_SIZE)) {
1387 deviate = realloc(dev->deviate, (LY_YANG_ARRAY_SIZE + dev->deviate_size) * sizeof *deviate);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001388 LY_CHECK_ERR_RETURN(!deviate, LOGMEM, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001389 memset(deviate + dev->deviate_size, 0, LY_YANG_ARRAY_SIZE * sizeof *deviate);
1390 dev->deviate = deviate;
Pavol Vican85f12022016-03-05 16:30:35 +01001391 }
PavolVican75af21d2016-12-29 20:04:07 +01001392 dev->deviate[dev->deviate_size].mod = mod;
1393 return &dev->deviate[dev->deviate_size++];
Pavol Vican85f12022016-03-05 16:30:35 +01001394}
1395
1396int
PavolVican75af21d2016-12-29 20:04:07 +01001397yang_read_deviate_units(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001398{
1399 const char **stritem;
PavolVican6f000922017-02-10 12:56:59 +01001400 int j;
Pavol Vican85f12022016-03-05 16:30:35 +01001401
Pavol Vican85f12022016-03-05 16:30:35 +01001402 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001403 if (dev_target->nodetype == LYS_LEAFLIST) {
1404 stritem = &((struct lys_node_leaflist *)dev_target)->units;
1405 } else if (dev_target->nodetype == LYS_LEAF) {
1406 stritem = &((struct lys_node_leaf *)dev_target)->units;
Pavol Vican85f12022016-03-05 16:30:35 +01001407 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001408 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1409 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001410 goto error;
1411 }
1412
PavolVican75af21d2016-12-29 20:04:07 +01001413 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001414 /* check values */
PavolVican75af21d2016-12-29 20:04:07 +01001415 if (!ly_strequal(*stritem, deviate->units, 1)) {
1416 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->units, "units");
Pavol Vican0adf01d2016-03-22 12:29:33 +01001417 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001418 goto error;
1419 }
1420 /* remove current units value of the target */
1421 lydict_remove(ctx, *stritem);
PavolVican6f000922017-02-10 12:56:59 +01001422 *stritem = NULL;
1423 /* remove its extensions */
1424 j = -1;
1425 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_UNITS)) != -1) {
1426 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1427 --j;
1428 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001429 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001430 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001431 /* check that there is no current value */
1432 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001433 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1434 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001435 goto error;
1436 }
1437 } else { /* replace */
1438 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001439 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1440 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001441 goto error;
1442 }
1443 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001444 /* remove current units value of the target ... */
1445 lydict_remove(ctx, *stritem);
1446
1447 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001448 *stritem = lydict_insert(ctx, deviate->units, 0);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001449 }
1450
Pavol Vican85f12022016-03-05 16:30:35 +01001451 return EXIT_SUCCESS;
1452
1453error:
1454 return EXIT_FAILURE;
1455}
1456
1457int
PavolVican75af21d2016-12-29 20:04:07 +01001458yang_read_deviate_unique(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001459{
Pavol Vican85f12022016-03-05 16:30:35 +01001460 struct lys_node_list *list;
PavolVican75af21d2016-12-29 20:04:07 +01001461 struct lys_unique *unique;
Pavol Vican85f12022016-03-05 16:30:35 +01001462
1463 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001464 if (dev_target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001465 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1466 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001467 goto error;
1468 }
1469
PavolVican75af21d2016-12-29 20:04:07 +01001470 list = (struct lys_node_list *)dev_target;
1471 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001472 /* reallocate the unique array of the target */
PavolVican75af21d2016-12-29 20:04:07 +01001473 unique = ly_realloc(list->unique, (deviate->unique_size + list->unique_size) * sizeof *unique);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001474 LY_CHECK_ERR_GOTO(!unique, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001475 list->unique = unique;
1476 memset(unique + list->unique_size, 0, deviate->unique_size * sizeof *unique);
Pavol Vican85f12022016-03-05 16:30:35 +01001477 }
1478
1479 return EXIT_SUCCESS;
1480
1481error:
1482 return EXIT_FAILURE;
1483}
1484
1485int
PavolVican75af21d2016-12-29 20:04:07 +01001486yang_fill_deviate_default(struct ly_ctx *ctx, struct lys_deviate *deviate, struct lys_node *dev_target,
1487 struct ly_set *dflt_check, const char *value)
Pavol Vican38321d02016-08-16 14:56:02 +02001488{
1489 struct lys_node *node;
1490 struct lys_node_choice *choice;
1491 struct lys_node_leaf *leaf;
1492 struct lys_node_leaflist *llist;
PavolVican6f000922017-02-10 12:56:59 +01001493 int rc, i, j;
Pavol Vican38321d02016-08-16 14:56:02 +02001494 unsigned int u;
Pavol Vican38321d02016-08-16 14:56:02 +02001495
Pavol Vican38321d02016-08-16 14:56:02 +02001496 u = strlen(value);
PavolVican75af21d2016-12-29 20:04:07 +01001497 if (dev_target->nodetype == LYS_CHOICE) {
1498 choice = (struct lys_node_choice *)dev_target;
Pavol Vican38321d02016-08-16 14:56:02 +02001499 rc = resolve_choice_default_schema_nodeid(value, choice->child, (const struct lys_node **)&node);
1500 if (rc || !node) {
1501 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1502 goto error;
1503 }
PavolVican75af21d2016-12-29 20:04:07 +01001504 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001505 if (!choice->dflt || (choice->dflt != node)) {
1506 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1507 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1508 goto error;
1509 }
PavolVican6f000922017-02-10 12:56:59 +01001510 choice->dflt = NULL;
1511 /* remove extensions of this default instance from the target node */
1512 j = -1;
1513 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1514 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1515 --j;
1516 }
Pavol Vican38321d02016-08-16 14:56:02 +02001517 } else { /* add or replace */
1518 choice->dflt = node;
1519 if (!choice->dflt) {
1520 /* default branch not found */
1521 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1522 goto error;
1523 }
1524 }
PavolVican75af21d2016-12-29 20:04:07 +01001525 } else if (dev_target->nodetype == LYS_LEAF) {
1526 leaf = (struct lys_node_leaf *)dev_target;
1527 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001528 if (!leaf->dflt || !ly_strequal(leaf->dflt, value, 1)) {
1529 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1530 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
1531 goto error;
1532 }
1533 /* remove value */
1534 lydict_remove(ctx, leaf->dflt);
1535 leaf->dflt = NULL;
Radek Krejcibd117f02016-11-04 16:28:08 +01001536 leaf->flags &= ~LYS_DFLTJSON;
PavolVican6f000922017-02-10 12:56:59 +01001537 /* remove extensions of this default instance from the target node */
1538 j = -1;
1539 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1540 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1541 --j;
1542 }
Pavol Vican38321d02016-08-16 14:56:02 +02001543 } else { /* add (already checked) and replace */
1544 /* remove value */
1545 lydict_remove(ctx, leaf->dflt);
Radek Krejcibd117f02016-11-04 16:28:08 +01001546 leaf->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001547
1548 /* set new value */
1549 leaf->dflt = lydict_insert(ctx, value, u);
1550
1551 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001552 ly_set_add(dflt_check, dev_target, 0);
Pavol Vican38321d02016-08-16 14:56:02 +02001553 }
1554 } else { /* LYS_LEAFLIST */
PavolVican75af21d2016-12-29 20:04:07 +01001555 llist = (struct lys_node_leaflist *)dev_target;
1556 if (deviate->mod == LY_DEVIATE_DEL) {
Pavol Vican38321d02016-08-16 14:56:02 +02001557 /* find and remove the value in target list */
1558 for (i = 0; i < llist->dflt_size; i++) {
1559 if (llist->dflt[i] && ly_strequal(llist->dflt[i], value, 1)) {
1560 /* match, remove the value */
1561 lydict_remove(llist->module->ctx, llist->dflt[i]);
1562 llist->dflt[i] = NULL;
PavolVican6f000922017-02-10 12:56:59 +01001563 /* remove extensions of this default instance from the target node */
1564 j = -1;
1565 while ((j = lys_ext_iter(dev_target->ext, dev_target->ext_size, j + 1, LYEXT_SUBSTMT_DEFAULT)) != -1) {
1566 if (dev_target->ext[j]->insubstmt_index == i) {
1567 lyp_ext_instance_rm(ctx, &dev_target->ext, &dev_target->ext_size, j);
1568 --j;
1569 } else if (dev_target->ext[j]->insubstmt_index > i) {
1570 /* decrease the substatement index of the extension because of the changed array of defaults */
1571 dev_target->ext[j]->insubstmt_index--;
1572 }
1573 }
Pavol Vican38321d02016-08-16 14:56:02 +02001574 break;
1575 }
1576 }
1577 if (i == llist->dflt_size) {
1578 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1579 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The default value to delete not found in the target node.");
1580 goto error;
1581 }
1582 } else {
1583 /* add or replace, anyway we place items into the deviate's list
1584 which propagates to the target */
1585 /* we just want to check that the value isn't already in the list */
1586 for (i = 0; i < llist->dflt_size; i++) {
1587 if (ly_strequal(llist->dflt[i], value, 1)) {
1588 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
1589 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", value);
1590 goto error;
1591 }
1592 }
1593 /* store it in target node */
1594 llist->dflt[llist->dflt_size++] = lydict_insert(ctx, value, u);
1595
1596 /* remember to check it later (it may not fit now, but the type can be deviated too) */
PavolVican75af21d2016-12-29 20:04:07 +01001597 ly_set_add(dflt_check, dev_target, 0);
Radek Krejcibd117f02016-11-04 16:28:08 +01001598 llist->flags &= ~LYS_DFLTJSON;
Pavol Vican38321d02016-08-16 14:56:02 +02001599 }
1600 }
1601
1602 return EXIT_SUCCESS;
1603error:
1604 return EXIT_FAILURE;
1605}
1606
Pavol Vican38321d02016-08-16 14:56:02 +02001607int
PavolVican75af21d2016-12-29 20:04:07 +01001608yang_read_deviate_default(struct lys_module *module, struct lys_deviate *deviate,
1609 struct lys_node *dev_target, struct ly_set * dflt_check)
Pavol Vican85f12022016-03-05 16:30:35 +01001610{
PavolVican75af21d2016-12-29 20:04:07 +01001611 int i;
1612 struct lys_node_leaflist *llist;
1613 const char **dflt;
1614
1615 /* check target node type */
1616 if (module->version < 2 && dev_target->nodetype == LYS_LEAFLIST) {
1617 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1618 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
1619 goto error;
1620 } else if (deviate->dflt_size > 1 && dev_target->nodetype != LYS_LEAFLIST) { /* from YANG 1.1 */
1621 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1622 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow multiple \"default\" properties.");
1623 goto error;
1624 } else if (!(dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) {
1625 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1626 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001627 goto error;
1628 }
1629
PavolVican75af21d2016-12-29 20:04:07 +01001630 if (deviate->mod == LY_DEVIATE_ADD) {
1631 /* check that there is no current value */
1632 if ((dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) ||
1633 (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt)) {
1634 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1635 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
1636 goto error;
1637 }
Pavol Vican85f12022016-03-05 16:30:35 +01001638
PavolVican75af21d2016-12-29 20:04:07 +01001639 /* check collision with mandatory/min-elements */
1640 if ((dev_target->flags & LYS_MAND_TRUE) ||
1641 (dev_target->nodetype == LYS_LEAFLIST && ((struct lys_node_leaflist *)dev_target)->min)) {
1642 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "deviation");
1643 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
1644 "Adding the \"default\" statement is forbidden on %s statement.",
1645 (dev_target->flags & LYS_MAND_TRUE) ? "nodes with the \"mandatory\"" : "leaflists with non-zero \"min-elements\"");
1646 goto error;
1647 }
1648 } else if (deviate->mod == LY_DEVIATE_RPL) {
1649 /* check that there was a value before */
1650 if (((dev_target->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && !((struct lys_node_leaf *)dev_target)->dflt) ||
1651 (dev_target->nodetype == LYS_CHOICE && !((struct lys_node_choice *)dev_target)->dflt)) {
1652 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1653 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
1654 goto error;
1655 }
1656 }
Pavol Vican85f12022016-03-05 16:30:35 +01001657
PavolVican75af21d2016-12-29 20:04:07 +01001658 if (dev_target->nodetype == LYS_LEAFLIST) {
1659 /* reallocate default list in the target */
1660 llist = (struct lys_node_leaflist *)dev_target;
1661 if (deviate->mod == LY_DEVIATE_ADD) {
1662 /* reallocate (enlarge) the unique array of the target */
1663 dflt = realloc(llist->dflt, (deviate->dflt_size + llist->dflt_size) * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001664 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001665 llist->dflt = dflt;
1666 } else if (deviate->mod == LY_DEVIATE_RPL) {
1667 /* reallocate (replace) the unique array of the target */
1668 for (i = 0; i < llist->dflt_size; i++) {
1669 lydict_remove(llist->module->ctx, llist->dflt[i]);
1670 }
1671 dflt = realloc(llist->dflt, deviate->dflt_size * sizeof *dflt);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001672 LY_CHECK_ERR_GOTO(!dflt, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001673 llist->dflt = dflt;
1674 llist->dflt_size = 0;
1675 }
1676 }
1677
1678 for (i = 0; i < deviate->dflt_size; ++i) {
1679 if (yang_fill_deviate_default(module->ctx, deviate, dev_target, dflt_check, deviate->dflt[i])) {
1680 goto error;
1681 }
1682 }
Pavol Vican85f12022016-03-05 16:30:35 +01001683
1684 return EXIT_SUCCESS;
1685
1686error:
1687 return EXIT_FAILURE;
1688}
1689
1690int
PavolVican75af21d2016-12-29 20:04:07 +01001691yang_check_deviate_mandatory(struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vican85f12022016-03-05 16:30:35 +01001692{
Radek Krejcie00d2312016-08-12 15:27:49 +02001693 struct lys_node *parent;
1694
Pavol Vican85f12022016-03-05 16:30:35 +01001695 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001696 if (!(dev_target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001697 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1698 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001699 goto error;
1700 }
1701
PavolVican75af21d2016-12-29 20:04:07 +01001702 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001703 /* check that there is no current value */
PavolVican75af21d2016-12-29 20:04:07 +01001704 if (dev_target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001705 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1706 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001707 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001708 } else {
PavolVican75af21d2016-12-29 20:04:07 +01001709 if (dev_target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001710 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1711 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1712 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1713 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01001714 } else if (dev_target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev_target)->dflt) {
Pavol Vican321a02e2016-04-05 16:11:59 +02001715 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1716 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1717 goto error;
1718 }
Pavol Vican85f12022016-03-05 16:30:35 +01001719 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001720 } else { /* replace */
PavolVican75af21d2016-12-29 20:04:07 +01001721 if (!(dev_target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001722 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1723 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001724 goto error;
1725 }
Pavol Vican85f12022016-03-05 16:30:35 +01001726 }
1727
Pavol Vican85f12022016-03-05 16:30:35 +01001728 /* remove current mandatory value of the target ... */
PavolVican75af21d2016-12-29 20:04:07 +01001729 dev_target->flags &= ~LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001730
1731 /* ... and replace it with the value specified in deviation */
PavolVican75af21d2016-12-29 20:04:07 +01001732 dev_target->flags |= deviate->flags & LYS_MAND_MASK;
Pavol Vican85f12022016-03-05 16:30:35 +01001733
Radek Krejcie00d2312016-08-12 15:27:49 +02001734 /* check for mandatory node in default case, first find the closest parent choice to the changed node */
PavolVican75af21d2016-12-29 20:04:07 +01001735 for (parent = dev_target->parent;
Radek Krejcie00d2312016-08-12 15:27:49 +02001736 parent && !(parent->nodetype & (LYS_CHOICE | LYS_GROUPING | LYS_ACTION));
1737 parent = parent->parent) {
1738 if (parent->nodetype == LYS_CONTAINER && ((struct lys_node_container *)parent)->presence) {
1739 /* stop also on presence containers */
1740 break;
1741 }
1742 }
1743 /* and if it is a choice with the default case, check it for presence of a mandatory node in it */
1744 if (parent && parent->nodetype == LYS_CHOICE && ((struct lys_node_choice *)parent)->dflt) {
1745 if (lyp_check_mandatory_choice(parent)) {
1746 goto error;
1747 }
1748 }
1749
Pavol Vican85f12022016-03-05 16:30:35 +01001750 return EXIT_SUCCESS;
1751
1752error:
1753 return EXIT_FAILURE;
1754}
1755
1756int
PavolVican75af21d2016-12-29 20:04:07 +01001757yang_read_deviate_minmax(struct lys_deviate *deviate, struct lys_node *dev_target, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001758{
Pavol Vican09adcc32016-08-25 10:51:36 +02001759 uint32_t *ui32val, *min, *max;
Pavol Vican85f12022016-03-05 16:30:35 +01001760
1761 /* check target node type */
PavolVican75af21d2016-12-29 20:04:07 +01001762 if (dev_target->nodetype == LYS_LEAFLIST) {
1763 max = &((struct lys_node_leaflist *)dev_target)->max;
1764 min = &((struct lys_node_leaflist *)dev_target)->min;
1765 } else if (dev_target->nodetype == LYS_LIST) {
1766 max = &((struct lys_node_list *)dev_target)->max;
1767 min = &((struct lys_node_list *)dev_target)->min;
Pavol Vican85f12022016-03-05 16:30:35 +01001768 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001769 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1770 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 +01001771 goto error;
1772 }
1773
PavolVican75af21d2016-12-29 20:04:07 +01001774 ui32val = (type) ? max : min;
1775 if (deviate->mod == LY_DEVIATE_ADD) {
Pavol Vican85f12022016-03-05 16:30:35 +01001776 /* check that there is no current value */
1777 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001778 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1779 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001780 goto error;
1781 }
PavolVican75af21d2016-12-29 20:04:07 +01001782 } else if (deviate->mod == LY_DEVIATE_RPL) {
Pavol Vican4766aca2016-03-07 12:42:36 +01001783 /* unfortunately, there is no way to check reliably that there
1784 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001785 }
1786
1787 /* add (already checked) and replace */
1788 /* set new value specified in deviation */
1789 *ui32val = value;
1790
Pavol Vican09adcc32016-08-25 10:51:36 +02001791 /* check min-elements is smaller than max-elements */
1792 if (*max && *min > *max) {
1793 if (type) {
1794 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"max-elements\".", value);
1795 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"max-elements\" is smaller than \"min-elements\".");
1796 } else {
1797 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"min-elements\".", value);
1798 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"min-elements\" is bigger than \"max-elements\".");
1799 }
1800 goto error;
1801 }
1802
Pavol Vican85f12022016-03-05 16:30:35 +01001803 return EXIT_SUCCESS;
1804
1805error:
1806 return EXIT_FAILURE;
1807}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001808
1809int
PavolVican75af21d2016-12-29 20:04:07 +01001810yang_check_deviate_must(struct lys_module *module, struct unres_schema *unres,
1811 struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001812{
PavolVican75af21d2016-12-29 20:04:07 +01001813 int i, j, erase_must = 1;
1814 struct lys_restr **trg_must, *must;
PavolVican214408f2017-02-03 11:54:05 +01001815 uint8_t *trg_must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001816
PavolVican75af21d2016-12-29 20:04:07 +01001817 /* check target node type */
1818 switch (dev_target->nodetype) {
1819 case LYS_LEAF:
1820 trg_must = &((struct lys_node_leaf *)dev_target)->must;
1821 trg_must_size = &((struct lys_node_leaf *)dev_target)->must_size;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001822 break;
PavolVican75af21d2016-12-29 20:04:07 +01001823 case LYS_CONTAINER:
1824 trg_must = &((struct lys_node_container *)dev_target)->must;
1825 trg_must_size = &((struct lys_node_container *)dev_target)->must_size;
1826 break;
1827 case LYS_LEAFLIST:
1828 trg_must = &((struct lys_node_leaflist *)dev_target)->must;
1829 trg_must_size = &((struct lys_node_leaflist *)dev_target)->must_size;
1830 break;
1831 case LYS_LIST:
1832 trg_must = &((struct lys_node_list *)dev_target)->must;
1833 trg_must_size = &((struct lys_node_list *)dev_target)->must_size;
1834 break;
1835 case LYS_ANYXML:
1836 case LYS_ANYDATA:
1837 trg_must = &((struct lys_node_anydata *)dev_target)->must;
1838 trg_must_size = &((struct lys_node_anydata *)dev_target)->must_size;
1839 break;
1840 default:
1841 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1842 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
1843 goto error;
1844 }
1845
1846 /* flag will be checked again, clear it for now */
PavolVicancec18782017-01-26 21:48:46 +01001847 dev_target->flags &= ~LYS_XPATH_DEP;
PavolVican75af21d2016-12-29 20:04:07 +01001848
1849 if (deviate->mod == LY_DEVIATE_ADD) {
1850 /* reallocate the must array of the target */
1851 must = ly_realloc(*trg_must, (deviate->must_size + *trg_must_size) * sizeof *must);
Radek Krejcia8d111f2017-05-31 13:57:37 +02001852 LY_CHECK_ERR_GOTO(!must, LOGMEM, error);
PavolVican75af21d2016-12-29 20:04:07 +01001853 *trg_must = must;
PavolVican214408f2017-02-03 11:54:05 +01001854 memcpy(&(*trg_must)[*trg_must_size], deviate->must, deviate->must_size * sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001855 free(deviate->must);
1856 deviate->must = &must[*trg_must_size];
PavolVican214408f2017-02-03 11:54:05 +01001857 *trg_must_size = *trg_must_size + deviate->must_size;
PavolVican75af21d2016-12-29 20:04:07 +01001858 erase_must = 0;
1859 } else if (deviate->mod == LY_DEVIATE_DEL) {
1860 /* find must to delete, we are ok with just matching conditions */
1861 for (j = 0; j < deviate->must_size; ++j) {
1862 for (i = 0; i < *trg_must_size; i++) {
1863 if (ly_strequal(deviate->must[j].expr, (*trg_must)[i].expr, 1)) {
1864 /* we have a match, free the must structure ... */
Radek Krejci5138e9f2017-04-12 13:10:46 +02001865 lys_restr_free(module->ctx, &((*trg_must)[i]), NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001866 /* ... and maintain the array */
1867 (*trg_must_size)--;
1868 if (i != *trg_must_size) {
PavolVican214408f2017-02-03 11:54:05 +01001869 memcpy(&(*trg_must)[i], &(*trg_must)[*trg_must_size], sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001870 }
1871 if (!(*trg_must_size)) {
1872 free(*trg_must);
1873 *trg_must = NULL;
1874 } else {
PavolVican214408f2017-02-03 11:54:05 +01001875 memset(&(*trg_must)[*trg_must_size], 0, sizeof *must);
PavolVican75af21d2016-12-29 20:04:07 +01001876 }
1877
1878 i = -1; /* set match flag */
1879 break;
1880 }
1881 }
1882 if (i != -1) {
1883 /* no match found */
1884 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, deviate->must[j].expr, "must");
1885 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
1886 goto error;
1887 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001888 }
1889 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001890
PavolVican6f000922017-02-10 12:56:59 +01001891 if (yang_check_must(module, deviate->must, deviate->must_size, unres)) {
1892 goto error;
1893 }
PavolVican75af21d2016-12-29 20:04:07 +01001894 /* check XPath dependencies */
Michal Vaskof96dfb62017-08-17 12:23:49 +02001895 if (*trg_must_size && (unres_schema_add_node(module, unres, dev_target, UNRES_XPATH, NULL) == -1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001896 goto error;
1897 }
1898
PavolVican75af21d2016-12-29 20:04:07 +01001899 return EXIT_SUCCESS;
1900error:
1901 if (deviate->mod == LY_DEVIATE_ADD && erase_must) {
1902 for (i = 0; i < deviate->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02001903 lys_restr_free(module->ctx, &deviate->must[i], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01001904 }
1905 free(deviate->must);
1906 }
1907 return EXIT_FAILURE;
1908}
1909
1910int
1911yang_deviate_delete_unique(struct lys_module *module, struct lys_deviate *deviate,
1912 struct lys_node_list *list, int index, char * value)
1913{
PavolVican6f000922017-02-10 12:56:59 +01001914 int i, j, k;
PavolVican75af21d2016-12-29 20:04:07 +01001915
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001916 /* find unique structures to delete */
1917 for (i = 0; i < list->unique_size; i++) {
PavolVican75af21d2016-12-29 20:04:07 +01001918 if (list->unique[i].expr_size != deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001919 continue;
1920 }
1921
PavolVican75af21d2016-12-29 20:04:07 +01001922 for (j = 0; j < deviate->unique[index].expr_size; j++) {
1923 if (!ly_strequal(list->unique[i].expr[j], deviate->unique[index].expr[j], 1)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001924 break;
1925 }
1926 }
1927
PavolVican75af21d2016-12-29 20:04:07 +01001928 if (j == deviate->unique[index].expr_size) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001929 /* we have a match, free the unique structure ... */
1930 for (j = 0; j < list->unique[i].expr_size; j++) {
1931 lydict_remove(module->ctx, list->unique[i].expr[j]);
1932 }
1933 free(list->unique[i].expr);
1934 /* ... and maintain the array */
1935 list->unique_size--;
1936 if (i != list->unique_size) {
1937 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1938 list->unique[i].expr = list->unique[list->unique_size].expr;
1939 }
1940
1941 if (!list->unique_size) {
1942 free(list->unique);
1943 list->unique = NULL;
1944 } else {
1945 list->unique[list->unique_size].expr_size = 0;
1946 list->unique[list->unique_size].expr = NULL;
1947 }
1948
PavolVican6f000922017-02-10 12:56:59 +01001949 k = i; /* remember index for removing extensions */
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001950 i = -1; /* set match flag */
1951 break;
1952 }
1953 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001954
1955 if (i != -1) {
1956 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001957 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1958 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
PavolVican75af21d2016-12-29 20:04:07 +01001959 return EXIT_FAILURE;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001960 }
1961
PavolVican6f000922017-02-10 12:56:59 +01001962 /* remove extensions of this unique instance from the target node */
1963 j = -1;
1964 while ((j = lys_ext_iter(list->ext, list->ext_size, j + 1, LYEXT_SUBSTMT_UNIQUE)) != -1) {
1965 if (list->ext[j]->insubstmt_index == k) {
1966 lyp_ext_instance_rm(module->ctx, &list->ext, &list->ext_size, j);
1967 --j;
1968 } else if (list->ext[j]->insubstmt_index > k) {
1969 /* decrease the substatement index of the extension because of the changed array of uniques */
1970 list->ext[j]->insubstmt_index--;
1971 }
1972 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001973 return EXIT_SUCCESS;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001974}
Pavol Vican021488a2016-01-25 23:56:12 +01001975
PavolVican75af21d2016-12-29 20:04:07 +01001976int yang_check_deviate_unique(struct lys_module *module, struct lys_deviate *deviate, struct lys_node *dev_target)
Pavol Vicane92421d2016-03-08 10:12:33 +01001977{
PavolVican75af21d2016-12-29 20:04:07 +01001978 struct lys_node_list *list;
1979 char *str;
PavolVican4b80d042017-02-23 14:30:27 +01001980 uint i = 0;
1981 struct lys_unique *last_unique = NULL;
Pavol Vicane92421d2016-03-08 10:12:33 +01001982
PavolVican75af21d2016-12-29 20:04:07 +01001983 if (yang_read_deviate_unique(deviate, dev_target)) {
1984 goto error;
1985 }
1986 list = (struct lys_node_list *)dev_target;
1987 last_unique = &list->unique[list->unique_size];
1988 for (i = 0; i < deviate->unique_size; ++i) {
1989 str = (char *) deviate->unique[i].expr;
1990 if (deviate->mod == LY_DEVIATE_ADD) {
1991 if (yang_fill_unique(module, list, &list->unique[list->unique_size], str, NULL)) {
1992 free(str);
1993 goto error;
1994 }
1995 list->unique_size++;
1996 } else if (deviate->mod == LY_DEVIATE_DEL) {
1997 if (yang_fill_unique(module, list, &deviate->unique[i], str, NULL)) {
1998 free(str);
1999 goto error;
2000 }
2001 if (yang_deviate_delete_unique(module, deviate, list, i, str)) {
2002 free(str);
2003 goto error;
Pavol Vicane92421d2016-03-08 10:12:33 +01002004 }
2005 }
PavolVican75af21d2016-12-29 20:04:07 +01002006 free(str);
2007 }
2008 if (deviate->mod == LY_DEVIATE_ADD) {
2009 free(deviate->unique);
2010 deviate->unique = last_unique;
Pavol Vicane92421d2016-03-08 10:12:33 +01002011 }
Pavol Vican38321d02016-08-16 14:56:02 +02002012
Pavol Vican38321d02016-08-16 14:56:02 +02002013
PavolVican75af21d2016-12-29 20:04:07 +01002014 return EXIT_SUCCESS;
Pavol Vican021488a2016-01-25 23:56:12 +01002015error:
PavolVican75af21d2016-12-29 20:04:07 +01002016 if (deviate->mod == LY_DEVIATE_ADD) {
2017 for (i = i + 1; i < deviate->unique_size; ++i) {
2018 free(deviate->unique[i].expr);
2019 }
2020 free(deviate->unique);
2021 deviate->unique = last_unique;
2022
2023 }
Pavol Vican021488a2016-01-25 23:56:12 +01002024 return EXIT_FAILURE;
2025}
2026
Pavol Vicanec423c92016-10-24 21:33:43 +02002027static int
2028yang_fill_include(struct lys_module *trg, char *value, struct lys_include *inc,
2029 struct unres_schema *unres)
Pavol Vican021488a2016-01-25 23:56:12 +01002030{
Pavol Vican55870412016-03-10 12:36:21 +01002031 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002032 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002033 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002034
Pavol Vicanec423c92016-10-24 21:33:43 +02002035 str = lydict_insert_zc(trg->ctx, value);
Radek Krejcid4c1d0f2017-01-19 16:11:38 +01002036 rc = lyp_check_include(trg, str, inc, unres);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002037 if (!rc) {
2038 /* success, copy the filled data into the final array */
Pavol Vicane024ab72016-07-27 14:27:43 +02002039 memcpy(&trg->inc[trg->inc_size], inc, sizeof *inc);
PavolVican7d0b5ab2017-02-01 13:06:53 +01002040 if (yang_check_ext_instance(trg, &trg->inc[trg->inc_size].ext, trg->inc[trg->inc_size].ext_size,
2041 &trg->inc[trg->inc_size], unres)) {
2042 ret = -1;
2043 }
Radek Krejci4dcd3392016-06-22 10:28:40 +02002044 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002045 } else if (rc == -1) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002046 lys_extension_instances_free(trg->ctx, inc->ext, inc->ext_size, NULL);
Radek Krejci83e3f5b2016-06-24 14:55:25 +02002047 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002048 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01002049
Pavol Vicanec423c92016-10-24 21:33:43 +02002050 lydict_remove(trg->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02002051 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01002052}
Pavol Vicanf4717e62016-03-16 11:30:01 +01002053
PavolVicanc1807262017-01-31 18:00:27 +01002054struct lys_ext_instance *
PavolVican22e88682017-02-14 22:38:18 +01002055yang_ext_instance(void *node, enum yytokentype type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002056{
2057 struct lys_ext_instance ***ext, **tmp, *instance = NULL;
2058 LYEXT_PAR parent_type;
2059 uint8_t *size;
2060
2061 switch (type) {
2062 case MODULE_KEYWORD:
PavolVicane6fa67b2017-02-01 11:06:57 +01002063 case SUBMODULE_KEYWORD:
PavolVicanc1807262017-01-31 18:00:27 +01002064 ext = &((struct lys_module *)node)->ext;
2065 size = &((struct lys_module *)node)->ext_size;
2066 parent_type = LYEXT_PAR_MODULE;
2067 break;
PavolVican22e88682017-02-14 22:38:18 +01002068 case BELONGS_TO_KEYWORD:
2069 if (is_ext_instance) {
2070 ext = &((struct lys_ext_instance *)node)->ext;
2071 size = &((struct lys_ext_instance *)node)->ext_size;
2072 parent_type = LYEXT_PAR_EXTINST;
2073 } else {
2074 ext = &((struct lys_module *)node)->ext;
2075 size = &((struct lys_module *)node)->ext_size;
2076 parent_type = LYEXT_PAR_MODULE;
2077 }
2078 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002079 case IMPORT_KEYWORD:
2080 ext = &((struct lys_import *)node)->ext;
2081 size = &((struct lys_import *)node)->ext_size;
2082 parent_type = LYEXT_PAR_IMPORT;
2083 break;
2084 case INCLUDE_KEYWORD:
2085 ext = &((struct lys_include *)node)->ext;
2086 size = &((struct lys_include *)node)->ext_size;
2087 parent_type = LYEXT_PAR_INCLUDE;
2088 break;
PavolVican171717d2017-02-01 14:49:55 +01002089 case REVISION_KEYWORD:
2090 ext = &((struct lys_revision *)node)->ext;
2091 size = &((struct lys_revision *)node)->ext_size;
2092 parent_type = LYEXT_PAR_REVISION;
2093 break;
PavolVican70ce7452017-02-01 15:39:39 +01002094 case GROUPING_KEYWORD:
PavolVican59af9be2017-02-01 16:04:37 +01002095 case CONTAINER_KEYWORD:
PavolVicana6c3ac92017-02-03 13:15:13 +01002096 case LEAF_KEYWORD:
2097 case LEAF_LIST_KEYWORD:
2098 case LIST_KEYWORD:
PavolVican91eb04a2017-02-03 13:45:52 +01002099 case CHOICE_KEYWORD:
2100 case CASE_KEYWORD:
2101 case ANYXML_KEYWORD:
2102 case ANYDATA_KEYWORD:
PavolVican07596382017-02-03 14:05:12 +01002103 case USES_KEYWORD:
2104 case AUGMENT_KEYWORD:
PavolVican97d1e6f2017-02-03 14:39:52 +01002105 case ACTION_KEYWORD:
2106 case RPC_KEYWORD:
2107 case INPUT_KEYWORD:
2108 case OUTPUT_KEYWORD:
2109 case NOTIFICATION_KEYWORD:
PavolVican70ce7452017-02-01 15:39:39 +01002110 ext = &((struct lys_node *)node)->ext;
2111 size = &((struct lys_node *)node)->ext_size;
2112 parent_type = LYEXT_PAR_NODE;
2113 break;
PavolVican19dc6152017-02-06 12:04:15 +01002114 case ARGUMENT_KEYWORD:
PavolVican50809742017-02-18 21:22:54 +01002115 if (is_ext_instance) {
2116 ext = &((struct lys_ext_instance *)node)->ext;
2117 size = &((struct lys_ext_instance *)node)->ext_size;
2118 parent_type = LYEXT_PAR_EXTINST;
2119 } else {
2120 ext = &((struct lys_ext *)node)->ext;
2121 size = &((struct lys_ext *)node)->ext_size;
2122 parent_type = LYEXT_PAR_EXT;
2123 }
2124 break;
PavolVican19dc6152017-02-06 12:04:15 +01002125 case EXTENSION_KEYWORD:
2126 ext = &((struct lys_ext *)node)->ext;
2127 size = &((struct lys_ext *)node)->ext_size;
2128 parent_type = LYEXT_PAR_EXT;
2129 break;
PavolVican5393d3f2017-02-06 23:30:55 +01002130 case FEATURE_KEYWORD:
2131 ext = &((struct lys_feature *)node)->ext;
2132 size = &((struct lys_feature *)node)->ext_size;
2133 parent_type = LYEXT_PAR_FEATURE;
2134 break;
PavolVican8fa31242017-02-07 11:04:26 +01002135 case IDENTITY_KEYWORD:
2136 ext = &((struct lys_ident *)node)->ext;
2137 size = &((struct lys_ident *)node)->ext_size;
2138 parent_type = LYEXT_PAR_IDENT;
2139 break;
2140 case IF_FEATURE_KEYWORD:
2141 ext = &((struct lys_iffeature *)node)->ext;
2142 size = &((struct lys_iffeature *)node)->ext_size;
2143 parent_type = LYEXT_PAR_IFFEATURE;
2144 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002145 case TYPEDEF_KEYWORD:
2146 ext = &((struct lys_tpdf *)node)->ext;
2147 size = &((struct lys_tpdf *)node)->ext_size;
2148 parent_type = LYEXT_PAR_TPDF;
2149 break;
PavolVican056fcd12017-02-07 15:36:53 +01002150 case TYPE_KEYWORD:
2151 ext = &((struct yang_type *)node)->type->ext;
2152 size = &((struct yang_type *)node)->type->ext_size;
2153 parent_type = LYEXT_PAR_TYPE;
2154 break;
2155 case LENGTH_KEYWORD:
2156 case PATTERN_KEYWORD:
2157 case RANGE_KEYWORD:
PavolVican38104a32017-02-08 12:25:23 +01002158 case MUST_KEYWORD:
PavolVican056fcd12017-02-07 15:36:53 +01002159 ext = &((struct lys_restr *)node)->ext;
2160 size = &((struct lys_restr *)node)->ext_size;
2161 parent_type = LYEXT_PAR_RESTR;
2162 break;
PavolVican59ba4602017-02-08 11:53:32 +01002163 case WHEN_KEYWORD:
2164 ext = &((struct lys_when *)node)->ext;
2165 size = &((struct lys_when *)node)->ext_size;
2166 parent_type = LYEXT_PAR_RESTR;
2167 break;
PavolVican056fcd12017-02-07 15:36:53 +01002168 case ENUM_KEYWORD:
2169 ext = &((struct lys_type_enum *)node)->ext;
2170 size = &((struct lys_type_enum *)node)->ext_size;
2171 parent_type = LYEXT_PAR_TYPE_ENUM;
2172 break;
2173 case BIT_KEYWORD:
2174 ext = &((struct lys_type_bit *)node)->ext;
2175 size = &((struct lys_type_bit *)node)->ext_size;
2176 parent_type = LYEXT_PAR_TYPE_BIT;
2177 break;
PavolVican77374ee2017-02-08 15:18:45 +01002178 case REFINE_KEYWORD:
2179 ext = &((struct lys_type_bit *)node)->ext;
2180 size = &((struct lys_type_bit *)node)->ext_size;
2181 parent_type = LYEXT_PAR_REFINE;
2182 break;
PavolVican6f000922017-02-10 12:56:59 +01002183 case DEVIATION_KEYWORD:
2184 ext = &((struct lys_deviation *)node)->ext;
2185 size = &((struct lys_deviation *)node)->ext_size;
2186 parent_type = LYEXT_PAR_DEVIATION;
2187 break;
2188 case NOT_SUPPORTED_KEYWORD:
2189 case ADD_KEYWORD:
2190 case DELETE_KEYWORD:
2191 case REPLACE_KEYWORD:
2192 ext = &((struct lys_deviate *)node)->ext;
2193 size = &((struct lys_deviate *)node)->ext_size;
2194 parent_type = LYEXT_PAR_DEVIATE;
2195 break;
PavolVicandefa4852017-02-10 13:13:23 +01002196 case EXTENSION_INSTANCE:
2197 ext = &((struct lys_ext_instance *)node)->ext;
2198 size = &((struct lys_ext_instance *)node)->ext_size;
2199 parent_type = LYEXT_PAR_EXTINST;
2200 break;
PavolVicanc1807262017-01-31 18:00:27 +01002201 default:
2202 LOGINT;
2203 return NULL;
2204 }
2205
2206 instance = calloc(1, sizeof *instance);
2207 if (!instance) {
2208 goto error;
2209 }
2210 instance->parent_type = parent_type;
2211 tmp = realloc(*ext, (*size + 1) * sizeof *tmp);
2212 if (!tmp) {
2213 goto error;
2214 }
2215 tmp[*size] = instance;
2216 *ext = tmp;
2217 (*size)++;
2218 return instance;
2219
2220error:
2221 LOGMEM;
2222 free(instance);
2223 return NULL;
2224}
2225
2226void *
2227yang_read_ext(struct lys_module *module, void *actual, char *ext_name, char *ext_arg,
PavolVican22e88682017-02-14 22:38:18 +01002228 enum yytokentype actual_type, enum yytokentype backup_type, int is_ext_instance)
PavolVicanc1807262017-01-31 18:00:27 +01002229{
2230 struct lys_ext_instance *instance;
PavolVican5334c892017-02-15 16:29:09 +01002231 LY_STMT stmt = LY_STMT_UNKNOWN;
PavolVicanc1807262017-01-31 18:00:27 +01002232
2233 if (backup_type != NODE) {
PavolVican4b80d042017-02-23 14:30:27 +01002234 instance = yang_ext_instance(actual, backup_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002235 if (!instance) {
2236 return NULL;
2237 }
PavolVicanc1807262017-01-31 18:00:27 +01002238 switch (actual_type) {
PavolVicana4b79bc2017-02-08 13:47:00 +01002239 case YANG_VERSION_KEYWORD:
2240 instance->insubstmt = LYEXT_SUBSTMT_VERSION;
PavolVican5334c892017-02-15 16:29:09 +01002241 stmt = LY_STMT_VERSION;
PavolVicana4b79bc2017-02-08 13:47:00 +01002242 break;
PavolVicanc1807262017-01-31 18:00:27 +01002243 case NAMESPACE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002244 instance->insubstmt = LYEXT_SUBSTMT_NAMESPACE;
PavolVican5334c892017-02-15 16:29:09 +01002245 stmt = LY_STMT_NAMESPACE;
PavolVicanc1807262017-01-31 18:00:27 +01002246 break;
PavolVicane6fa67b2017-02-01 11:06:57 +01002247 case PREFIX_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002248 instance->insubstmt = LYEXT_SUBSTMT_PREFIX;
PavolVican5334c892017-02-15 16:29:09 +01002249 stmt = LY_STMT_PREFIX;
PavolVicane6fa67b2017-02-01 11:06:57 +01002250 break;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002251 case REVISION_DATE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002252 instance->insubstmt = LYEXT_SUBSTMT_REVISIONDATE;
PavolVican5334c892017-02-15 16:29:09 +01002253 stmt = LY_STMT_REVISIONDATE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002254 break;
2255 case DESCRIPTION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002256 instance->insubstmt = LYEXT_SUBSTMT_DESCRIPTION;
PavolVican5334c892017-02-15 16:29:09 +01002257 stmt = LY_STMT_DESCRIPTION;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002258 break;
2259 case REFERENCE_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002260 instance->insubstmt = LYEXT_SUBSTMT_REFERENCE;
PavolVican5334c892017-02-15 16:29:09 +01002261 stmt = LY_STMT_REFERENCE;
PavolVican7d0b5ab2017-02-01 13:06:53 +01002262 break;
PavolVican171717d2017-02-01 14:49:55 +01002263 case CONTACT_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002264 instance->insubstmt = LYEXT_SUBSTMT_CONTACT;
PavolVican5334c892017-02-15 16:29:09 +01002265 stmt = LY_STMT_CONTACT;
PavolVican171717d2017-02-01 14:49:55 +01002266 break;
2267 case ORGANIZATION_KEYWORD:
Radek Krejcifebdad72017-02-06 11:35:51 +01002268 instance->insubstmt = LYEXT_SUBSTMT_ORGANIZATION;
PavolVican5334c892017-02-15 16:29:09 +01002269 stmt = LY_STMT_ORGANIZATION;
PavolVican171717d2017-02-01 14:49:55 +01002270 break;
PavolVican19dc6152017-02-06 12:04:15 +01002271 case YIN_ELEMENT_KEYWORD:
2272 instance->insubstmt = LYEXT_SUBSTMT_YINELEM;
PavolVican5334c892017-02-15 16:29:09 +01002273 stmt = LY_STMT_YINELEM;
PavolVican19dc6152017-02-06 12:04:15 +01002274 break;
2275 case STATUS_KEYWORD:
2276 instance->insubstmt = LYEXT_SUBSTMT_STATUS;
PavolVican5334c892017-02-15 16:29:09 +01002277 stmt = LY_STMT_STATUS;
PavolVican19dc6152017-02-06 12:04:15 +01002278 break;
PavolVican8fa31242017-02-07 11:04:26 +01002279 case BASE_KEYWORD:
2280 instance->insubstmt = LYEXT_SUBSTMT_BASE;
PavolVican5334c892017-02-15 16:29:09 +01002281 stmt = LY_STMT_BASE;
PavolVican056fcd12017-02-07 15:36:53 +01002282 if (backup_type == IDENTITY_KEYWORD) {
2283 instance->insubstmt_index = ((struct lys_ident *)actual)->base_size;
PavolVican5334c892017-02-15 16:29:09 +01002284 } else if (backup_type == TYPE_KEYWORD) {
PavolVican056fcd12017-02-07 15:36:53 +01002285 instance->insubstmt_index = ((struct yang_type *)actual)->type->info.ident.count;
2286 }
PavolVican8fa31242017-02-07 11:04:26 +01002287 break;
PavolVicandf9e7972017-02-07 11:41:38 +01002288 case DEFAULT_KEYWORD:
2289 instance->insubstmt = LYEXT_SUBSTMT_DEFAULT;
PavolVican5334c892017-02-15 16:29:09 +01002290 stmt = LY_STMT_DEFAULT;
PavolVican6f000922017-02-10 12:56:59 +01002291 switch (backup_type) {
2292 case LEAF_LIST_KEYWORD:
PavolVican3feb2f92017-02-08 13:44:39 +01002293 instance->insubstmt_index = ((struct lys_node_leaflist *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002294 break;
2295 case REFINE_KEYWORD:
PavolVican77374ee2017-02-08 15:18:45 +01002296 instance->insubstmt_index = ((struct lys_refine *)actual)->dflt_size;
PavolVican6f000922017-02-10 12:56:59 +01002297 break;
2298 case ADD_KEYWORD:
2299 instance->insubstmt_index = ((struct lys_deviate *)actual)->dflt_size;
2300 break;
2301 default:
2302 /* nothing changes */
2303 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002304 }
PavolVicandf9e7972017-02-07 11:41:38 +01002305 break;
2306 case UNITS_KEYWORD:
2307 instance->insubstmt = LYEXT_SUBSTMT_UNITS;
PavolVican5334c892017-02-15 16:29:09 +01002308 stmt = LY_STMT_UNITS;
PavolVicandf9e7972017-02-07 11:41:38 +01002309 break;
PavolVican056fcd12017-02-07 15:36:53 +01002310 case REQUIRE_INSTANCE_KEYWORD:
2311 instance->insubstmt = LYEXT_SUBSTMT_REQINSTANCE;
PavolVican5334c892017-02-15 16:29:09 +01002312 stmt = LY_STMT_REQINSTANCE;
PavolVican056fcd12017-02-07 15:36:53 +01002313 break;
2314 case PATH_KEYWORD:
2315 instance->insubstmt = LYEXT_SUBSTMT_PATH;
PavolVican5334c892017-02-15 16:29:09 +01002316 stmt = LY_STMT_PATH;
PavolVican056fcd12017-02-07 15:36:53 +01002317 break;
2318 case ERROR_MESSAGE_KEYWORD:
2319 instance->insubstmt = LYEXT_SUBSTMT_ERRMSG;
PavolVican5334c892017-02-15 16:29:09 +01002320 stmt = LY_STMT_ERRMSG;
PavolVican056fcd12017-02-07 15:36:53 +01002321 break;
2322 case ERROR_APP_TAG_KEYWORD:
2323 instance->insubstmt = LYEXT_SUBSTMT_ERRTAG;
PavolVican5334c892017-02-15 16:29:09 +01002324 stmt = LY_STMT_ERRTAG;
PavolVican056fcd12017-02-07 15:36:53 +01002325 break;
2326 case MODIFIER_KEYWORD:
2327 instance->insubstmt = LYEXT_SUBSTMT_MODIFIER;
PavolVican5334c892017-02-15 16:29:09 +01002328 stmt = LY_STMT_MODIFIER;
PavolVican056fcd12017-02-07 15:36:53 +01002329 break;
2330 case FRACTION_DIGITS_KEYWORD:
2331 instance->insubstmt = LYEXT_SUBSTMT_DIGITS;
PavolVican5334c892017-02-15 16:29:09 +01002332 stmt = LY_STMT_DIGITS;
PavolVican056fcd12017-02-07 15:36:53 +01002333 break;
2334 case VALUE_KEYWORD:
2335 instance->insubstmt = LYEXT_SUBSTMT_VALUE;
PavolVican5334c892017-02-15 16:29:09 +01002336 stmt = LY_STMT_VALUE;
PavolVican056fcd12017-02-07 15:36:53 +01002337 break;
2338 case POSITION_KEYWORD:
2339 instance->insubstmt = LYEXT_SUBSTMT_POSITION;
PavolVican5334c892017-02-15 16:29:09 +01002340 stmt = LY_STMT_POSITION;
PavolVican056fcd12017-02-07 15:36:53 +01002341 break;
PavolVican5b910842017-02-08 13:08:47 +01002342 case PRESENCE_KEYWORD:
2343 instance->insubstmt = LYEXT_SUBSTMT_PRESENCE;
PavolVican5334c892017-02-15 16:29:09 +01002344 stmt = LY_STMT_PRESENCE;
PavolVican5b910842017-02-08 13:08:47 +01002345 break;
2346 case CONFIG_KEYWORD:
2347 instance->insubstmt = LYEXT_SUBSTMT_CONFIG;
PavolVican5334c892017-02-15 16:29:09 +01002348 stmt = LY_STMT_CONFIG;
PavolVican5b910842017-02-08 13:08:47 +01002349 break;
PavolVican3feb2f92017-02-08 13:44:39 +01002350 case MANDATORY_KEYWORD:
2351 instance->insubstmt = LYEXT_SUBSTMT_MANDATORY;
PavolVican5334c892017-02-15 16:29:09 +01002352 stmt = LY_STMT_MANDATORY;
PavolVican3feb2f92017-02-08 13:44:39 +01002353 break;
2354 case MIN_ELEMENTS_KEYWORD:
2355 instance->insubstmt = LYEXT_SUBSTMT_MIN;
PavolVican5334c892017-02-15 16:29:09 +01002356 stmt = LY_STMT_MIN;
PavolVican3feb2f92017-02-08 13:44:39 +01002357 break;
2358 case MAX_ELEMENTS_KEYWORD:
2359 instance->insubstmt = LYEXT_SUBSTMT_MAX;
PavolVican5334c892017-02-15 16:29:09 +01002360 stmt = LY_STMT_MAX;
PavolVican3feb2f92017-02-08 13:44:39 +01002361 break;
2362 case ORDERED_BY_KEYWORD:
2363 instance->insubstmt = LYEXT_SUBSTMT_ORDEREDBY;
PavolVican5334c892017-02-15 16:29:09 +01002364 stmt = LY_STMT_ORDEREDBY;
PavolVican3feb2f92017-02-08 13:44:39 +01002365 break;
2366 case KEY_KEYWORD:
2367 instance->insubstmt = LYEXT_SUBSTMT_KEY;
PavolVican5334c892017-02-15 16:29:09 +01002368 stmt = LY_STMT_KEY;
PavolVican3feb2f92017-02-08 13:44:39 +01002369 break;
2370 case UNIQUE_KEYWORD:
2371 instance->insubstmt = LYEXT_SUBSTMT_UNIQUE;
PavolVican5334c892017-02-15 16:29:09 +01002372 stmt = LY_STMT_UNIQUE;
2373 switch (backup_type) {
2374 case LIST_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002375 instance->insubstmt_index = ((struct lys_node_list *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002376 break;
2377 case ADD_KEYWORD:
2378 case DELETE_KEYWORD:
2379 case REPLACE_KEYWORD:
PavolVican6f000922017-02-10 12:56:59 +01002380 instance->insubstmt_index = ((struct lys_deviate *)actual)->unique_size;
PavolVican5334c892017-02-15 16:29:09 +01002381 break;
2382 default:
2383 /* nothing changes */
2384 break;
PavolVican6f000922017-02-10 12:56:59 +01002385 }
PavolVican3feb2f92017-02-08 13:44:39 +01002386 break;
PavolVicanc1807262017-01-31 18:00:27 +01002387 default:
2388 LOGINT;
2389 return NULL;
2390 }
2391 } else {
PavolVican4b80d042017-02-23 14:30:27 +01002392 instance = yang_ext_instance(actual, actual_type, is_ext_instance);
PavolVicane6fa67b2017-02-01 11:06:57 +01002393 if (!instance) {
2394 return NULL;
2395 }
Radek Krejcifebdad72017-02-06 11:35:51 +01002396 instance->insubstmt = LYEXT_SUBSTMT_SELF;
PavolVican19dc6152017-02-06 12:04:15 +01002397 switch (actual_type) {
2398 case ARGUMENT_KEYWORD:
2399 instance->insubstmt = LYEXT_SUBSTMT_ARGUMENT;
PavolVican5334c892017-02-15 16:29:09 +01002400 stmt = LY_STMT_ARGUMENT;
PavolVican19dc6152017-02-06 12:04:15 +01002401 break;
PavolVicanfaa49702017-02-06 12:10:59 +01002402 case BELONGS_TO_KEYWORD:
2403 instance->insubstmt = LYEXT_SUBSTMT_BELONGSTO;
PavolVican5334c892017-02-15 16:29:09 +01002404 stmt = LY_STMT_BELONGSTO;
PavolVicanfaa49702017-02-06 12:10:59 +01002405 break;
PavolVican19dc6152017-02-06 12:04:15 +01002406 default:
2407 instance->insubstmt = LYEXT_SUBSTMT_SELF;
2408 break;
2409 }
PavolVicanc1807262017-01-31 18:00:27 +01002410 }
2411 instance->flags |= LYEXT_OPT_YANG;
2412 instance->def = (struct lys_ext *)ext_name; /* hack for UNRES */
2413 instance->arg_value = lydict_insert_zc(module->ctx, ext_arg);
PavolVican5334c892017-02-15 16:29:09 +01002414 if (is_ext_instance && stmt != LY_STMT_UNKNOWN && instance->parent_type == LYEXT_PAR_EXTINST) {
2415 instance->insubstmt_index = yang_fill_ext_substm_index(actual, stmt, backup_type);
2416 }
PavolVicanc1807262017-01-31 18:00:27 +01002417 return instance;
2418}
2419
PavolVican05c4f9b2017-09-07 13:33:54 +02002420static int
2421check_status_flag(struct lys_node *node, struct lys_node *parent)
2422{
2423 char *str;
2424
2425 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
2426 /* status is not inherited by specification, but it not make sense to have
2427 * current in deprecated or deprecated in obsolete, so we print warning
2428 * and fix the schema by inheriting */
2429 if (!(node->flags & (LYS_STATUS_MASK))) {
2430 /* status not explicitely specified on the current node -> inherit */
2431 str = lys_path(parent);
2432 LOGWRN("Missing status in %s subtree (%s), inheriting.",
2433 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", str);
2434 free(str);
2435 node->flags |= parent->flags & LYS_STATUS_MASK;
2436 } else if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
2437 /* invalid combination of statuses */
2438 switch (node->flags & LYS_STATUS_MASK) {
2439 case 0:
2440 case LYS_STATUS_CURR:
2441 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "current", strnodetype(node->nodetype), "is child of",
2442 parent->flags & LYS_STATUS_DEPRC ? "deprecated" : "obsolete", parent->name);
2443 break;
2444 case LYS_STATUS_DEPRC:
2445 LOGVAL(LYE_INSTATUS, LY_VLOG_LYS, parent, "deprecated", strnodetype(node->nodetype), "is child of",
2446 "obsolete", parent->name);
2447 break;
2448 }
2449 return EXIT_FAILURE;
2450 }
2451 }
2452
2453 return EXIT_SUCCESS;
2454}
2455
Pavol Vicanf4717e62016-03-16 11:30:01 +01002456int
Radek Krejci7212e0a2017-03-08 15:58:22 +01002457store_config_flag(struct lys_node *node, int options)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002458{
Pavol Vicanec598812016-11-30 14:13:38 +01002459 switch (node->nodetype) {
2460 case LYS_CONTAINER:
2461 case LYS_LEAF:
2462 case LYS_LEAFLIST:
2463 case LYS_LIST:
2464 case LYS_CHOICE:
2465 case LYS_ANYDATA:
2466 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002467 if (options & LYS_PARSE_OPT_CFG_IGNORE) {
Pavol Vicanec598812016-11-30 14:13:38 +01002468 node->flags |= node->flags & (~(LYS_CONFIG_MASK | LYS_CONFIG_SET));
Radek Krejci7212e0a2017-03-08 15:58:22 +01002469 } else if (!(options & LYS_PARSE_OPT_CFG_NOINHERIT)) {
Pavol Vicanec598812016-11-30 14:13:38 +01002470 if (!(node->flags & LYS_CONFIG_MASK)) {
2471 /* get config flag from parent */
2472 if (node->parent) {
2473 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2474 } else {
2475 /* default config is true */
2476 node->flags |= LYS_CONFIG_W;
2477 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002478 }
2479 }
Pavol Vicanec598812016-11-30 14:13:38 +01002480 break;
2481 case LYS_CASE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01002482 if (!(options & (LYS_PARSE_OPT_CFG_IGNORE | LYS_PARSE_OPT_CFG_NOINHERIT))) {
Pavol Vicanec598812016-11-30 14:13:38 +01002483 if (!(node->flags & LYS_CONFIG_MASK)) {
2484 /* get config flag from parent */
2485 if (node->parent) {
2486 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2487 } else {
2488 /* default config is true */
2489 node->flags |= LYS_CONFIG_W;
2490 }
2491 }
2492 }
2493 break;
Pavol Vicanec598812016-11-30 14:13:38 +01002494 default:
2495 break;
Pavol Vican1938d882016-04-10 13:36:31 +02002496 }
Pavol Vicanec598812016-11-30 14:13:38 +01002497
Radek Krejci7212e0a2017-03-08 15:58:22 +01002498 return EXIT_SUCCESS;
Pavol Vican1938d882016-04-10 13:36:31 +02002499}
2500
2501int
Pavol Vican9d50a772016-10-14 22:23:36 +02002502yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres,
2503 const char *data, unsigned int size_data, struct lys_node **node)
Pavol Vican1938d882016-04-10 13:36:31 +02002504{
Pavol Vican974377b2016-03-23 00:38:53 +01002505 unsigned int size;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002506 YY_BUFFER_STATE bp;
2507 yyscan_t scanner = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002508 int ret = 0;
Pavol Vican082afd02016-10-25 12:39:15 +02002509 struct lys_module *trg;
PavolVican196694c2017-01-27 10:33:09 +01002510 struct yang_parameter param;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002511
Pavol Vican8e7110b2016-03-22 17:00:26 +01002512 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican4fb66c92016-03-17 10:32:27 +01002513 yylex_init(&scanner);
2514 bp = yy_scan_buffer((char *)data, size, scanner);
2515 yy_switch_to_buffer(bp, scanner);
PavolVican22e88682017-02-14 22:38:18 +01002516 memset(&param, 0, sizeof param);
PavolVican196694c2017-01-27 10:33:09 +01002517 param.module = module;
2518 param.submodule = submodule;
2519 param.unres = unres;
2520 param.node = node;
PavolVican22e88682017-02-14 22:38:18 +01002521 param.flags |= YANG_REMOVE_IMPORT;
PavolVican196694c2017-01-27 10:33:09 +01002522 if (yyparse(scanner, &param)) {
PavolVican22e88682017-02-14 22:38:18 +01002523 if (param.flags & YANG_REMOVE_IMPORT) {
Pavol Vican082afd02016-10-25 12:39:15 +02002524 trg = (submodule) ? (struct lys_module *)submodule : module;
2525 yang_free_import(trg->ctx, trg->imp, 0, trg->imp_size);
2526 yang_free_include(trg->ctx, trg->inc, 0, trg->inc_size);
2527 trg->inc_size = 0;
2528 trg->imp_size = 0;
2529 }
PavolVican22e88682017-02-14 22:38:18 +01002530 ret = (param.flags & YANG_EXIST_MODULE) ? 1 : -1;
2531 }
2532 yy_delete_buffer(bp, scanner);
2533 yylex_destroy(scanner);
2534 return ret;
2535}
2536
2537int
2538yang_parse_ext_substatement(struct lys_module *module, struct unres_schema *unres, const char *data,
2539 char *ext_name, struct lys_ext_instance_complex *ext)
2540{
2541 unsigned int size;
2542 YY_BUFFER_STATE bp;
2543 yyscan_t scanner = NULL;
2544 int ret = 0;
2545 struct yang_parameter param;
PavolVicanf3091bf2017-02-19 18:27:01 +01002546 struct lys_node *node = NULL;
PavolVican22e88682017-02-14 22:38:18 +01002547
PavolVicandb0e8172017-02-20 00:46:09 +01002548 if (!data) {
2549 return EXIT_SUCCESS;
2550 }
PavolVican22e88682017-02-14 22:38:18 +01002551 size = strlen(data) + 2;
2552 yylex_init(&scanner);
2553 bp = yy_scan_buffer((char *)data, size, scanner);
2554 yy_switch_to_buffer(bp, scanner);
2555 memset(&param, 0, sizeof param);
2556 param.module = module;
2557 param.unres = unres;
PavolVicanf3091bf2017-02-19 18:27:01 +01002558 param.node = &node;
PavolVican22e88682017-02-14 22:38:18 +01002559 param.actual_node = (void **)ext;
2560 param.data_node = (void **)ext_name;
2561 param.flags |= EXT_INSTANCE_SUBSTMT;
2562 if (yyparse(scanner, &param)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002563 yang_free_nodes(module->ctx, node);
PavolVican22e88682017-02-14 22:38:18 +01002564 ret = -1;
PavolVicanf3091bf2017-02-19 18:27:01 +01002565 } else {
2566 /* success parse, but it needs some sematic controls */
Radek Krejci7212e0a2017-03-08 15:58:22 +01002567 if (node && yang_check_nodes(module, (struct lys_node *)ext, node, LYS_PARSE_OPT_CFG_NOINHERIT, unres)) {
PavolVicanf3091bf2017-02-19 18:27:01 +01002568 ret = -1;
2569 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002570 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002571 yy_delete_buffer(bp, scanner);
2572 yylex_destroy(scanner);
Pavol Vican1938d882016-04-10 13:36:31 +02002573 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002574}
2575
2576struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002577yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002578{
2579
PavolVican9e81c6a2017-02-09 13:09:07 +01002580 struct lys_module *module = NULL, *tmp_mod;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002581 struct unres_schema *unres = NULL;
Pavol Vican9d50a772016-10-14 22:23:36 +02002582 struct lys_node *node = NULL;
PavolVican9e81c6a2017-02-09 13:09:07 +01002583 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002584
2585 unres = calloc(1, sizeof *unres);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002586 LY_CHECK_ERR_GOTO(!unres, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002587
2588 module = calloc(1, sizeof *module);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002589 LY_CHECK_ERR_GOTO(!module, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002590
2591 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002592 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002593 module->type = 0;
2594 module->implemented = (implement ? 1 : 0);
2595
Radek Krejci9e757e02017-03-08 17:18:09 +01002596 /* add into the list of processed modules */
2597 if (lyp_check_circmod_add(module)) {
2598 goto error;
2599 }
2600
PavolVican9e81c6a2017-02-09 13:09:07 +01002601 ret = yang_parse_mem(module, NULL, unres, data, size, &node);
2602 if (ret == -1) {
Pavol Vican05810b62016-11-23 14:07:22 +01002603 free_yang_common(module, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002604 goto error;
Michal Vasko7b460e52017-02-10 14:50:26 +01002605 } else if (ret == 1) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002606 assert(!unres->count);
2607 } else {
2608 if (yang_check_sub_module(module, unres, node)) {
2609 goto error;
2610 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002611
Michal Vasko7b460e52017-02-10 14:50:26 +01002612 if (unres->count && resolve_unres_schema(module, unres)) {
PavolVican9e81c6a2017-02-09 13:09:07 +01002613 goto error;
2614 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002615 }
2616
PavolVicanfe83b152017-02-19 03:19:29 +01002617 lyp_sort_revisions(module);
2618
Pavol Vican8e7110b2016-03-22 17:00:26 +01002619 if (revision) {
2620 /* check revision of the parsed model */
2621 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2622 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2623 module->name, module->rev[0].date, revision);
2624 goto error;
2625 }
2626 }
2627
PavolVican9e81c6a2017-02-09 13:09:07 +01002628 /* add into context if not already there */
2629 if (!ret) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002630 /* check correctness of includes */
2631 if (lyp_check_include_missing(module)) {
Michal Vasko26055752016-05-03 11:36:31 +02002632 goto error;
2633 }
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002634
PavolVicanfd6f6952017-02-14 00:09:42 +01002635 /* remove our submodules from the parsed submodules list */
2636 lyp_del_includedup(module);
2637
2638
PavolVican6f000922017-02-10 12:56:59 +01002639 if (lyp_rfn_apply_ext(module) || lyp_deviation_apply_ext(module)) {
Michal Vaskoe8c73dd2017-02-10 11:34:17 +01002640 goto error;
2641 }
2642
PavolVican9e81c6a2017-02-09 13:09:07 +01002643 if (lyp_ctx_add_module(module)) {
Michal Vasko7da5b0b2016-05-02 16:36:59 +02002644 goto error;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002645 }
PavolVican9e81c6a2017-02-09 13:09:07 +01002646
2647 if (module->deviation_size && !module->implemented) {
2648 LOGVRB("Module \"%s\" includes deviations, changing its conformance to \"implement\".", module->name);
2649 /* deviations always causes target to be made implemented,
2650 * but augents and leafrefs not, so we have to apply them now */
2651 if (lys_set_implemented(module)) {
2652 goto error;
2653 }
2654 }
2655 } else {
2656 tmp_mod = module;
2657
2658 /* get the model from the context */
2659 module = (struct lys_module *)ly_ctx_get_module(ctx, module->name, revision);
2660 assert(module);
2661
2662 /* free what was parsed */
2663 lys_free(tmp_mod, NULL, 0);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002664 }
2665
Michal Vasko44ab1462017-05-18 13:18:36 +02002666 unres_schema_free(NULL, &unres, 0);
Radek Krejci9e757e02017-03-08 17:18:09 +01002667 lyp_check_circmod_pop(ctx);
Michal Vaskobe136f62017-09-21 12:08:39 +02002668 LOGVRB("Module \"%s%s%s\" successfully parsed as %s.", module->name, (module->rev_size ? "@" : ""),
2669 (module->rev_size ? module->rev[0].date : ""), (module->implemented ? "implemented" : "imported"));
Pavol Vican8e7110b2016-03-22 17:00:26 +01002670 return module;
2671
2672error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002673 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002674 unres_schema_free(module, &unres, 1);
Radek Krejcif505cd12017-06-13 10:32:48 +02002675 if (!module) {
Radek Krejci48cfa0f2016-11-08 19:18:34 +01002676 if (ly_vecode != LYVE_SUBMODULE) {
2677 LOGERR(ly_errno, "Module parsing failed.");
2678 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002679 return NULL;
2680 }
2681
Radek Krejcif505cd12017-06-13 10:32:48 +02002682 if (module->name) {
2683 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
2684 } else {
2685 LOGERR(ly_errno, "Module parsing failed.");
2686 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002687
Radek Krejci9e757e02017-03-08 17:18:09 +01002688 lyp_check_circmod_pop(ctx);
Michal Vaskocf0489e2017-02-13 11:57:45 +01002689 lyp_del_includedup(module);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002690 lys_sub_module_remove_devs_augs(module);
2691 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002692 return NULL;
2693}
2694
2695struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002696yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002697{
2698 struct lys_submodule *submodule;
Pavol Vican9d50a772016-10-14 22:23:36 +02002699 struct lys_node *node = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002700
2701 submodule = calloc(1, sizeof *submodule);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002702 LY_CHECK_ERR_GOTO(!submodule, LOGMEM, error);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002703
2704 submodule->ctx = module->ctx;
2705 submodule->type = 1;
Radek Krejci29eac3d2017-06-01 16:50:02 +02002706 submodule->implemented = module->implemented;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002707 submodule->belongsto = module;
2708
Radek Krejci9e757e02017-03-08 17:18:09 +01002709 /* add into the list of processed modules */
2710 if (lyp_check_circmod_add((struct lys_module *)submodule)) {
2711 goto error;
2712 }
2713
PavolVican9e81c6a2017-02-09 13:09:07 +01002714 /* module cannot be changed in this case and 1 cannot be returned */
Pavol Vican9d50a772016-10-14 22:23:36 +02002715 if (yang_parse_mem(module, submodule, unres, data, size, &node)) {
Pavol Vican05810b62016-11-23 14:07:22 +01002716 free_yang_common((struct lys_module *)submodule, node);
Pavol Vican7313fc02016-11-14 01:10:31 +01002717 goto error;
2718 }
2719
PavolVicanfe83b152017-02-19 03:19:29 +01002720 lyp_sort_revisions((struct lys_module *)submodule);
2721
Pavol Vican7313fc02016-11-14 01:10:31 +01002722 if (yang_check_sub_module((struct lys_module *)submodule, unres, node)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002723 goto error;
2724 }
2725
Radek Krejci9e757e02017-03-08 17:18:09 +01002726 lyp_check_circmod_pop(module->ctx);
2727
Pavol Vican8e7110b2016-03-22 17:00:26 +01002728 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002729 return submodule;
2730
2731error:
2732 /* cleanup */
Michal Vasko44ab1462017-05-18 13:18:36 +02002733 unres_schema_free((struct lys_module *)submodule, &unres, 0);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002734
2735 if (!submodule || !submodule->name) {
2736 free(submodule);
2737 LOGERR(ly_errno, "Submodule parsing failed.");
2738 return NULL;
2739 }
2740
2741 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2742
Radek Krejci9e757e02017-03-08 17:18:09 +01002743 lyp_check_circmod_pop(module->ctx);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002744 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2745 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002746 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002747 return NULL;
2748}
Pavol Vican8760bb72016-04-07 09:44:01 +02002749
2750static int
Pavol Vican8760bb72016-04-07 09:44:01 +02002751read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2752{
2753 int k = 0, j;
2754
2755 while (in_index < size) {
2756 if (input[in_index] == ' ') {
2757 k++;
2758 } else if (input[in_index] == '\t') {
2759 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2760 k += 8;
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002761 } else if (input[in_index] == '\\' && input[in_index + 1] == 't') {
2762 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2763 k += 8;
2764 ++in_index;
Pavol Vican8760bb72016-04-07 09:44:01 +02002765 } else {
2766 break;
2767 }
2768 ++in_index;
2769 if (k >= indent) {
2770 for (j = k - indent; j > 0; --j) {
2771 output[*out_index] = ' ';
Pavol Vicana7bf3372016-12-01 15:58:18 +01002772 if (j > 1) {
2773 ++(*out_index);
2774 }
Pavol Vican8760bb72016-04-07 09:44:01 +02002775 }
2776 break;
2777 }
2778 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002779 return in_index - 1;
Pavol Vican8760bb72016-04-07 09:44:01 +02002780}
2781
2782char *
PavolVican1bc22062017-01-19 15:09:04 +01002783yang_read_string(const char *input, char *output, int size, int offset, int indent) {
Pavol Vican3f598892016-09-28 15:41:07 +02002784 int i = 0, out_index = offset, space = 0;
Pavol Vican8760bb72016-04-07 09:44:01 +02002785
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002786 while (i < size) {
2787 switch (input[i]) {
2788 case '\n':
2789 out_index -= space;
2790 output[out_index] = '\n';
2791 space = 0;
2792 i = read_indent(input, indent, size, i + 1, &out_index, output);
2793 break;
2794 case ' ':
2795 case '\t':
2796 output[out_index] = input[i];
2797 ++space;
2798 break;
2799 case '\\':
2800 if (input[i + 1] == 'n') {
2801 out_index -= space;
2802 output[out_index] = '\n';
2803 space = 0;
2804 i = read_indent(input, indent, size, i + 2, &out_index, output);
2805 } else if (input[i + 1] == 't') {
2806 output[out_index] = '\t';
2807 ++i;
2808 ++space;
2809 } else if (input[i + 1] == '\\') {
2810 output[out_index] = '\\';
2811 ++i;
2812 } else if ((i + 1) != size && input[i + 1] == '"') {
2813 output[out_index] = '"';
2814 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002815 } else {
PavolVican1bc22062017-01-19 15:09:04 +01002816 /* backslash must not be followed by any other character */
2817 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, input);
2818 return NULL;
Pavol Vican8760bb72016-04-07 09:44:01 +02002819 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002820 break;
2821 default:
2822 output[out_index] = input[i];
2823 space = 0;
2824 break;
Pavol Vican8760bb72016-04-07 09:44:01 +02002825 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002826 ++i;
Pavol Vican8760bb72016-04-07 09:44:01 +02002827 ++out_index;
2828 }
Pavol Vican0fbb57b2016-09-27 21:46:12 +02002829 output[out_index] = '\0';
2830 if (size != out_index) {
Pavol Vican3f598892016-09-28 15:41:07 +02002831 output = realloc(output, out_index + 1);
Radek Krejcia8d111f2017-05-31 13:57:37 +02002832 LY_CHECK_ERR_RETURN(!output, LOGMEM, NULL);
Pavol Vican8760bb72016-04-07 09:44:01 +02002833 }
Pavol Vican3f598892016-09-28 15:41:07 +02002834 return output;
Pavol Vican8760bb72016-04-07 09:44:01 +02002835}
Pavol Vican1cc4e192016-10-24 16:38:31 +02002836
2837/* free function */
2838
PavolVicana0fdbf32017-02-15 17:59:02 +01002839void
2840yang_type_free(struct ly_ctx *ctx, struct lys_type *type)
Pavol Vican7313fc02016-11-14 01:10:31 +01002841{
2842 struct yang_type *stype = (struct yang_type *)type->der;
Radek Krejcidce5f972017-09-12 15:47:49 +02002843 unsigned int i;
Pavol Vican7313fc02016-11-14 01:10:31 +01002844
2845 if (!stype) {
2846 return ;
2847 }
PavolVicane87cb932016-12-30 15:36:18 +01002848 if (type->base == LY_TYPE_DER || type->base == LY_TYPE_ERR || type->base == LY_TYPE_UNION) {
2849 lydict_remove(ctx, stype->name);
2850 if (stype->base == LY_TYPE_IDENT && (!(stype->flags & LYS_NO_ERASE_IDENTITY))) {
2851 for (i = 0; i < type->info.ident.count; ++i) {
2852 free(type->info.ident.ref[i]);
2853 }
Pavol Vican7313fc02016-11-14 01:10:31 +01002854 }
PavolVicane87cb932016-12-30 15:36:18 +01002855 if (stype->base == LY_TYPE_UNION) {
2856 for (i = 0; i < type->info.uni.count; ++i) {
2857 yang_type_free(ctx, &type->info.uni.types[i]);
2858 }
2859 free(type->info.uni.types);
2860 type->base = LY_TYPE_DER;
2861 } else {
2862 type->base = stype->base;
2863 }
2864 free(stype);
2865 type->der = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002866 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02002867 lys_type_free(ctx, type, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002868 type->base = LY_TYPE_DER;
PavolVican575a9342017-02-15 18:14:39 +01002869 type->ext_size = 0;
2870 type->ext = NULL;
Pavol Vican7313fc02016-11-14 01:10:31 +01002871}
2872
2873static void
2874yang_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf, uint8_t start, uint8_t size)
2875{
2876 uint8_t i;
2877
2878 assert(ctx);
2879 if (!tpdf) {
2880 return;
2881 }
2882
2883 for (i = start; i < size; ++i) {
Pavol Vicancee10802016-11-22 15:48:35 +01002884 lydict_remove(ctx, tpdf[i].name);
2885 lydict_remove(ctx, tpdf[i].dsc);
2886 lydict_remove(ctx, tpdf[i].ref);
Pavol Vican7313fc02016-11-14 01:10:31 +01002887
Pavol Vicancee10802016-11-22 15:48:35 +01002888 yang_type_free(ctx, &tpdf[i].type);
Pavol Vican7313fc02016-11-14 01:10:31 +01002889
Pavol Vicancee10802016-11-22 15:48:35 +01002890 lydict_remove(ctx, tpdf[i].units);
2891 lydict_remove(ctx, tpdf[i].dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002892 lys_extension_instances_free(ctx, tpdf[i].ext, tpdf[i].ext_size, NULL);
Pavol Vican7313fc02016-11-14 01:10:31 +01002893 }
2894}
2895
Pavol Vican1cc4e192016-10-24 16:38:31 +02002896static void
2897yang_free_import(struct ly_ctx *ctx, struct lys_import *imp, uint8_t start, uint8_t size)
2898{
2899 uint8_t i;
2900
2901 for (i = start; i < size; ++i){
2902 free((char *)imp[i].module);
2903 lydict_remove(ctx, imp[i].prefix);
2904 lydict_remove(ctx, imp[i].dsc);
2905 lydict_remove(ctx, imp[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002906 lys_extension_instances_free(ctx, imp[i].ext, imp[i].ext_size, NULL);
Pavol Vican1cc4e192016-10-24 16:38:31 +02002907 }
2908}
2909
Pavol Vicanec423c92016-10-24 21:33:43 +02002910static void
2911yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size)
2912{
2913 uint8_t i;
2914
2915 for (i = start; i < size; ++i){
2916 free((char *)inc[i].submodule);
2917 lydict_remove(ctx, inc[i].dsc);
2918 lydict_remove(ctx, inc[i].ref);
Radek Krejci5138e9f2017-04-12 13:10:46 +02002919 lys_extension_instances_free(ctx, inc[i].ext, inc[i].ext_size, NULL);
Pavol Vicanec423c92016-10-24 21:33:43 +02002920 }
2921}
2922
Pavol Vican36e27272016-11-22 15:47:28 +01002923static void
2924yang_free_ident_base(struct lys_ident *ident, uint32_t start, uint32_t size)
2925{
2926 uint32_t i;
2927 uint8_t j;
2928
2929 /* free base name */
2930 for (i = start; i < size; ++i) {
2931 for (j = 0; j < ident[i].base_size; ++j) {
2932 free(ident[i].base[j]);
2933 }
2934 }
2935}
2936
Pavol Vican05810b62016-11-23 14:07:22 +01002937static void
2938yang_free_grouping(struct ly_ctx *ctx, struct lys_node_grp * grp)
2939{
2940 yang_tpdf_free(ctx, grp->tpdf, 0, grp->tpdf_size);
2941 free(grp->tpdf);
2942}
2943
2944static void
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002945yang_free_container(struct ly_ctx *ctx, struct lys_node_container * cont)
2946{
2947 uint8_t i;
2948
2949 yang_tpdf_free(ctx, cont->tpdf, 0, cont->tpdf_size);
2950 free(cont->tpdf);
2951 lydict_remove(ctx, cont->presence);
2952
Pavol Vicanfda8c802016-12-03 02:00:42 +01002953 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002954 lys_restr_free(ctx, &cont->must[i], NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002955 }
2956 free(cont->must);
2957
Radek Krejci5138e9f2017-04-12 13:10:46 +02002958 lys_when_free(ctx, cont->when, NULL);
Pavol Vicanc54a8f72016-11-23 16:45:55 +01002959}
2960
2961static void
Pavol Vicana69aff22016-11-24 18:23:50 +01002962yang_free_leaf(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
2963{
2964 uint8_t i;
2965
2966 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002967 lys_restr_free(ctx, &leaf->must[i], NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002968 }
2969 free(leaf->must);
2970
Radek Krejci5138e9f2017-04-12 13:10:46 +02002971 lys_when_free(ctx, leaf->when, NULL);
Pavol Vicana69aff22016-11-24 18:23:50 +01002972
2973 yang_type_free(ctx, &leaf->type);
2974 lydict_remove(ctx, leaf->units);
2975 lydict_remove(ctx, leaf->dflt);
2976}
2977
2978static void
Pavol Vican36aff862016-11-26 17:07:05 +01002979yang_free_leaflist(struct ly_ctx *ctx, struct lys_node_leaflist *leaflist)
2980{
2981 uint8_t i;
2982
2983 for (i = 0; i < leaflist->must_size; i++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02002984 lys_restr_free(ctx, &leaflist->must[i], NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002985 }
2986 free(leaflist->must);
2987
2988 for (i = 0; i < leaflist->dflt_size; i++) {
2989 lydict_remove(ctx, leaflist->dflt[i]);
2990 }
2991 free(leaflist->dflt);
2992
Radek Krejci5138e9f2017-04-12 13:10:46 +02002993 lys_when_free(ctx, leaflist->when, NULL);
Pavol Vican36aff862016-11-26 17:07:05 +01002994
2995 yang_type_free(ctx, &leaflist->type);
2996 lydict_remove(ctx, leaflist->units);
2997}
2998
2999static void
Pavol Vicand8136a42016-11-27 13:28:04 +01003000yang_free_list(struct ly_ctx *ctx, struct lys_node_list *list)
3001{
3002 uint8_t i;
3003
3004 yang_tpdf_free(ctx, list->tpdf, 0, list->tpdf_size);
3005 free(list->tpdf);
3006
3007 for (i = 0; i < list->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003008 lys_restr_free(ctx, &list->must[i], NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003009 }
3010 free(list->must);
3011
Radek Krejci5138e9f2017-04-12 13:10:46 +02003012 lys_when_free(ctx, list->when, NULL);
Pavol Vicand8136a42016-11-27 13:28:04 +01003013
3014 for (i = 0; i < list->unique_size; ++i) {
3015 free(list->unique[i].expr);
3016 }
3017 free(list->unique);
3018
3019 free(list->keys);
3020}
3021
3022static void
Pavol Vican36ace102016-11-28 11:46:59 +01003023yang_free_choice(struct ly_ctx *ctx, struct lys_node_choice *choice)
3024{
3025 free(choice->dflt);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003026 lys_when_free(ctx, choice->when, NULL);
Pavol Vican36ace102016-11-28 11:46:59 +01003027}
3028
3029static void
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003030yang_free_anydata(struct ly_ctx *ctx, struct lys_node_anydata *anydata)
3031{
3032 uint8_t i;
3033
3034 for (i = 0; i < anydata->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003035 lys_restr_free(ctx, &anydata->must[i], NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003036 }
3037 free(anydata->must);
3038
Radek Krejci5138e9f2017-04-12 13:10:46 +02003039 lys_when_free(ctx, anydata->when, NULL);
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003040}
3041
3042static void
Pavol Vican78729392016-11-28 17:18:22 +01003043yang_free_inout(struct ly_ctx *ctx, struct lys_node_inout *inout)
3044{
3045 uint8_t i;
3046
3047 yang_tpdf_free(ctx, inout->tpdf, 0, inout->tpdf_size);
3048 free(inout->tpdf);
3049
3050 for (i = 0; i < inout->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003051 lys_restr_free(ctx, &inout->must[i], NULL);
Pavol Vican78729392016-11-28 17:18:22 +01003052 }
3053 free(inout->must);
3054}
3055
3056static void
Pavol Vican29bf8802016-11-28 20:44:57 +01003057yang_free_notif(struct ly_ctx *ctx, struct lys_node_notif *notif)
3058{
3059 uint8_t i;
3060
3061 yang_tpdf_free(ctx, notif->tpdf, 0, notif->tpdf_size);
3062 free(notif->tpdf);
3063
3064 for (i = 0; i < notif->must_size; ++i) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003065 lys_restr_free(ctx, &notif->must[i], NULL);
Pavol Vican29bf8802016-11-28 20:44:57 +01003066 }
3067 free(notif->must);
3068}
3069
3070static void
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003071yang_free_uses(struct ly_ctx *ctx, struct lys_node_uses *uses)
3072{
3073 int i, j;
3074
3075 for (i = 0; i < uses->refine_size; i++) {
3076 lydict_remove(ctx, uses->refine[i].target_name);
3077 lydict_remove(ctx, uses->refine[i].dsc);
3078 lydict_remove(ctx, uses->refine[i].ref);
3079
3080 for (j = 0; j < uses->refine[i].must_size; j++) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003081 lys_restr_free(ctx, &uses->refine[i].must[j], NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003082 }
3083 free(uses->refine[i].must);
3084
3085 for (j = 0; j < uses->refine[i].dflt_size; j++) {
3086 lydict_remove(ctx, uses->refine[i].dflt[j]);
3087 }
3088 free(uses->refine[i].dflt);
3089
3090 if (uses->refine[i].target_type & LYS_CONTAINER) {
3091 lydict_remove(ctx, uses->refine[i].mod.presence);
3092 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003093 lys_extension_instances_free(ctx, uses->refine[i].ext, uses->refine[i].ext_size, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003094 }
3095 free(uses->refine);
3096
Radek Krejci5138e9f2017-04-12 13:10:46 +02003097 lys_when_free(ctx, uses->when, NULL);
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003098}
3099
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003100static void
Pavol Vican05810b62016-11-23 14:07:22 +01003101yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
3102{
3103 struct lys_node *tmp, *child, *sibling;
3104
3105 if (!node) {
3106 return;
3107 }
3108 tmp = node;
Pavol Vican05810b62016-11-23 14:07:22 +01003109
3110 while (tmp) {
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003111 child = tmp->child;
Pavol Vican05810b62016-11-23 14:07:22 +01003112 sibling = tmp->next;
3113 /* common part */
3114 lydict_remove(ctx, tmp->name);
3115 if (!(tmp->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003116 lys_iffeature_free(ctx, tmp->iffeature, tmp->iffeature_size, 0, NULL);
Pavol Vicane87ff8d2016-11-24 18:25:01 +01003117 lydict_remove(ctx, tmp->dsc);
3118 lydict_remove(ctx, tmp->ref);
Pavol Vican05810b62016-11-23 14:07:22 +01003119 }
3120
3121 switch (tmp->nodetype) {
3122 case LYS_GROUPING:
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003123 case LYS_RPC:
3124 case LYS_ACTION:
Pavol Vican05810b62016-11-23 14:07:22 +01003125 yang_free_grouping(ctx, (struct lys_node_grp *)tmp);
3126 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003127 case LYS_CONTAINER:
3128 yang_free_container(ctx, (struct lys_node_container *)tmp);
3129 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01003130 case LYS_LEAF:
3131 yang_free_leaf(ctx, (struct lys_node_leaf *)tmp);
3132 break;
Pavol Vican36aff862016-11-26 17:07:05 +01003133 case LYS_LEAFLIST:
3134 yang_free_leaflist(ctx, (struct lys_node_leaflist *)tmp);
3135 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003136 case LYS_LIST:
3137 yang_free_list(ctx, (struct lys_node_list *)tmp);
3138 break;
Pavol Vican36ace102016-11-28 11:46:59 +01003139 case LYS_CHOICE:
3140 yang_free_choice(ctx, (struct lys_node_choice *)tmp);
3141 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01003142 case LYS_CASE:
Radek Krejci5138e9f2017-04-12 13:10:46 +02003143 lys_when_free(ctx, ((struct lys_node_case *)tmp)->when, NULL);
Pavol Vicana420bac2016-11-28 14:51:54 +01003144 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01003145 case LYS_ANYXML:
3146 case LYS_ANYDATA:
3147 yang_free_anydata(ctx, (struct lys_node_anydata *)tmp);
3148 break;
Pavol Vican78729392016-11-28 17:18:22 +01003149 case LYS_INPUT:
3150 case LYS_OUTPUT:
3151 yang_free_inout(ctx, (struct lys_node_inout *)tmp);
3152 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003153 case LYS_NOTIF:
3154 yang_free_notif(ctx, (struct lys_node_notif *)tmp);
3155 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003156 case LYS_USES:
3157 yang_free_uses(ctx, (struct lys_node_uses *)tmp);
3158 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003159 default:
3160 break;
3161 }
Radek Krejci5138e9f2017-04-12 13:10:46 +02003162 lys_extension_instances_free(ctx, tmp->ext, tmp->ext_size, NULL);
Pavol Vican05810b62016-11-23 14:07:22 +01003163 yang_free_nodes(ctx, child);
3164 free(tmp);
3165 tmp = sibling;
3166 }
3167}
3168
Pavol Vican3ad50f82016-12-04 15:00:36 +01003169static void
3170yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
3171{
3172 lydict_remove(ctx, aug->target_name);
3173 lydict_remove(ctx, aug->dsc);
3174 lydict_remove(ctx, aug->ref);
3175
Frank Rimplerc4db1c72017-09-12 12:56:39 +00003176 lys_iffeature_free(ctx, aug->iffeature, aug->iffeature_size, 0, NULL);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003177 lys_when_free(ctx, aug->when, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003178 yang_free_nodes(ctx, aug->child);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003179 lys_extension_instances_free(ctx, aug->ext, aug->ext_size, NULL);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003180}
3181
PavolVican75af21d2016-12-29 20:04:07 +01003182static void
3183yang_free_deviate(struct ly_ctx *ctx, struct lys_deviation *dev, uint index)
3184{
3185 uint i, j;
3186
3187 for (i = index; i < dev->deviate_size; ++i) {
3188 lydict_remove(ctx, dev->deviate[i].units);
3189
3190 if (dev->deviate[i].type) {
3191 yang_type_free(ctx, dev->deviate[i].type);
3192 }
3193
3194 for (j = 0; j < dev->deviate[i].dflt_size; ++j) {
3195 lydict_remove(ctx, dev->deviate[i].dflt[j]);
3196 }
3197 free(dev->deviate[i].dflt);
3198
3199 for (j = 0; j < dev->deviate[i].must_size; ++j) {
Radek Krejci5138e9f2017-04-12 13:10:46 +02003200 lys_restr_free(ctx, &dev->deviate[i].must[j], NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003201 }
3202 free(dev->deviate[i].must);
3203
3204 for (j = 0; j < dev->deviate[i].unique_size; ++j) {
3205 free(dev->deviate[i].unique[j].expr);
3206 }
3207 free(dev->deviate[i].unique);
Radek Krejci5138e9f2017-04-12 13:10:46 +02003208 lys_extension_instances_free(ctx, dev->deviate[i].ext, dev->deviate[i].ext_size, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01003209 }
3210}
3211
PavolVicandb0e8172017-02-20 00:46:09 +01003212void
3213yang_free_ext_data(struct yang_ext_substmt *substmt)
3214{
3215 int i;
3216
3217 if (!substmt) {
3218 return;
3219 }
3220
3221 free(substmt->ext_substmt);
3222 if (substmt->ext_modules) {
3223 for (i = 0; substmt->ext_modules[i]; ++i) {
3224 free(substmt->ext_modules[i]);
3225 }
3226 free(substmt->ext_modules);
3227 }
3228 free(substmt);
3229}
3230
Pavol Vican7313fc02016-11-14 01:10:31 +01003231/* free common item from module and submodule */
3232static void
Pavol Vican05810b62016-11-23 14:07:22 +01003233free_yang_common(struct lys_module *module, struct lys_node *node)
Pavol Vican7313fc02016-11-14 01:10:31 +01003234{
PavolVican75af21d2016-12-29 20:04:07 +01003235 uint i;
Pavol Vican7313fc02016-11-14 01:10:31 +01003236 yang_tpdf_free(module->ctx, module->tpdf, 0, module->tpdf_size);
3237 module->tpdf_size = 0;
Pavol Vican36e27272016-11-22 15:47:28 +01003238 yang_free_ident_base(module->ident, 0, module->ident_size);
Pavol Vican05810b62016-11-23 14:07:22 +01003239 yang_free_nodes(module->ctx, node);
PavolVican75af21d2016-12-29 20:04:07 +01003240 for (i = 0; i < module->augment_size; ++i) {
3241 yang_free_augment(module->ctx, &module->augment[i]);
3242 }
3243 module->augment_size = 0;
3244 for (i = 0; i < module->deviation_size; ++i) {
3245 yang_free_deviate(module->ctx, &module->deviation[i], 0);
3246 free(module->deviation[i].deviate);
3247 }
3248 module->deviation_size = 0;
Pavol Vican7313fc02016-11-14 01:10:31 +01003249}
3250
Pavol Vican1cc4e192016-10-24 16:38:31 +02003251/* check function*/
3252
3253int
PavolVicanc1807262017-01-31 18:00:27 +01003254yang_check_ext_instance(struct lys_module *module, struct lys_ext_instance ***ext, uint size,
3255 void *parent, struct unres_schema *unres)
3256{
3257 struct unres_ext *info;
3258 uint i;
3259
3260 for (i = 0; i < size; ++i) {
3261 info = malloc(sizeof *info);
Radek Krejcia8d111f2017-05-31 13:57:37 +02003262 LY_CHECK_ERR_RETURN(!info, LOGMEM, EXIT_FAILURE);
PavolVicanc1807262017-01-31 18:00:27 +01003263 info->data.yang = (*ext)[i]->parent;
3264 info->datatype = LYS_IN_YANG;
3265 info->parent = parent;
3266 info->mod = module;
3267 info->parent_type = (*ext)[i]->parent_type;
Radek Krejcifebdad72017-02-06 11:35:51 +01003268 info->substmt = (*ext)[i]->insubstmt;
3269 info->substmt_index = (*ext)[i]->insubstmt_index;
PavolVicanc1807262017-01-31 18:00:27 +01003270 info->ext_index = i;
3271 if (unres_schema_add_node(module, unres, ext, UNRES_EXT, (struct lys_node *)info) == -1) {
3272 return EXIT_FAILURE;
3273 }
3274 }
3275
3276 return EXIT_SUCCESS;
3277}
3278
3279int
Pavol Vicanec423c92016-10-24 21:33:43 +02003280yang_check_imports(struct lys_module *module, struct unres_schema *unres)
Pavol Vican1cc4e192016-10-24 16:38:31 +02003281{
3282 struct lys_import *imp;
Pavol Vicanec423c92016-10-24 21:33:43 +02003283 struct lys_include *inc;
3284 uint8_t imp_size, inc_size, j = 0, i = 0;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003285 char *s;
3286
3287 imp = module->imp;
3288 imp_size = module->imp_size;
Pavol Vicanec423c92016-10-24 21:33:43 +02003289 inc = module->inc;
3290 inc_size = module->inc_size;
Pavol Vican1cc4e192016-10-24 16:38:31 +02003291
3292 if (imp_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003293 module->imp = calloc(imp_size, sizeof *module->imp);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003294 module->imp_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003295 LY_CHECK_ERR_GOTO(!module->imp, LOGMEM, error);
Pavol Vicanec423c92016-10-24 21:33:43 +02003296 }
Pavol Vican1cc4e192016-10-24 16:38:31 +02003297
Pavol Vicanec423c92016-10-24 21:33:43 +02003298 if (inc_size) {
PavolVican5144fd82017-03-07 19:45:06 +01003299 module->inc = calloc(inc_size, sizeof *module->inc);
Pavol Vicanec423c92016-10-24 21:33:43 +02003300 module->inc_size = 0;
Radek Krejcia8d111f2017-05-31 13:57:37 +02003301 LY_CHECK_ERR_GOTO(!module->inc, LOGMEM, error);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003302 }
3303
3304 for (i = 0; i < imp_size; ++i) {
3305 s = (char *) imp[i].module;
3306 imp[i].module = NULL;
PavolVican7d0b5ab2017-02-01 13:06:53 +01003307 if (yang_fill_import(module, &imp[i], &module->imp[module->imp_size], s, unres)) {
Pavol Vican1cc4e192016-10-24 16:38:31 +02003308 ++i;
3309 goto error;
3310 }
3311 }
Pavol Vicanec423c92016-10-24 21:33:43 +02003312 for (j = 0; j < inc_size; ++j) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003313 s = (char *) inc[j].submodule;
3314 inc[j].submodule = NULL;
3315 if (yang_fill_include(module, s, &inc[j], unres)) {
3316 ++j;
Pavol Vicanec423c92016-10-24 21:33:43 +02003317 goto error;
3318 }
3319 }
3320 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003321 free(imp);
3322
3323 return EXIT_SUCCESS;
3324
3325error:
3326 yang_free_import(module->ctx, imp, i, imp_size);
Pavol Vicanec423c92016-10-24 21:33:43 +02003327 yang_free_include(module->ctx, inc, j, inc_size);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003328 free(imp);
Pavol Vicanec423c92016-10-24 21:33:43 +02003329 free(inc);
Pavol Vican1cc4e192016-10-24 16:38:31 +02003330 return EXIT_FAILURE;
3331}
Pavol Vican7313fc02016-11-14 01:10:31 +01003332
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003333static int
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003334yang_check_iffeatures(struct lys_module *module, void *ptr, void *parent, enum yytokentype type, struct unres_schema *unres)
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003335{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003336 struct lys_iffeature *iffeature;
3337 uint8_t *ptr_size, size, i;
3338 char *s;
3339 int parent_is_feature = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003340
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003341 switch (type) {
3342 case FEATURE_KEYWORD:
3343 iffeature = ((struct lys_feature *)parent)->iffeature;
3344 size = ((struct lys_feature *)parent)->iffeature_size;
3345 ptr_size = &((struct lys_feature *)parent)->iffeature_size;
3346 parent_is_feature = 1;
3347 break;
3348 case IDENTITY_KEYWORD:
3349 iffeature = ((struct lys_ident *)parent)->iffeature;
3350 size = ((struct lys_ident *)parent)->iffeature_size;
3351 ptr_size = &((struct lys_ident *)parent)->iffeature_size;
3352 break;
3353 case ENUM_KEYWORD:
3354 iffeature = ((struct lys_type_enum *)ptr)->iffeature;
3355 size = ((struct lys_type_enum *)ptr)->iffeature_size;
3356 ptr_size = &((struct lys_type_enum *)ptr)->iffeature_size;
3357 break;
3358 case BIT_KEYWORD:
3359 iffeature = ((struct lys_type_bit *)ptr)->iffeature;
3360 size = ((struct lys_type_bit *)ptr)->iffeature_size;
3361 ptr_size = &((struct lys_type_bit *)ptr)->iffeature_size;
3362 break;
3363 case REFINE_KEYWORD:
3364 iffeature = ((struct lys_refine *)ptr)->iffeature;
3365 size = ((struct lys_refine *)ptr)->iffeature_size;
3366 ptr_size = &((struct lys_refine *)ptr)->iffeature_size;
3367 break;
3368 default:
3369 iffeature = ((struct lys_node *)parent)->iffeature;
3370 size = ((struct lys_node *)parent)->iffeature_size;
3371 ptr_size = &((struct lys_node *)parent)->iffeature_size;
3372 break;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003373 }
3374
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003375 *ptr_size = 0;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003376 for (i = 0; i < size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003377 s = (char *)iffeature[i].features;
3378 iffeature[i].features = NULL;
3379 if (yang_fill_iffeature(module, &iffeature[i], parent, s, unres, parent_is_feature)) {
3380 *ptr_size = size;
3381 return EXIT_FAILURE;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003382 }
PavolVican8fa31242017-02-07 11:04:26 +01003383 if (yang_check_ext_instance(module, &iffeature[i].ext, iffeature[i].ext_size, &iffeature[i], unres)) {
3384 *ptr_size = size;
3385 return EXIT_FAILURE;
3386 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003387 (*ptr_size)++;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003388 }
3389
3390 return EXIT_SUCCESS;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003391}
3392
Pavol Vicanb60a1d12016-12-03 01:56:55 +01003393static int
3394yang_check_identityref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
3395{
3396 uint size, i;
3397 int rc;
3398 struct lys_ident **ref;
3399 const char *value;
3400 char *expr;
3401
3402 ref = type->info.ident.ref;
3403 size = type->info.ident.count;
3404 type->info.ident.count = 0;
3405 type->info.ident.ref = NULL;
3406 ((struct yang_type *)type->der)->flags |= LYS_NO_ERASE_IDENTITY;
3407
3408 for (i = 0; i < size; ++i) {
3409 expr = (char *)ref[i];
3410 /* store in the JSON format */
3411 value = transform_schema2json(module, expr);
3412 free(expr);
3413
3414 if (!value) {
3415 goto error;
3416 }
3417 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
3418 lydict_remove(module->ctx, value);
3419
3420 if (rc == -1) {
3421 goto error;
3422 }
3423 }
3424 free(ref);
3425
3426 return EXIT_SUCCESS;
3427error:
3428 for (i = i+1; i < size; ++i) {
3429 free(ref[i]);
3430 }
3431 free(ref);
3432 return EXIT_FAILURE;
3433}
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003434
Pavol Vican7313fc02016-11-14 01:10:31 +01003435int
PavolVican056fcd12017-02-07 15:36:53 +01003436yang_fill_type(struct lys_module *module, struct lys_type *type, struct yang_type *stype,
3437 void *parent, struct unres_schema *unres)
3438{
Radek Krejcidce5f972017-09-12 15:47:49 +02003439 unsigned int i;
PavolVican056fcd12017-02-07 15:36:53 +01003440
3441 type->parent = parent;
3442 if (yang_check_ext_instance(module, &type->ext, type->ext_size, type, unres)) {
3443 return EXIT_FAILURE;
3444 }
3445 switch (stype->base) {
3446 case LY_TYPE_ENUM:
3447 for (i = 0; i < type->info.enums.count; ++i) {
3448 if (yang_check_iffeatures(module, &type->info.enums.enm[i], parent, ENUM_KEYWORD, unres)) {
3449 return EXIT_FAILURE;
3450 }
3451 if (yang_check_ext_instance(module, &type->info.enums.enm[i].ext, type->info.enums.enm[i].ext_size,
3452 &type->info.enums.enm[i], unres)) {
3453 return EXIT_FAILURE;
3454 }
3455 }
3456 break;
3457 case LY_TYPE_BITS:
3458 for (i = 0; i < type->info.bits.count; ++i) {
3459 if (yang_check_iffeatures(module, &type->info.bits.bit[i], parent, BIT_KEYWORD, unres)) {
3460 return EXIT_FAILURE;
3461 }
3462 if (yang_check_ext_instance(module, &type->info.bits.bit[i].ext, type->info.bits.bit[i].ext_size,
3463 &type->info.bits.bit[i], unres)) {
3464 return EXIT_FAILURE;
3465 }
3466 }
3467 break;
3468 case LY_TYPE_IDENT:
3469 if (yang_check_identityref(module, type, unres)) {
3470 return EXIT_FAILURE;
3471 }
3472 break;
3473 case LY_TYPE_STRING:
3474 if (type->info.str.length && yang_check_ext_instance(module, &type->info.str.length->ext,
3475 type->info.str.length->ext_size, type->info.str.length, unres)) {
3476 return EXIT_FAILURE;
3477 }
3478 for (i = 0; i < type->info.str.pat_count; ++i) {
3479 if (yang_check_ext_instance(module, &type->info.str.patterns[i].ext, type->info.str.patterns[i].ext_size,
3480 &type->info.str.patterns[i], unres)) {
3481 return EXIT_FAILURE;
3482 }
3483 }
3484 break;
3485 case LY_TYPE_DEC64:
3486 if (type->info.dec64.range && yang_check_ext_instance(module, &type->info.dec64.range->ext,
3487 type->info.dec64.range->ext_size, type->info.dec64.range, unres)) {
3488 return EXIT_FAILURE;
3489 }
3490 break;
3491 case LY_TYPE_UNION:
3492 for (i = 0; i < type->info.uni.count; ++i) {
3493 if (yang_fill_type(module, &type->info.uni.types[i], (struct yang_type *)type->info.uni.types[i].der,
3494 parent, unres)) {
3495 return EXIT_FAILURE;
3496 }
3497 }
Radek Krejci57b41682017-03-07 12:33:24 +01003498 break;
PavolVican056fcd12017-02-07 15:36:53 +01003499 default:
3500 /* nothing checks */
3501 break;
3502 }
3503 return EXIT_SUCCESS;
3504}
3505
3506int
Pavol Vican7313fc02016-11-14 01:10:31 +01003507yang_check_typedef(struct lys_module *module, struct lys_node *parent, struct unres_schema *unres)
3508{
3509 struct lys_tpdf *tpdf;
PavolVican056fcd12017-02-07 15:36:53 +01003510 uint8_t i, tpdf_size, *ptr_tpdf_size;
Pavol Vican7313fc02016-11-14 01:10:31 +01003511
3512 if (!parent) {
3513 tpdf = module->tpdf;
3514 ptr_tpdf_size = &module->tpdf_size;
Pavol Vican05810b62016-11-23 14:07:22 +01003515 } else {
3516 switch (parent->nodetype) {
3517 case LYS_GROUPING:
3518 tpdf = ((struct lys_node_grp *)parent)->tpdf;
3519 ptr_tpdf_size = &((struct lys_node_grp *)parent)->tpdf_size;
3520 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003521 case LYS_CONTAINER:
3522 tpdf = ((struct lys_node_container *)parent)->tpdf;
3523 ptr_tpdf_size = &((struct lys_node_container *)parent)->tpdf_size;
3524 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01003525 case LYS_LIST:
3526 tpdf = ((struct lys_node_list *)parent)->tpdf;
3527 ptr_tpdf_size = &((struct lys_node_list *)parent)->tpdf_size;
3528 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003529 case LYS_RPC:
3530 case LYS_ACTION:
3531 tpdf = ((struct lys_node_rpc_action *)parent)->tpdf;
3532 ptr_tpdf_size = &((struct lys_node_rpc_action *)parent)->tpdf_size;
3533 break;
Pavol Vican78729392016-11-28 17:18:22 +01003534 case LYS_INPUT:
3535 case LYS_OUTPUT:
3536 tpdf = ((struct lys_node_inout *)parent)->tpdf;
3537 ptr_tpdf_size = &((struct lys_node_inout *)parent)->tpdf_size;
3538 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01003539 case LYS_NOTIF:
3540 tpdf = ((struct lys_node_notif *)parent)->tpdf;
3541 ptr_tpdf_size = &((struct lys_node_notif *)parent)->tpdf_size;
3542 break;
Pavol Vican05810b62016-11-23 14:07:22 +01003543 default:
3544 LOGINT;
3545 return EXIT_FAILURE;
3546 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003547 }
3548
3549 tpdf_size = *ptr_tpdf_size;
3550 *ptr_tpdf_size = 0;
3551
3552 for (i = 0; i < tpdf_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003553 if (lyp_check_identifier(tpdf[i].name, LY_IDENT_TYPE, module, parent)) {
3554 goto error;
3555 }
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003556
PavolVican056fcd12017-02-07 15:36:53 +01003557 if (yang_fill_type(module, &tpdf[i].type, (struct yang_type *)tpdf[i].type.der, &tpdf[i], unres)) {
3558 goto error;
Pavol Vican5c8a9ad2016-11-22 11:50:54 +01003559 }
PavolVicandf9e7972017-02-07 11:41:38 +01003560 if (yang_check_ext_instance(module, &tpdf[i].ext, tpdf[i].ext_size, &tpdf[i], unres)) {
3561 goto error;
3562 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003563 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPE_DER_TPDF, parent) == -1) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003564 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003565 }
3566
PavolVicane87cb932016-12-30 15:36:18 +01003567 (*ptr_tpdf_size)++;
Pavol Vican7313fc02016-11-14 01:10:31 +01003568 /* check default value*/
Radek Krejciab08f0f2017-03-09 16:37:15 +01003569 if (unres_schema_add_node(module, unres, &tpdf[i].type, UNRES_TYPEDEF_DFLT,
3570 (struct lys_node *)(&tpdf[i].dflt)) == -1) {
Pavol Vican7313fc02016-11-14 01:10:31 +01003571 ++i;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003572 goto error;
Pavol Vican7313fc02016-11-14 01:10:31 +01003573 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003574 }
Pavol Vican7313fc02016-11-14 01:10:31 +01003575
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003576 return EXIT_SUCCESS;
3577
3578error:
3579 yang_tpdf_free(module->ctx, tpdf, i, tpdf_size);
3580 return EXIT_FAILURE;
Pavol Vican7313fc02016-11-14 01:10:31 +01003581}
3582
3583static int
Pavol Vican36e27272016-11-22 15:47:28 +01003584yang_check_identities(struct lys_module *module, struct unres_schema *unres)
3585{
3586 uint32_t i, size, base_size;
3587 uint8_t j;
3588
3589 size = module->ident_size;
3590 module->ident_size = 0;
3591 for (i = 0; i < size; ++i) {
3592 base_size = module->ident[i].base_size;
3593 module->ident[i].base_size = 0;
3594 for (j = 0; j < base_size; ++j) {
3595 if (yang_read_base(module, &module->ident[i], (char *)module->ident[i].base[j], unres)) {
3596 ++j;
3597 module->ident_size = size;
3598 goto error;
3599 }
3600 }
3601 module->ident_size++;
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003602 if (yang_check_iffeatures(module, NULL, &module->ident[i], IDENTITY_KEYWORD, unres)) {
3603 goto error;
3604 }
PavolVican8fa31242017-02-07 11:04:26 +01003605 if (yang_check_ext_instance(module, &module->ident[i].ext, module->ident[i].ext_size, &module->ident[i], unres)) {
3606 goto error;
3607 }
Pavol Vican36e27272016-11-22 15:47:28 +01003608 }
3609
PavolVican8fa31242017-02-07 11:04:26 +01003610
Pavol Vican36e27272016-11-22 15:47:28 +01003611 return EXIT_SUCCESS;
3612
3613error:
3614 for (; j< module->ident[i].base_size; ++j) {
3615 free(module->ident[i].base[j]);
3616 }
3617 yang_free_ident_base(module->ident, i + 1, size);
3618 return EXIT_FAILURE;
3619}
3620
3621static int
PavolVican38104a32017-02-08 12:25:23 +01003622yang_check_must(struct lys_module *module, struct lys_restr *must, uint size, struct unres_schema *unres)
3623{
3624 uint i;
3625
3626 for (i = 0; i < size; ++i) {
3627 if (yang_check_ext_instance(module, &must[i].ext, must[i].ext_size, &must[i], unres)) {
3628 return EXIT_FAILURE;
3629 }
3630 }
3631 return EXIT_SUCCESS;
3632}
3633
3634static int
PavolVicane87cb932016-12-30 15:36:18 +01003635yang_check_container(struct lys_module *module, struct lys_node_container *cont, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003636 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01003637{
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003638 if (yang_check_typedef(module, (struct lys_node *)cont, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01003639 goto error;
3640 }
3641
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003642 if (yang_check_iffeatures(module, NULL, cont, CONTAINER_KEYWORD, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003643 goto error;
3644 }
3645
Radek Krejci7212e0a2017-03-08 15:58:22 +01003646 if (yang_check_nodes(module, (struct lys_node *)cont, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003647 *child = NULL;
3648 goto error;
3649 }
3650 *child = NULL;
3651
PavolVican59ba4602017-02-08 11:53:32 +01003652 if (cont->when && yang_check_ext_instance(module, &cont->when->ext, cont->when->ext_size, cont->when, unres)) {
3653 goto error;
3654 }
PavolVican38104a32017-02-08 12:25:23 +01003655 if (yang_check_must(module, cont->must, cont->must_size, unres)) {
3656 goto error;
3657 }
3658
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003659 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01003660 if (cont->when || cont->must_size) {
3661 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003662 if (lyxp_node_check_syntax((struct lys_node *)cont)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003663 goto error;
3664 }
3665 } else {
3666 if (unres_schema_add_node(module, unres, cont, UNRES_XPATH, NULL) == -1) {
3667 goto error;
3668 }
3669 }
Pavol Vicanc54a8f72016-11-23 16:45:55 +01003670 }
3671
3672 return EXIT_SUCCESS;
3673error:
3674 return EXIT_FAILURE;
3675}
3676
3677static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003678yang_check_leaf(struct lys_module *module, struct lys_node_leaf *leaf, int options, struct unres_schema *unres)
Pavol Vicana69aff22016-11-24 18:23:50 +01003679{
PavolVican056fcd12017-02-07 15:36:53 +01003680 if (yang_fill_type(module, &leaf->type, (struct yang_type *)leaf->type.der, leaf, unres)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003681 yang_type_free(module->ctx, &leaf->type);
3682 goto error;
Pavol Vicana69aff22016-11-24 18:23:50 +01003683 }
PavolVicana08d3652016-12-29 21:07:47 +01003684 if (yang_check_iffeatures(module, NULL, leaf, LEAF_KEYWORD, unres)) {
3685 yang_type_free(module->ctx, &leaf->type);
3686 goto error;
3687 }
3688
Pavol Vicanfda8c802016-12-03 02:00:42 +01003689 if (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DER, (struct lys_node *)leaf) == -1) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003690 yang_type_free(module->ctx, &leaf->type);
3691 goto error;
3692 }
3693
Radek Krejciab08f0f2017-03-09 16:37:15 +01003694 if (!(options & LYS_PARSE_OPT_INGRP) &&
3695 (unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)&leaf->dflt) == -1)) {
Pavol Vicana69aff22016-11-24 18:23:50 +01003696 goto error;
3697 }
3698
PavolVican59ba4602017-02-08 11:53:32 +01003699 if (leaf->when && yang_check_ext_instance(module, &leaf->when->ext, leaf->when->ext_size, leaf->when, unres)) {
3700 goto error;
3701 }
PavolVican38104a32017-02-08 12:25:23 +01003702 if (yang_check_must(module, leaf->must, leaf->must_size, unres)) {
3703 goto error;
3704 }
Michal Vasko89afc112017-03-16 13:57:28 +01003705
Pavol Vicana69aff22016-11-24 18:23:50 +01003706 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01003707 if (leaf->when || leaf->must_size) {
3708 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003709 if (lyxp_node_check_syntax((struct lys_node *)leaf)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003710 goto error;
3711 }
3712 } else {
3713 if (unres_schema_add_node(module, unres, leaf, UNRES_XPATH, NULL) == -1) {
3714 goto error;
3715 }
3716 }
Pavol Vicana69aff22016-11-24 18:23:50 +01003717 }
3718
3719 return EXIT_SUCCESS;
3720error:
3721 return EXIT_FAILURE;
3722}
3723
3724static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003725yang_check_leaflist(struct lys_module *module, struct lys_node_leaflist *leaflist, int options,
3726 struct unres_schema *unres)
Pavol Vican36aff862016-11-26 17:07:05 +01003727{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003728 int i, j;
Pavol Vican36aff862016-11-26 17:07:05 +01003729
PavolVican056fcd12017-02-07 15:36:53 +01003730 if (yang_fill_type(module, &leaflist->type, (struct yang_type *)leaflist->type.der, leaflist, unres)) {
PavolVican6a2148f2017-02-07 23:09:55 +01003731 yang_type_free(module->ctx, &leaflist->type);
3732 goto error;
Pavol Vican36aff862016-11-26 17:07:05 +01003733 }
PavolVicana08d3652016-12-29 21:07:47 +01003734 if (yang_check_iffeatures(module, NULL, leaflist, LEAF_LIST_KEYWORD, unres)) {
3735 yang_type_free(module->ctx, &leaflist->type);
3736 goto error;
3737 }
3738
Pavol Vicanfda8c802016-12-03 02:00:42 +01003739 if (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DER, (struct lys_node *)leaflist) == -1) {
Pavol Vican36aff862016-11-26 17:07:05 +01003740 yang_type_free(module->ctx, &leaflist->type);
3741 goto error;
3742 }
3743
Pavol Vican36aff862016-11-26 17:07:05 +01003744 for (i = 0; i < leaflist->dflt_size; ++i) {
Pavol Vicanfda8c802016-12-03 02:00:42 +01003745 /* check for duplicity in case of configuration data,
3746 * in case of status data duplicities are allowed */
3747 if (leaflist->flags & LYS_CONFIG_W) {
3748 for (j = i +1; j < leaflist->dflt_size; ++j) {
3749 if (ly_strequal(leaflist->dflt[i], leaflist->dflt[j], 1)) {
PavolVican196694c2017-01-27 10:33:09 +01003750 LOGVAL(LYE_INARG, LY_VLOG_LYS, leaflist, leaflist->dflt[i], "default");
3751 LOGVAL(LYE_SPEC, LY_VLOG_LYS, leaflist, "Duplicated default value \"%s\".", leaflist->dflt[i]);
Pavol Vicanfda8c802016-12-03 02:00:42 +01003752 goto error;
3753 }
3754 }
3755 }
3756 /* check default value (if not defined, there still could be some restrictions
3757 * that need to be checked against a default value from a derived type) */
Radek Krejciab08f0f2017-03-09 16:37:15 +01003758 if (!(options & LYS_PARSE_OPT_INGRP) &&
3759 (unres_schema_add_node(module, unres, &leaflist->type, UNRES_TYPE_DFLT,
3760 (struct lys_node *)(&leaflist->dflt[i])) == -1)) {
Pavol Vican36aff862016-11-26 17:07:05 +01003761 goto error;
3762 }
3763 }
3764
PavolVican59ba4602017-02-08 11:53:32 +01003765 if (leaflist->when && yang_check_ext_instance(module, &leaflist->when->ext, leaflist->when->ext_size, leaflist->when, unres)) {
3766 goto error;
3767 }
PavolVican38104a32017-02-08 12:25:23 +01003768 if (yang_check_must(module, leaflist->must, leaflist->must_size, unres)) {
3769 goto error;
3770 }
PavolVican59ba4602017-02-08 11:53:32 +01003771
Pavol Vican36aff862016-11-26 17:07:05 +01003772 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01003773 if (leaflist->when || leaflist->must_size) {
3774 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003775 if (lyxp_node_check_syntax((struct lys_node *)leaflist)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003776 goto error;
3777 }
3778 } else {
3779 if (unres_schema_add_node(module, unres, leaflist, UNRES_XPATH, NULL) == -1) {
3780 goto error;
3781 }
3782 }
Pavol Vican36aff862016-11-26 17:07:05 +01003783 }
3784
3785 return EXIT_SUCCESS;
3786error:
3787 return EXIT_FAILURE;
3788}
3789
3790static int
PavolVicane87cb932016-12-30 15:36:18 +01003791yang_check_list(struct lys_module *module, struct lys_node_list *list, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003792 int options, struct unres_schema *unres)
Pavol Vicand8136a42016-11-27 13:28:04 +01003793{
Pavol Vicanfda8c802016-12-03 02:00:42 +01003794 struct lys_node *node;
3795
Pavol Vicand8136a42016-11-27 13:28:04 +01003796 if (yang_check_typedef(module, (struct lys_node *)list, unres)) {
3797 goto error;
3798 }
3799
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003800 if (yang_check_iffeatures(module, NULL, list, LIST_KEYWORD, unres)) {
3801 goto error;
Pavol Vicand8136a42016-11-27 13:28:04 +01003802 }
3803
Pavol Vicanfda8c802016-12-03 02:00:42 +01003804 if (list->flags & LYS_CONFIG_R) {
3805 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data
3806 * ignore oredering MASK - 0x7F
3807 */
3808 list->flags &= 0x7F;
3809 }
3810 /* check - if list is configuration, key statement is mandatory
3811 * (but only if we are not in a grouping or augment, then the check is deferred) */
PavolVicanc68dfea2017-02-21 15:40:43 +01003812 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 +01003813 if (!node && (list->flags & LYS_CONFIG_W) && !list->keys) {
3814 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_LYS, list, "key", "list");
3815 goto error;
3816 }
3817
Radek Krejci7212e0a2017-03-08 15:58:22 +01003818 if (yang_check_nodes(module, (struct lys_node *)list, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003819 *child = NULL;
3820 goto error;
3821 }
3822 *child = NULL;
3823
Pavol Vicand8136a42016-11-27 13:28:04 +01003824 if (list->keys && yang_read_key(module, list, unres)) {
3825 goto error;
3826 }
3827
3828 if (yang_read_unique(module, list, unres)) {
3829 goto error;
3830 }
3831
PavolVican59ba4602017-02-08 11:53:32 +01003832 if (list->when && yang_check_ext_instance(module, &list->when->ext, list->when->ext_size, list->when, unres)) {
3833 goto error;
3834 }
PavolVican38104a32017-02-08 12:25:23 +01003835 if (yang_check_must(module, list->must, list->must_size, unres)) {
3836 goto error;
3837 }
Michal Vasko89afc112017-03-16 13:57:28 +01003838
Pavol Vicand8136a42016-11-27 13:28:04 +01003839 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01003840 if (list->when || list->must_size) {
3841 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003842 if (lyxp_node_check_syntax((struct lys_node *)list)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003843 goto error;
3844 }
3845 } else {
3846 if (unres_schema_add_node(module, unres, list, UNRES_XPATH, NULL) == -1) {
3847 goto error;
3848 }
3849 }
Pavol Vicand8136a42016-11-27 13:28:04 +01003850 }
3851
3852 return EXIT_SUCCESS;
3853error:
3854 return EXIT_FAILURE;
3855}
3856
3857static int
PavolVicane87cb932016-12-30 15:36:18 +01003858yang_check_choice(struct lys_module *module, struct lys_node_choice *choice, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003859 int options, struct unres_schema *unres)
Pavol Vican36ace102016-11-28 11:46:59 +01003860{
3861 char *value;
Pavol Vican36ace102016-11-28 11:46:59 +01003862
PavolVicana08d3652016-12-29 21:07:47 +01003863 if (yang_check_iffeatures(module, NULL, choice, CHOICE_KEYWORD, unres)) {
3864 free(choice->dflt);
3865 choice->dflt = NULL;
3866 goto error;
3867 }
3868
Radek Krejci7212e0a2017-03-08 15:58:22 +01003869 if (yang_check_nodes(module, (struct lys_node *)choice, *child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003870 *child = NULL;
3871 free(choice->dflt);
3872 choice->dflt = NULL;
3873 goto error;
3874 }
3875 *child = NULL;
3876
Pavol Vican36ace102016-11-28 11:46:59 +01003877 if (choice->dflt) {
3878 value = (char *)choice->dflt;
3879 choice->dflt = NULL;
3880 if (unres_schema_add_str(module, unres, choice, UNRES_CHOICE_DFLT, value) == -1) {
3881 free(value);
3882 goto error;
3883 }
3884 free(value);
3885 }
3886
PavolVican59ba4602017-02-08 11:53:32 +01003887 if (choice->when && yang_check_ext_instance(module, &choice->when->ext, choice->when->ext_size, choice->when, unres)) {
3888 goto error;
3889 }
3890
Pavol Vican36ace102016-11-28 11:46:59 +01003891 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01003892 if (choice->when) {
3893 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003894 if (lyxp_node_check_syntax((struct lys_node *)choice)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003895 goto error;
3896 }
3897 } else {
3898 if (unres_schema_add_node(module, unres, choice, UNRES_XPATH, NULL) == -1) {
3899 goto error;
3900 }
3901 }
Pavol Vican36ace102016-11-28 11:46:59 +01003902 }
3903
3904 return EXIT_SUCCESS;
3905error:
3906 return EXIT_FAILURE;
3907}
3908
3909static int
PavolVicane87cb932016-12-30 15:36:18 +01003910yang_check_rpc_action(struct lys_module *module, struct lys_node_rpc_action *rpc, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003911 int options, struct unres_schema *unres)
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003912{
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003913 struct lys_node *node;
3914
3915 if (rpc->nodetype == LYS_ACTION) {
3916 for (node = rpc->parent; node; node = lys_parent(node)) {
3917 if ((node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
Pavol Vican73ff8032016-12-04 15:03:51 +01003918 || ((node->nodetype == LYS_LIST) && !((struct lys_node_list *)node)->keys)) {
PavolVican196694c2017-01-27 10:33:09 +01003919 LOGVAL(LYE_INPAR, LY_VLOG_LYS, rpc->parent, strnodetype(node->nodetype), "action");
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003920 goto error;
3921 }
3922 }
3923 }
3924 if (yang_check_typedef(module, (struct lys_node *)rpc, unres)) {
3925 goto error;
3926 }
3927
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003928 if (yang_check_iffeatures(module, NULL, rpc, RPC_KEYWORD, unres)) {
3929 goto error;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003930 }
3931
Radek Krejci7212e0a2017-03-08 15:58:22 +01003932 if (yang_check_nodes(module, (struct lys_node *)rpc, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003933 *child = NULL;
3934 goto error;
3935 }
3936 *child = NULL;
3937
Pavol Vicanebc9ef82016-11-28 16:46:49 +01003938 return EXIT_SUCCESS;
3939error:
3940 return EXIT_FAILURE;
3941}
3942
3943static int
PavolVicane87cb932016-12-30 15:36:18 +01003944yang_check_notif(struct lys_module *module, struct lys_node_notif *notif, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01003945 int options, struct unres_schema *unres)
Pavol Vican29bf8802016-11-28 20:44:57 +01003946{
Pavol Vican29bf8802016-11-28 20:44:57 +01003947 if (yang_check_typedef(module, (struct lys_node *)notif, unres)) {
3948 goto error;
3949 }
3950
Pavol Vicandf9a95c2016-12-02 23:34:51 +01003951 if (yang_check_iffeatures(module, NULL, notif, NOTIFICATION_KEYWORD, unres)) {
3952 goto error;
Pavol Vican29bf8802016-11-28 20:44:57 +01003953 }
3954
Radek Krejci7212e0a2017-03-08 15:58:22 +01003955 if (yang_check_nodes(module, (struct lys_node *)notif, *child, options | LYS_PARSE_OPT_CFG_IGNORE, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01003956 *child = NULL;
3957 goto error;
3958 }
3959 *child = NULL;
3960
Michal Vasko89afc112017-03-16 13:57:28 +01003961 if (yang_check_must(module, notif->must, notif->must_size, unres)) {
3962 goto error;
3963 }
3964
3965 /* check XPath dependencies */
PavolVican38104a32017-02-08 12:25:23 +01003966 if (notif->must_size) {
Michal Vasko89afc112017-03-16 13:57:28 +01003967 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01003968 if (lyxp_node_check_syntax((struct lys_node *)notif)) {
Michal Vasko89afc112017-03-16 13:57:28 +01003969 goto error;
3970 }
3971 } else {
3972 if (unres_schema_add_node(module, unres, notif, UNRES_XPATH, NULL) == -1) {
3973 goto error;
3974 }
PavolVican38104a32017-02-08 12:25:23 +01003975 }
Pavol Vican29bf8802016-11-28 20:44:57 +01003976 }
3977
3978 return EXIT_SUCCESS;
3979error:
3980 return EXIT_FAILURE;
3981}
3982
3983static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01003984yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int options, struct unres_schema *unres)
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003985{
Pavol Vican3ad50f82016-12-04 15:00:36 +01003986 struct lys_node *child;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01003987
Pavol Vican3ad50f82016-12-04 15:00:36 +01003988 child = augment->child;
3989 augment->child = NULL;
3990
PavolVicana08d3652016-12-29 21:07:47 +01003991 if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
3992 yang_free_nodes(module->ctx, child);
Pavol Vican3ad50f82016-12-04 15:00:36 +01003993 goto error;
3994 }
3995
Radek Krejci7212e0a2017-03-08 15:58:22 +01003996 if (yang_check_nodes(module, (struct lys_node *)augment, child, options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01003997 goto error;
3998 }
3999
PavolVicanfa9510e2017-02-08 17:20:46 +01004000 if (yang_check_ext_instance(module, &augment->ext, augment->ext_size, augment, unres)) {
4001 goto error;
4002 }
4003
PavolVican59ba4602017-02-08 11:53:32 +01004004 if (augment->when && yang_check_ext_instance(module, &augment->when->ext, augment->when->ext_size, augment->when, unres)) {
4005 goto error;
4006 }
4007
Pavol Vican3ad50f82016-12-04 15:00:36 +01004008 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01004009 if (augment->when) {
4010 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004011 if (lyxp_node_check_syntax((struct lys_node *)augment)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004012 goto error;
4013 }
4014 } else {
4015 if (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1) {
4016 goto error;
4017 }
4018 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004019 }
4020
4021 return EXIT_SUCCESS;
4022error:
4023 return EXIT_FAILURE;
4024}
4025
4026static int
Radek Krejci7212e0a2017-03-08 15:58:22 +01004027yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int options, struct unres_schema *unres)
Pavol Vican3ad50f82016-12-04 15:00:36 +01004028{
4029 uint i, size;
4030
4031 size = uses->augment_size;
4032 uses->augment_size = 0;
4033
4034 if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004035 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004036 }
4037
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004038 for (i = 0; i < uses->refine_size; ++i) {
PavolVican77374ee2017-02-08 15:18:45 +01004039 if (yang_check_iffeatures(module, &uses->refine[i], uses, REFINE_KEYWORD, unres)) {
4040 goto error;
4041 }
4042 if (yang_check_must(module, uses->refine[i].must, uses->refine[i].must_size, unres)) {
4043 goto error;
4044 }
4045 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 +01004046 goto error;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004047 }
4048 }
4049
Pavol Vican3ad50f82016-12-04 15:00:36 +01004050 for (i = 0; i < size; ++i) {
4051 uses->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004052 if (yang_check_augment(module, &uses->augment[i], options, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004053 goto error;
4054 }
4055 }
4056
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004057 if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
4058 goto error;
4059 }
4060
PavolVican59ba4602017-02-08 11:53:32 +01004061 if (uses->when && yang_check_ext_instance(module, &uses->when->ext, uses->when->ext_size, uses->when, unres)) {
4062 goto error;
4063 }
4064
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004065 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01004066 if (uses->when) {
4067 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004068 if (lyxp_node_check_syntax((struct lys_node *)uses)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004069 goto error;
4070 }
4071 } else {
4072 if (unres_schema_add_node(module, unres, uses, UNRES_XPATH, NULL) == -1) {
4073 goto error;
4074 }
4075 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004076 }
4077
4078 return EXIT_SUCCESS;
4079error:
Pavol Vican3ad50f82016-12-04 15:00:36 +01004080 for (i = uses->augment_size; i < size; ++i) {
4081 yang_free_augment(module->ctx, &uses->augment[i]);
4082 }
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004083 return EXIT_FAILURE;
4084}
4085
4086static int
PavolVican59ba4602017-02-08 11:53:32 +01004087yang_check_anydata(struct lys_module *module, struct lys_node_anydata *anydata, struct lys_node **child,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004088 int options, struct unres_schema *unres)
PavolVican59ba4602017-02-08 11:53:32 +01004089{
4090 if (yang_check_iffeatures(module, NULL, anydata, ANYDATA_KEYWORD, unres)) {
4091 goto error;
4092 }
4093
Radek Krejci7212e0a2017-03-08 15:58:22 +01004094 if (yang_check_nodes(module, (struct lys_node *)anydata, *child, options, unres)) {
PavolVican59ba4602017-02-08 11:53:32 +01004095 *child = NULL;
4096 goto error;
4097 }
4098 *child = NULL;
4099
4100 if (anydata->when && yang_check_ext_instance(module, &anydata->when->ext, anydata->when->ext_size, anydata->when, unres)) {
4101 goto error;
4102 }
PavolVican38104a32017-02-08 12:25:23 +01004103 if (yang_check_must(module, anydata->must, anydata->must_size, unres)) {
4104 goto error;
4105 }
PavolVican59ba4602017-02-08 11:53:32 +01004106
4107 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01004108 if (anydata->when || anydata->must_size) {
4109 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004110 if (lyxp_node_check_syntax((struct lys_node *)anydata)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004111 goto error;
4112 }
4113 } else {
4114 if (unres_schema_add_node(module, unres, anydata, UNRES_XPATH, NULL) == -1) {
4115 goto error;
4116 }
4117 }
PavolVican59ba4602017-02-08 11:53:32 +01004118 }
Michal Vasko89afc112017-03-16 13:57:28 +01004119
PavolVican59ba4602017-02-08 11:53:32 +01004120 return EXIT_SUCCESS;
4121error:
4122 return EXIT_FAILURE;
4123}
4124
4125static int
Pavol Vican3ad50f82016-12-04 15:00:36 +01004126yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
Radek Krejci7212e0a2017-03-08 15:58:22 +01004127 int options, struct unres_schema *unres)
Pavol Vican05810b62016-11-23 14:07:22 +01004128{
Pavol Vican3ad50f82016-12-04 15:00:36 +01004129 struct lys_node *node = nodes, *sibling, *child;
Pavol Vican05810b62016-11-23 14:07:22 +01004130
4131 while (node) {
4132 sibling = node->next;
4133 child = node->child;
4134 node->next = NULL;
4135 node->child = NULL;
4136 node->prev = node;
4137
PavolVican05c4f9b2017-09-07 13:33:54 +02004138 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node) ||
4139 check_status_flag(node, parent)) {
Pavol Vican24ba7f62016-11-28 12:15:20 +01004140 lys_node_unlink(node);
PavolVican4b80d042017-02-23 14:30:27 +01004141 yang_free_nodes(module->ctx, node);
Pavol Vican05810b62016-11-23 14:07:22 +01004142 goto error;
4143 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004144 store_config_flag(node, options);
PavolVican70ce7452017-02-01 15:39:39 +01004145 if (yang_check_ext_instance(module, &node->ext, node->ext_size, node, unres)) {
4146 goto error;
4147 }
Pavol Vicanfda8c802016-12-03 02:00:42 +01004148
Pavol Vican05810b62016-11-23 14:07:22 +01004149 switch (node->nodetype) {
4150 case LYS_GROUPING:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004151 if (yang_check_typedef(module, node, unres)) {
4152 goto error;
4153 }
4154 if (yang_check_iffeatures(module, NULL, node, GROUPING_KEYWORD, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004155 goto error;
4156 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004157 if (yang_check_nodes(module, node, child, options | LYS_PARSE_OPT_INGRP, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004158 child = NULL;
4159 goto error;
4160 }
Pavol Vican05810b62016-11-23 14:07:22 +01004161 break;
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004162 case LYS_CONTAINER:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004163 if (yang_check_container(module, (struct lys_node_container *)node, &child, options, unres)) {
Pavol Vicanc54a8f72016-11-23 16:45:55 +01004164 goto error;
4165 }
4166 break;
Pavol Vicana69aff22016-11-24 18:23:50 +01004167 case LYS_LEAF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004168 if (yang_check_leaf(module, (struct lys_node_leaf *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004169 child = NULL;
Pavol Vicana69aff22016-11-24 18:23:50 +01004170 goto error;
4171 }
4172 break;
Pavol Vican36aff862016-11-26 17:07:05 +01004173 case LYS_LEAFLIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004174 if (yang_check_leaflist(module, (struct lys_node_leaflist *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004175 child = NULL;
Pavol Vican36aff862016-11-26 17:07:05 +01004176 goto error;
4177 }
4178 break;
Pavol Vicand8136a42016-11-27 13:28:04 +01004179 case LYS_LIST:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004180 if (yang_check_list(module, (struct lys_node_list *)node, &child, options, unres)) {
Pavol Vicand8136a42016-11-27 13:28:04 +01004181 goto error;
4182 }
4183 break;
Pavol Vican36ace102016-11-28 11:46:59 +01004184 case LYS_CHOICE:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004185 if (yang_check_choice(module, (struct lys_node_choice *)node, &child, options, unres)) {
Pavol Vican36ace102016-11-28 11:46:59 +01004186 goto error;
4187 }
4188 break;
Pavol Vicana420bac2016-11-28 14:51:54 +01004189 case LYS_CASE:
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004190 if (yang_check_iffeatures(module, NULL, node, CASE_KEYWORD, unres)) {
Pavol Vicana420bac2016-11-28 14:51:54 +01004191 goto error;
4192 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004193 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004194 child = NULL;
4195 goto error;
4196 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004197 if (((struct lys_node_case *)node)->when) {
4198 if (yang_check_ext_instance(module, &((struct lys_node_case *)node)->when->ext,
4199 ((struct lys_node_case *)node)->when->ext_size, ((struct lys_node_case *)node)->when, unres)) {
4200 goto error;
4201 }
4202 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01004203 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004204 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004205 goto error;
4206 }
4207 } else {
4208 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4209 goto error;
4210 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004211 }
4212 }
Pavol Vicana420bac2016-11-28 14:51:54 +01004213 break;
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004214 case LYS_ANYDATA:
4215 case LYS_ANYXML:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004216 if (yang_check_anydata(module, (struct lys_node_anydata *)node, &child, options, unres)) {
Pavol Vicanbfa1a582016-11-28 15:35:59 +01004217 goto error;
4218 }
4219 break;
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004220 case LYS_RPC:
4221 case LYS_ACTION:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004222 if (yang_check_rpc_action(module, (struct lys_node_rpc_action *)node, &child, options, unres)){
Pavol Vicanebc9ef82016-11-28 16:46:49 +01004223 goto error;
4224 }
4225 break;
Pavol Vican78729392016-11-28 17:18:22 +01004226 case LYS_INPUT:
4227 case LYS_OUTPUT:
PavolVicane87cb932016-12-30 15:36:18 +01004228 if (yang_check_typedef(module, node, unres)) {
4229 goto error;
4230 }
Radek Krejci7212e0a2017-03-08 15:58:22 +01004231 if (yang_check_nodes(module, node, child, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004232 child = NULL;
4233 goto error;
4234 }
PavolVican38104a32017-02-08 12:25:23 +01004235 if (((struct lys_node_inout *)node)->must_size) {
4236 if (yang_check_must(module, ((struct lys_node_inout *)node)->must, ((struct lys_node_inout *)node)->must_size, unres)) {
4237 goto error;
4238 }
4239 /* check XPath dependencies */
Michal Vasko89afc112017-03-16 13:57:28 +01004240 if (options & LYS_PARSE_OPT_INGRP) {
Michal Vasko364918a2017-03-17 13:23:46 +01004241 if (lyxp_node_check_syntax(node)) {
Michal Vasko89afc112017-03-16 13:57:28 +01004242 goto error;
4243 }
4244 } else {
4245 if (unres_schema_add_node(module, unres, node, UNRES_XPATH, NULL) == -1) {
4246 goto error;
4247 }
PavolVican38104a32017-02-08 12:25:23 +01004248 }
Pavol Vican78729392016-11-28 17:18:22 +01004249 }
Pavol Vican78729392016-11-28 17:18:22 +01004250 break;
Pavol Vican29bf8802016-11-28 20:44:57 +01004251 case LYS_NOTIF:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004252 if (yang_check_notif(module, (struct lys_node_notif *)node, &child, options, unres)) {
Pavol Vican29bf8802016-11-28 20:44:57 +01004253 goto error;
4254 }
4255 break;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004256 case LYS_USES:
Radek Krejci7212e0a2017-03-08 15:58:22 +01004257 if (yang_check_uses(module, (struct lys_node_uses *)node, options, unres)) {
PavolVicane87cb932016-12-30 15:36:18 +01004258 child = NULL;
Pavol Vican3b5e82a2016-11-29 21:41:56 +01004259 goto error;
4260 }
4261 break;
Pavol Vican05810b62016-11-23 14:07:22 +01004262 default:
4263 LOGINT;
Pavol Vican05810b62016-11-23 14:07:22 +01004264 goto error;
4265 }
Pavol Vican05810b62016-11-23 14:07:22 +01004266 node = sibling;
4267 }
4268
4269 return EXIT_SUCCESS;
4270error:
4271 yang_free_nodes(module->ctx, sibling);
4272 yang_free_nodes(module->ctx, child);
4273 return EXIT_FAILURE;
4274}
4275
4276static int
PavolVican75af21d2016-12-29 20:04:07 +01004277yang_check_deviate(struct lys_module *module, struct unres_schema *unres, struct lys_deviate *deviate,
4278 struct lys_node *dev_target, struct ly_set *dflt_check)
4279{
4280 struct lys_node_leaflist *llist;
4281 struct lys_type *type;
4282 struct lys_tpdf *tmp_parent;
4283 int i, j;
4284
PavolVican6f000922017-02-10 12:56:59 +01004285 if (yang_check_ext_instance(module, &deviate->ext, deviate->ext_size, deviate, unres)) {
4286 goto error;
4287 }
PavolVican75af21d2016-12-29 20:04:07 +01004288 if (deviate->must_size && yang_check_deviate_must(module, unres, deviate, dev_target)) {
4289 goto error;
4290 }
4291 if (deviate->unique && yang_check_deviate_unique(module, deviate, dev_target)) {
4292 goto error;
4293 }
4294 if (deviate->dflt_size) {
4295 if (yang_read_deviate_default(module, deviate, dev_target, dflt_check)) {
4296 goto error;
4297 }
4298 if (dev_target->nodetype == LYS_LEAFLIST && deviate->mod == LY_DEVIATE_DEL) {
4299 /* consolidate the final list in the target after removing items from it */
4300 llist = (struct lys_node_leaflist *)dev_target;
4301 for (i = j = 0; j < llist->dflt_size; j++) {
4302 llist->dflt[i] = llist->dflt[j];
4303 if (llist->dflt[i]) {
4304 i++;
4305 }
4306 }
4307 llist->dflt_size = i + 1;
4308 }
4309 }
4310
4311 if (deviate->max_set && yang_read_deviate_minmax(deviate, dev_target, deviate->max, 1)) {
4312 goto error;
4313 }
4314
4315 if (deviate->min_set && yang_read_deviate_minmax(deviate, dev_target, deviate->min, 0)) {
4316 goto error;
4317 }
4318
4319 if (deviate->units && yang_read_deviate_units(module->ctx, deviate, dev_target)) {
4320 goto error;
4321 }
4322
4323 if ((deviate->flags & LYS_CONFIG_MASK)) {
4324 /* add and replace are the same in this case */
4325 /* remove current config value of the target ... */
4326 dev_target->flags &= ~LYS_CONFIG_MASK;
4327
4328 /* ... and replace it with the value specified in deviation */
4329 dev_target->flags |= deviate->flags & LYS_CONFIG_MASK;
4330 }
4331
4332 if ((deviate->flags & LYS_MAND_MASK) && yang_check_deviate_mandatory(deviate, dev_target)) {
4333 goto error;
4334 }
4335
4336 if (deviate->type) {
4337 /* check target node type */
4338 if (dev_target->nodetype == LYS_LEAF) {
4339 type = &((struct lys_node_leaf *)dev_target)->type;
4340 } else if (dev_target->nodetype == LYS_LEAFLIST) {
4341 type = &((struct lys_node_leaflist *)dev_target)->type;
4342 } else {
4343 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
4344 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
4345 goto error;
4346 }
4347 /* remove type and initialize it */
4348 tmp_parent = type->parent;
Radek Krejci5138e9f2017-04-12 13:10:46 +02004349 lys_type_free(module->ctx, type, NULL);
PavolVican75af21d2016-12-29 20:04:07 +01004350 memcpy(type, deviate->type, sizeof *deviate->type);
4351 free(deviate->type);
4352 deviate->type = type;
4353 deviate->type->parent = tmp_parent;
PavolVican6f000922017-02-10 12:56:59 +01004354 if (yang_fill_type(module, type, (struct yang_type *)type->der, tmp_parent, unres)) {
4355 goto error;
4356 }
4357
PavolVican75af21d2016-12-29 20:04:07 +01004358 if (unres_schema_add_node(module, unres, deviate->type, UNRES_TYPE_DER, dev_target) == -1) {
4359 goto error;
4360 }
4361 }
4362
4363 return EXIT_SUCCESS;
4364error:
4365 if (deviate->type) {
4366 yang_type_free(module->ctx, deviate->type);
4367 deviate->type = NULL;
4368 }
4369 return EXIT_FAILURE;
4370}
4371
4372static int
4373yang_check_deviation(struct lys_module *module, struct unres_schema *unres, struct lys_deviation *dev)
4374{
4375 int rc;
4376 uint i;
4377 struct lys_node *dev_target = NULL, *parent;
Michal Vasko50576712017-07-28 12:28:33 +02004378 struct ly_set *dflt_check = ly_set_new(), *set;
PavolVican75af21d2016-12-29 20:04:07 +01004379 unsigned int u;
4380 const char *value, *target_name;
4381 struct lys_node_leaflist *llist;
4382 struct lys_node_leaf *leaf;
4383 struct unres_schema tmp_unres;
4384 struct lys_module *mod;
4385
4386 /* resolve target node */
Michal Vasko50576712017-07-28 12:28:33 +02004387 rc = resolve_schema_nodeid(dev->target_name, NULL, module, &set, 0, 1);
4388 if (rc == -1) {
PavolVican75af21d2016-12-29 20:04:07 +01004389 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Michal Vasko50576712017-07-28 12:28:33 +02004390 ly_set_free(set);
PavolVican75af21d2016-12-29 20:04:07 +01004391 goto error;
4392 }
Michal Vasko50576712017-07-28 12:28:33 +02004393 dev_target = set->set.s[0];
4394 ly_set_free(set);
4395
PavolVican75af21d2016-12-29 20:04:07 +01004396 if (dev_target->module == lys_main_module(module)) {
4397 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
4398 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
4399 goto error;
4400 }
4401
4402 if (!dflt_check) {
4403 LOGMEM;
4404 goto error;
4405 }
4406
4407 if (dev->deviate[0].mod == LY_DEVIATE_NO) {
4408 /* you cannot remove a key leaf */
4409 if ((dev_target->nodetype == LYS_LEAF) && dev_target->parent && (dev_target->parent->nodetype == LYS_LIST)) {
4410 for (i = 0; i < ((struct lys_node_list *)dev_target->parent)->keys_size; ++i) {
4411 if (((struct lys_node_list *)dev_target->parent)->keys[i] == (struct lys_node_leaf *)dev_target) {
4412 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
4413 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
PavolVican4b80d042017-02-23 14:30:27 +01004414 goto error;
PavolVican75af21d2016-12-29 20:04:07 +01004415 }
4416 }
4417 }
4418 /* unlink and store the original node */
Radek Krejci9cf034c2017-08-24 17:10:35 +02004419 parent = dev_target->parent;
PavolVican75af21d2016-12-29 20:04:07 +01004420 lys_node_unlink(dev_target);
Radek Krejci9cf034c2017-08-24 17:10:35 +02004421 if (parent && parent->nodetype == LYS_AUGMENT) {
4422 /* hack for augment, because when the original will be sometime reconnected back, we actually need
4423 * to reconnect it to both - the augment and its target (which is deduced from the deviations target
4424 * path), so we need to remember the augment as an addition */
4425 dev_target->parent = parent;
4426 }
PavolVican75af21d2016-12-29 20:04:07 +01004427 dev->orig_node = dev_target;
4428 } else {
4429 /* store a shallow copy of the original node */
4430 memset(&tmp_unres, 0, sizeof tmp_unres);
PavolVican8c33b152017-01-27 12:45:34 +01004431 dev->orig_node = lys_node_dup(dev_target->module, NULL, dev_target, &tmp_unres, 1);
PavolVican75af21d2016-12-29 20:04:07 +01004432 /* just to be safe */
4433 if (tmp_unres.count) {
4434 LOGINT;
4435 goto error;
4436 }
4437 }
4438
PavolVican6f000922017-02-10 12:56:59 +01004439 if (yang_check_ext_instance(module, &dev->ext, dev->ext_size, dev, unres)) {
4440 goto error;
4441 }
4442
PavolVican75af21d2016-12-29 20:04:07 +01004443 for (i = 0; i < dev->deviate_size; ++i) {
4444 if (yang_check_deviate(module, unres, &dev->deviate[i], dev_target, dflt_check)) {
4445 yang_free_deviate(module->ctx, dev, i + 1);
4446 dev->deviate_size = i+1;
4447 goto error; // missing free unresolve type in deviate
4448 }
4449 }
4450 /* now check whether default value, if any, matches the type */
4451 for (u = 0; u < dflt_check->number; ++u) {
4452 value = NULL;
4453 rc = EXIT_SUCCESS;
4454 if (dflt_check->set.s[u]->nodetype == LYS_LEAF) {
4455 leaf = (struct lys_node_leaf *)dflt_check->set.s[u];
4456 target_name = leaf->name;
4457 value = leaf->dflt;
4458 rc = unres_schema_add_node(module, unres, &leaf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&leaf->dflt));
4459 } else { /* LYS_LEAFLIST */
4460 llist = (struct lys_node_leaflist *)dflt_check->set.s[u];
4461 target_name = llist->name;
4462 for (i = 0; i < llist->dflt_size; i++) {
4463 rc = unres_schema_add_node(module, unres, &llist->type, UNRES_TYPE_DFLT,
4464 (struct lys_node *)(&llist->dflt[i]));
4465 if (rc == -1) {
4466 value = llist->dflt[i];
4467 break;
4468 }
4469 }
4470 }
4471 if (rc == -1) {
4472 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "default");
4473 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL,
4474 "The default value \"%s\" of the deviated node \"%s\"no longer matches its type.",
4475 target_name);
4476 goto error;
4477 }
4478 }
4479 ly_set_free(dflt_check);
4480
Radek Krejci29eac3d2017-06-01 16:50:02 +02004481 /* mark all the affected modules as deviated and implemented */
4482 for (parent = dev_target; parent; parent = lys_parent(parent)) {
PavolVican75af21d2016-12-29 20:04:07 +01004483 mod = lys_node_module(parent);
4484 if (module != mod) {
Radek Krejci29eac3d2017-06-01 16:50:02 +02004485 mod->deviated = 1; /* main module */
4486 parent->module->deviated = 1; /* possible submodule */
4487 if (lys_set_implemented(mod)) {
4488 LOGERR(ly_errno, "Setting the deviated module \"%s\" implemented failed.", mod->name);
4489 goto error;
4490 }
4491 }
PavolVican75af21d2016-12-29 20:04:07 +01004492 }
PavolVican75af21d2016-12-29 20:04:07 +01004493
4494 return EXIT_SUCCESS;
4495error:
4496 ly_set_free(dflt_check);
4497 return EXIT_FAILURE;
4498}
4499
4500static int
Pavol Vican7313fc02016-11-14 01:10:31 +01004501yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
4502{
PavolVican75af21d2016-12-29 20:04:07 +01004503 uint i, erase_identities = 1, erase_nodes = 1, aug_size, dev_size = 0;
Pavol Vican3ad50f82016-12-04 15:00:36 +01004504
4505 aug_size = module->augment_size;
4506 module->augment_size = 0;
PavolVican75af21d2016-12-29 20:04:07 +01004507 dev_size = module->deviation_size;
4508 module->deviation_size = 0;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004509
PavolVican6f87bf92017-02-15 19:38:55 +01004510 if (yang_check_typedef(module, NULL, unres)) {
4511 goto error;
4512 }
4513
PavolVicanc1807262017-01-31 18:00:27 +01004514 if (yang_check_ext_instance(module, &module->ext, module->ext_size, module, unres)) {
4515 goto error;
4516 }
4517
PavolVican171717d2017-02-01 14:49:55 +01004518 /* check extension in revision */
4519 for (i = 0; i < module->rev_size; ++i) {
4520 if (yang_check_ext_instance(module, &module->rev[i].ext, module->rev[i].ext_size, &module->rev[i], unres)) {
4521 goto error;
4522 }
4523 }
4524
PavolVican19dc6152017-02-06 12:04:15 +01004525 /* check extension in definition of extension */
PavolVican5393d3f2017-02-06 23:30:55 +01004526 for (i = 0; i < module->extensions_size; ++i) {
PavolVican19dc6152017-02-06 12:04:15 +01004527 if (yang_check_ext_instance(module, &module->extensions[i].ext, module->extensions[i].ext_size, &module->extensions[i], unres)) {
4528 goto error;
4529 }
4530 }
4531
Pavol Vican7a7916f2016-11-21 23:38:30 +01004532 /* check features */
4533 for (i = 0; i < module->features_size; ++i) {
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004534 if (yang_check_iffeatures(module, NULL, &module->features[i], FEATURE_KEYWORD, unres)) {
4535 goto error;
4536 }
PavolVican5393d3f2017-02-06 23:30:55 +01004537 if (yang_check_ext_instance(module, &module->features[i].ext, module->features[i].ext_size, &module->features[i], unres)) {
4538 goto error;
4539 }
4540
Pavol Vicandf9a95c2016-12-02 23:34:51 +01004541 /* check for circular dependencies */
4542 if (module->features[i].iffeature_size && (unres_schema_add_node(module, unres, &module->features[i], UNRES_FEATURE, NULL) == -1)) {
4543 goto error;
Pavol Vican7a7916f2016-11-21 23:38:30 +01004544 }
4545 }
Pavol Vican36e27272016-11-22 15:47:28 +01004546 erase_identities = 0;
4547 if (yang_check_identities(module, unres)) {
4548 goto error;
4549 }
Pavol Vican05810b62016-11-23 14:07:22 +01004550 erase_nodes = 0;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004551 if (yang_check_nodes(module, NULL, node, 0, unres)) {
Pavol Vican05810b62016-11-23 14:07:22 +01004552 goto error;
4553 }
Pavol Vican7a7916f2016-11-21 23:38:30 +01004554
PavolVican75af21d2016-12-29 20:04:07 +01004555 /* check deviation */
4556 for (i = 0; i < dev_size; ++i) {
4557 module->deviation_size++;
4558 if (yang_check_deviation(module, unres, &module->deviation[i])) {
4559 goto error;
4560 }
4561 }
4562
Pavol Vican3ad50f82016-12-04 15:00:36 +01004563 /* check augments */
4564 for (i = 0; i < aug_size; ++i) {
4565 module->augment_size++;
Radek Krejci7212e0a2017-03-08 15:58:22 +01004566 if (yang_check_augment(module, &module->augment[i], 0, unres)) {
Pavol Vican3ad50f82016-12-04 15:00:36 +01004567 goto error;
4568 }
4569 if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
4570 goto error;
4571 }
4572 }
4573
Pavol Vican7313fc02016-11-14 01:10:31 +01004574 return EXIT_SUCCESS;
4575error:
Pavol Vican36e27272016-11-22 15:47:28 +01004576 if (erase_identities) {
4577 yang_free_ident_base(module->ident, 0, module->ident_size);
4578 }
Pavol Vican05810b62016-11-23 14:07:22 +01004579 if (erase_nodes) {
4580 yang_free_nodes(module->ctx, node);
4581 }
Pavol Vican3ad50f82016-12-04 15:00:36 +01004582 for (i = module->augment_size; i < aug_size; ++i) {
4583 yang_free_augment(module->ctx, &module->augment[i]);
4584 }
PavolVican75af21d2016-12-29 20:04:07 +01004585 for (i = module->deviation_size; i < dev_size; ++i) {
4586 yang_free_deviate(module->ctx, &module->deviation[i], 0);
4587 free(module->deviation[i].deviate);
4588 }
Pavol Vican7313fc02016-11-14 01:10:31 +01004589 return EXIT_FAILURE;
4590}
PavolVican22e88682017-02-14 22:38:18 +01004591
4592int
Michal Vasko3e3228d2017-02-24 14:55:32 +01004593yang_read_extcomplex_str(struct lys_module *module, struct lys_ext_instance_complex *ext, const char *arg_name,
PavolVican22e88682017-02-14 22:38:18 +01004594 const char *parent_name, char *value, int parent_stmt, LY_STMT stmt)
4595{
4596 int c;
4597 const char **str, ***p = NULL;
4598 void *reallocated;
4599 struct lyext_substmt *info;
4600
4601 c = 0;
4602 if (stmt == LY_STMT_PREFIX && parent_stmt == LY_STMT_BELONGSTO) {
PavolVican4b80d042017-02-23 14:30:27 +01004603 /* str contains no NULL value */
PavolVican22e88682017-02-14 22:38:18 +01004604 str = lys_ext_complex_get_substmt(LY_STMT_BELONGSTO, ext, &info);
4605 if (info->cardinality < LY_STMT_CARD_SOME) {
4606 str++;
4607 } else {
4608 /* get the index in the array to add new item */
4609 p = (const char ***)str;
4610 for (c = 0; p[0][c + 1]; c++);
4611 str = p[1];
4612 }
4613 str[c] = lydict_insert_zc(module->ctx, value);
4614 } else {
4615 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4616 if (!str) {
4617 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004618 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004619 }
4620 if (info->cardinality < LY_STMT_CARD_SOME && *str) {
4621 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, arg_name, parent_name);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004622 goto error;
PavolVican22e88682017-02-14 22:38:18 +01004623 }
4624
4625 if (info->cardinality >= LY_STMT_CARD_SOME) {
4626 /* there can be multiple instances, str is actually const char *** */
4627 p = (const char ***)str;
4628 if (!p[0]) {
4629 /* allocate initial array */
PavolVican50809742017-02-18 21:22:54 +01004630 p[0] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004631 LY_CHECK_ERR_GOTO(!p[0], LOGMEM, error);
PavolVican22e88682017-02-14 22:38:18 +01004632 if (stmt == LY_STMT_BELONGSTO) {
4633 /* allocate another array for the belongs-to's prefixes */
4634 p[1] = calloc(2, sizeof(const char *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004635 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004636 } else if (stmt == LY_STMT_ARGUMENT) {
4637 /* allocate another array for the yin element */
PavolVican4b80d042017-02-23 14:30:27 +01004638 ((uint8_t **)p)[1] = calloc(2, sizeof(uint8_t));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004639 LY_CHECK_ERR_GOTO(!p[1], LOGMEM, error);
PavolVican50809742017-02-18 21:22:54 +01004640 /* default value of yin element */
4641 ((uint8_t *)p[1])[0] = 2;
PavolVican22e88682017-02-14 22:38:18 +01004642 }
4643 } else {
4644 /* get the index in the array to add new item */
4645 for (c = 0; p[0][c]; c++);
4646 }
4647 str = p[0];
4648 }
4649
4650 str[c] = lydict_insert_zc(module->ctx, value);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004651 value = NULL;
PavolVican22e88682017-02-14 22:38:18 +01004652
PavolVican50809742017-02-18 21:22:54 +01004653 if (c) {
PavolVican22e88682017-02-14 22:38:18 +01004654 /* enlarge the array(s) */
4655 reallocated = realloc(p[0], (c + 2) * sizeof(const char *));
4656 if (!reallocated) {
4657 LOGMEM;
4658 lydict_remove(module->ctx, p[0][c]);
4659 p[0][c] = NULL;
4660 return EXIT_FAILURE;
4661 }
4662 p[0] = reallocated;
4663 p[0][c + 1] = NULL;
4664
4665 if (stmt == LY_STMT_BELONGSTO) {
4666 /* enlarge the second belongs-to's array with prefixes */
4667 reallocated = realloc(p[1], (c + 2) * sizeof(const char *));
4668 if (!reallocated) {
4669 LOGMEM;
4670 lydict_remove(module->ctx, p[1][c]);
4671 p[1][c] = NULL;
4672 return EXIT_FAILURE;
4673 }
4674 p[1] = reallocated;
4675 p[1][c + 1] = NULL;
PavolVican50809742017-02-18 21:22:54 +01004676 } else if (stmt == LY_STMT_ARGUMENT) {
4677 /* enlarge the second argument's array with yin element */
4678 reallocated = realloc(p[1], (c + 2) * sizeof(uint8_t));
4679 if (!reallocated) {
4680 LOGMEM;
4681 ((uint8_t *)p[1])[c] = 0;
4682 return EXIT_FAILURE;
4683 }
4684 p[1] = reallocated;
4685 ((uint8_t *)p[1])[c + 1] = 0;
PavolVican22e88682017-02-14 22:38:18 +01004686 }
4687 }
4688 }
4689
4690 return EXIT_SUCCESS;
Radek Krejcia8d111f2017-05-31 13:57:37 +02004691
4692error:
4693 free(value);
4694 return EXIT_FAILURE;
PavolVican22e88682017-02-14 22:38:18 +01004695}
PavolVican5334c892017-02-15 16:29:09 +01004696
4697static int
4698yang_fill_ext_substm_index(struct lys_ext_instance_complex *ext, LY_STMT stmt, enum yytokentype keyword)
4699{
4700 int c = 0, decrement = 0;
4701 const char **str, ***p = NULL;
4702 struct lyext_substmt *info;
4703
4704
4705 if (keyword == BELONGS_TO_KEYWORD || stmt == LY_STMT_BELONGSTO) {
4706 stmt = LY_STMT_BELONGSTO;
4707 decrement = -1;
PavolVican50809742017-02-18 21:22:54 +01004708 } else if (keyword == ARGUMENT_KEYWORD || stmt == LY_STMT_ARGUMENT) {
4709 stmt = LY_STMT_ARGUMENT;
4710 decrement = -1;
PavolVican5334c892017-02-15 16:29:09 +01004711 }
4712
4713 str = lys_ext_complex_get_substmt(stmt, ext, &info);
4714 if (!str || info->cardinality < LY_STMT_CARD_SOME || !((const char ***)str)[0]) {
4715 return 0;
4716 } else {
4717 p = (const char ***)str;
4718 /* get the index in the array */
4719 for (c = 0; p[0][c]; c++);
4720 return c + decrement;
4721 }
4722}
PavolVicana0fdbf32017-02-15 17:59:02 +01004723
4724void **
PavolVicanfe83b152017-02-19 03:19:29 +01004725yang_getplace_for_extcomplex_struct(struct lys_ext_instance_complex *ext, int *index,
4726 char *parent_name, char *node_name, LY_STMT stmt)
PavolVicana0fdbf32017-02-15 17:59:02 +01004727{
4728 int c;
4729 void **data, ***p = NULL;
4730 void *reallocated;
4731 struct lyext_substmt *info;
4732
4733 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4734 if (!data) {
4735 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4736 return NULL;
4737 }
4738 if (info->cardinality < LY_STMT_CARD_SOME && *data) {
4739 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4740 return NULL;
4741 }
4742
4743 c = 0;
4744 if (info->cardinality >= LY_STMT_CARD_SOME) {
4745 /* there can be multiple instances, so instead of pointer to array,
4746 * we have in data pointer to pointer to array */
4747 p = (void ***)data;
4748 data = *p;
4749 if (!data) {
4750 /* allocate initial array */
PavolVicaneef1d912017-02-19 00:19:15 +01004751 *p = data = calloc(2, sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004752 LY_CHECK_ERR_RETURN(!data, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004753 } else {
4754 for (c = 0; *data; data++, c++);
4755 }
4756 }
4757
PavolVicaneef1d912017-02-19 00:19:15 +01004758 if (c) {
PavolVicana0fdbf32017-02-15 17:59:02 +01004759 /* enlarge the array */
4760 reallocated = realloc(*p, (c + 2) * sizeof(void *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004761 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, NULL);
PavolVicana0fdbf32017-02-15 17:59:02 +01004762 *p = reallocated;
4763 data = *p;
4764 data[c + 1] = NULL;
4765 }
4766
PavolVicanfe83b152017-02-19 03:19:29 +01004767 if (index) {
4768 *index = c;
4769 return data;
4770 } else {
4771 return &data[c];
4772 }
PavolVicana0fdbf32017-02-15 17:59:02 +01004773}
PavolVicanff0f7f42017-02-16 11:35:42 +01004774
4775int
4776yang_fill_extcomplex_flags(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4777 LY_STMT stmt, uint16_t value, uint16_t mask)
4778{
4779 uint16_t *data;
4780 struct lyext_substmt *info;
4781
4782 data = lys_ext_complex_get_substmt(stmt, ext, &info);
4783 if (!data) {
4784 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4785 return EXIT_FAILURE;
4786 }
4787 if (info->cardinality < LY_STMT_CARD_SOME && (*data & mask)) {
4788 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4789 return EXIT_FAILURE;
4790 }
4791
4792 *data |= value;
4793 return EXIT_SUCCESS;
4794}
PavolVican8e8dfd12017-02-16 13:51:41 +01004795
4796int
PavolVican6a852a62017-02-16 15:36:01 +01004797yang_fill_extcomplex_uint8(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4798 LY_STMT stmt, uint8_t value)
PavolVican8e8dfd12017-02-16 13:51:41 +01004799{
PavolVican6a852a62017-02-16 15:36:01 +01004800 uint8_t *val, **pp = NULL, *reallocated;
PavolVican8e8dfd12017-02-16 13:51:41 +01004801 struct lyext_substmt *info;
PavolVican6a852a62017-02-16 15:36:01 +01004802 int i = 0;
PavolVican8e8dfd12017-02-16 13:51:41 +01004803
4804 val = lys_ext_complex_get_substmt(stmt, ext, &info);
4805 if (!val) {
4806 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4807 return EXIT_FAILURE;
4808 }
PavolVican6a852a62017-02-16 15:36:01 +01004809 if (stmt == LY_STMT_DIGITS) {
4810 if (info->cardinality < LY_STMT_CARD_SOME && *val) {
4811 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4812 return EXIT_FAILURE;
4813 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004814
PavolVican6a852a62017-02-16 15:36:01 +01004815 if (info->cardinality >= LY_STMT_CARD_SOME) {
4816 /* there can be multiple instances */
4817 pp = (uint8_t**)val;
4818 if (!(*pp)) {
4819 *pp = calloc(2, sizeof(uint8_t)); /* allocate initial array */
Radek Krejcia8d111f2017-05-31 13:57:37 +02004820 LY_CHECK_ERR_RETURN(!*pp, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004821 } else {
4822 for (i = 0; (*pp)[i]; i++);
4823 }
4824 val = &(*pp)[i];
4825 }
4826
4827 /* stored value */
4828 *val = value;
4829
4830 if (i) {
4831 /* enlarge the array */
4832 reallocated = realloc(*pp, (i + 2) * sizeof *val);
Radek Krejcia8d111f2017-05-31 13:57:37 +02004833 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVican6a852a62017-02-16 15:36:01 +01004834 *pp = reallocated;
4835 (*pp)[i + 1] = 0;
4836 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004837 } else {
PavolVican6a852a62017-02-16 15:36:01 +01004838 if (*val) {
4839 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4840 return EXIT_FAILURE;
4841 }
4842
4843 if (stmt == LY_STMT_REQINSTANCE) {
4844 *val = (value == 1) ? 1 : 2;
4845 } else if (stmt == LY_STMT_MODIFIER) {
4846 *val = 1;
4847 } else {
4848 LOGINT;
4849 return EXIT_FAILURE;
4850 }
PavolVican8e8dfd12017-02-16 13:51:41 +01004851 }
4852
4853 return EXIT_SUCCESS;
4854}
PavolVican3f47b292017-02-16 20:38:16 +01004855
PavolVicanf3091bf2017-02-19 18:27:01 +01004856int
4857yang_extcomplex_node(struct lys_ext_instance_complex *ext, char *parent_name, char *node_name,
4858 struct lys_node *node, LY_STMT stmt)
4859{
4860 struct lyext_substmt *info;
4861 struct lys_node **snode, *siter;
4862
4863 snode = lys_ext_complex_get_substmt(stmt, ext, &info);
4864 if (!snode) {
4865 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, node_name, parent_name);
4866 return EXIT_FAILURE;
4867 }
4868 if (info->cardinality < LY_STMT_CARD_SOME) {
4869 LY_TREE_FOR(node, siter) {
4870 if (stmt == lys_snode2stmt(siter->nodetype)) {
4871 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, node_name, parent_name);
4872 return EXIT_FAILURE;
4873 }
4874 }
4875 }
4876
4877 return EXIT_SUCCESS;
4878}
PavolVicandb0e8172017-02-20 00:46:09 +01004879
4880int
4881yang_fill_extcomplex_module(struct ly_ctx *ctx, struct lys_ext_instance_complex *ext,
4882 char *parent_name, char **values, int implemented)
4883{
4884 int c, i;
4885 struct lys_module **modules, ***p, *reallocated, **pp;
4886 struct lyext_substmt *info;
4887
4888 if (!values) {
4889 return EXIT_SUCCESS;
4890 }
4891 pp = modules = lys_ext_complex_get_substmt(LY_STMT_MODULE, ext, &info);
4892 if (!modules) {
4893 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "module", parent_name);
4894 return EXIT_FAILURE;
4895 }
4896
4897 for (i = 0; values[i]; ++i) {
4898 c = 0;
4899 if (info->cardinality < LY_STMT_CARD_SOME && *modules) {
4900 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "module", parent_name);
4901 return EXIT_FAILURE;
4902 }
4903 if (info->cardinality >= LY_STMT_CARD_SOME) {
4904 /* there can be multiple instances, so instead of pointer to array,
4905 * we have in modules pointer to pointer to array */
4906 p = (struct lys_module ***)pp;
4907 modules = *p;
4908 if (!modules) {
4909 /* allocate initial array */
4910 *p = modules = calloc(2, sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004911 LY_CHECK_ERR_RETURN(!*p, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01004912 } else {
4913 for (c = 0; *modules; modules++, c++);
4914 }
4915 }
4916
4917 if (c) {
4918 /* enlarge the array */
4919 reallocated = realloc(*p, (c + 2) * sizeof(struct lys_module *));
Radek Krejcia8d111f2017-05-31 13:57:37 +02004920 LY_CHECK_ERR_RETURN(!reallocated, LOGMEM, EXIT_FAILURE);
PavolVicandb0e8172017-02-20 00:46:09 +01004921 *p = (struct lys_module **)reallocated;
4922 modules = *p;
4923 modules[c + 1] = NULL;
4924 }
4925
4926 modules[c] = yang_read_module(ctx, values[i], 0, NULL, implemented);
4927 if (!modules[c]) {
4928 return EXIT_FAILURE;
4929 }
4930 }
4931
4932 return EXIT_SUCCESS;
4933}