blob: fb5a9a8d65eb0b1d2a444c118653531bf3c118d3 [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 Vican021488a2016-01-25 23:56:12 +010016#include "parser_yang.h"
Pavol Vican8e7110b2016-03-22 17:00:26 +010017#include "parser_yang_lex.h"
Pavol Vican6eb14e82016-02-03 12:27:13 +010018#include "parser.h"
Pavol Vicanf37eeaa2016-02-09 20:54:06 +010019#include "xpath.h"
Pavol Vican021488a2016-01-25 23:56:12 +010020
Michal Vaskofe7e5a72016-05-02 14:49:23 +020021static int
Pavol Vican0adf01d2016-03-22 12:29:33 +010022yang_check_string(struct lys_module *module, const char **target, char *what, char *where, char *value)
Pavol Vican2a064652016-02-02 22:54:34 +010023{
Pavol Vicanbf805472016-01-26 14:24:56 +010024 if (*target) {
Pavol Vican0adf01d2016-03-22 12:29:33 +010025 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, what, where);
Pavol Vicanbf805472016-01-26 14:24:56 +010026 free(value);
27 return 1;
28 } else {
Pavol Vican2a064652016-02-02 22:54:34 +010029 *target = lydict_insert_zc(module->ctx, value);
Pavol Vicanbf805472016-01-26 14:24:56 +010030 return 0;
31 }
32}
33
Michal Vaskofe7e5a72016-05-02 14:49:23 +020034int
Pavol Vican5f0316a2016-04-05 21:21:11 +020035yang_read_common(struct lys_module *module, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010036{
Pavol Vican6eb14e82016-02-03 12:27:13 +010037 int ret = 0;
Pavol Vican021488a2016-01-25 23:56:12 +010038
39 switch (type) {
Pavol Vican2a064652016-02-02 22:54:34 +010040 case MODULE_KEYWORD:
41 module->name = lydict_insert_zc(module->ctx, value);
42 break;
43 case NAMESPACE_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010044 ret = yang_check_string(module, &module->ns, "namespace", "module", value);
Pavol Vican2a064652016-02-02 22:54:34 +010045 break;
Pavol Vican1ca072c2016-02-03 13:03:56 +010046 case ORGANIZATION_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010047 ret = yang_check_string(module, &module->org, "organization", "module", value);
Pavol Vican1ca072c2016-02-03 13:03:56 +010048 break;
49 case CONTACT_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010050 ret = yang_check_string(module, &module->contact, "contact", "module", value);
Pavol Vican1ca072c2016-02-03 13:03:56 +010051 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020052 default:
53 free(value);
54 LOGINT;
55 ret = EXIT_FAILURE;
56 break;
Pavol Vican2a064652016-02-02 22:54:34 +010057 }
58
Pavol Vican021488a2016-01-25 23:56:12 +010059 return ret;
Pavol Vicanbf805472016-01-26 14:24:56 +010060}
61
Michal Vaskofe7e5a72016-05-02 14:49:23 +020062int
Pavol Vican5f0316a2016-04-05 21:21:11 +020063yang_read_prefix(struct lys_module *module, void *save, char *value, enum yytokentype type)
Pavol Vican2a064652016-02-02 22:54:34 +010064{
Pavol Vican6eb14e82016-02-03 12:27:13 +010065 int ret = 0;
Pavol Vicanbf805472016-01-26 14:24:56 +010066
Pavol Vican0adf01d2016-03-22 12:29:33 +010067 if (lyp_check_identifier(value, LY_IDENT_PREFIX, module, NULL)) {
Pavol Vican6eb14e82016-02-03 12:27:13 +010068 free(value);
69 return EXIT_FAILURE;
70 }
Pavol Vicanbf805472016-01-26 14:24:56 +010071 switch (type){
Pavol Vican2a064652016-02-02 22:54:34 +010072 case MODULE_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +010073 ret = yang_check_string(module, &module->prefix, "prefix", "module", value);
Pavol Vican2a064652016-02-02 22:54:34 +010074 break;
Pavol Vican6eb14e82016-02-03 12:27:13 +010075 case IMPORT_KEYWORD:
76 ((struct lys_import *)save)->prefix = lydict_insert_zc(module->ctx, value);
77 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +020078 default:
79 free(value);
80 LOGINT;
81 ret = EXIT_FAILURE;
82 break;
Pavol Vican2a064652016-02-02 22:54:34 +010083 }
Pavol Vican6eb14e82016-02-03 12:27:13 +010084
Pavol Vicanbf805472016-01-26 14:24:56 +010085 return ret;
86}
Pavol Vican6eb14e82016-02-03 12:27:13 +010087
Pavol Vican6eb14e82016-02-03 12:27:13 +010088int
Pavol Vican0adf01d2016-03-22 12:29:33 +010089yang_fill_import(struct lys_module *module, struct lys_import *imp, char *value)
Pavol Vican6eb14e82016-02-03 12:27:13 +010090{
Pavol Vican0da132e2016-03-21 12:03:03 +010091 const char *exp;
Radek Krejci4dcd3392016-06-22 10:28:40 +020092 int rc;
Pavol Vican6eb14e82016-02-03 12:27:13 +010093
Pavol Vican0da132e2016-03-21 12:03:03 +010094 exp = lydict_insert_zc(module->ctx, value);
Pavol Vican0adf01d2016-03-22 12:29:33 +010095 rc = lyp_check_import(module, exp, imp);
Pavol Vican0da132e2016-03-21 12:03:03 +010096 lydict_remove(module->ctx, exp);
Radek Krejci4dcd3392016-06-22 10:28:40 +020097 module->imp_size++;
Pavol Vican0da132e2016-03-21 12:03:03 +010098 if (rc) {
Radek Krejci4dcd3392016-06-22 10:28:40 +020099 return EXIT_FAILURE;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100100 }
Pavol Vican6eb14e82016-02-03 12:27:13 +0100101
Pavol Vican6eb14e82016-02-03 12:27:13 +0100102 return EXIT_SUCCESS;
Pavol Vican6eb14e82016-02-03 12:27:13 +0100103}
Pavol Vican1ca072c2016-02-03 13:03:56 +0100104
105int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100106yang_read_description(struct lys_module *module, void *node, char *value, char *where)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100107{
108 int ret;
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100109 char *dsc = "description";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100110
111 if (!node) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100112 ret = yang_check_string(module, &module->dsc, dsc, "module", value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100113 } else {
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100114 if (!strcmp("revision", where)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100115 ret = yang_check_string(module, &((struct lys_revision *)node)->dsc, dsc, where, value);
Pavol Vican9bcd7c62016-03-17 19:36:35 +0100116 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100117 ret = yang_check_string(module, &((struct lys_node *)node)->dsc, dsc, where, value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100118 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100119 }
120 return ret;
121}
122
123int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100124yang_read_reference(struct lys_module *module, void *node, char *value, char *where)
Pavol Vican1ca072c2016-02-03 13:03:56 +0100125{
126 int ret;
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100127 char *ref = "reference";
Pavol Vican1ca072c2016-02-03 13:03:56 +0100128
129 if (!node) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100130 ret = yang_check_string(module, &module->ref, "reference", "module", value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100131 } else {
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100132 if (!strcmp("revision", where)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100133 ret = yang_check_string(module, &((struct lys_revision *)node)->ref, ref, where, value);
Pavol Vicanf5fe9662016-03-17 20:00:16 +0100134 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100135 ret = yang_check_string(module, &((struct lys_node *)node)->ref, ref, where, value);
Pavol Vicanbedff692016-02-03 14:29:17 +0100136 }
Pavol Vican1ca072c2016-02-03 13:03:56 +0100137 }
138 return ret;
139}
Pavol Vicanbedff692016-02-03 14:29:17 +0100140
141void *
142yang_read_revision(struct lys_module *module, char *value)
143{
144 struct lys_revision *retval;
145
Pavol Vican1eeb1992016-02-09 11:10:45 +0100146 retval = &module->rev[module->rev_size];
Pavol Vicanbedff692016-02-03 14:29:17 +0100147
148 /* first member of array is last revision */
Pavol Vican1eeb1992016-02-09 11:10:45 +0100149 if (module->rev_size && strcmp(module->rev[0].date, value) < 0) {
Pavol Vicanbedff692016-02-03 14:29:17 +0100150 memcpy(retval->date, module->rev[0].date, LY_REV_SIZE);
151 memcpy(module->rev[0].date, value, LY_REV_SIZE);
152 retval->dsc = module->rev[0].dsc;
153 retval->ref = module->rev[0].ref;
154 retval = module->rev;
155 retval->dsc = NULL;
156 retval->ref = NULL;
157 } else {
158 memcpy(retval->date, value, LY_REV_SIZE);
159 }
Pavol Vican1eeb1992016-02-09 11:10:45 +0100160 module->rev_size++;
Pavol Vicanbedff692016-02-03 14:29:17 +0100161 free(value);
162 return retval;
163}
Pavol Vican1eeb1992016-02-09 11:10:45 +0100164
165int
Pavol Vicana1827962016-02-29 15:39:42 +0100166yang_add_elem(struct lys_node_array **node, uint32_t *size)
Pavol Vican1eeb1992016-02-09 11:10:45 +0100167{
Pavol Vican45ccc592016-03-09 18:53:48 +0100168 if (!(*size % LY_ARRAY_SIZE)) {
Pavol Vican1eeb1992016-02-09 11:10:45 +0100169 if (!(*node = ly_realloc(*node, (*size + LY_ARRAY_SIZE) * sizeof **node))) {
170 LOGMEM;
171 return EXIT_FAILURE;
172 } else {
Pavol Vican45ccc592016-03-09 18:53:48 +0100173 memset(*node + *size, 0, LY_ARRAY_SIZE * sizeof **node);
Pavol Vican1eeb1992016-02-09 11:10:45 +0100174 }
175 }
176 (*size)++;
177 return EXIT_SUCCESS;
178}
Pavol Vicane1354e92016-02-09 14:02:09 +0100179
180void *
Pavol Vican0adf01d2016-03-22 12:29:33 +0100181yang_read_feature(struct lys_module *module, char *value)
Pavol Vicane1354e92016-02-09 14:02:09 +0100182{
183 struct lys_feature *retval;
184
185 /* check uniqueness of feature's names */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100186 if (lyp_check_identifier(value, LY_IDENT_FEATURE, module, NULL)) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100187 goto error;
188 }
189 retval = &module->features[module->features_size];
190 retval->name = lydict_insert_zc(module->ctx, value);
191 retval->module = module;
192 module->features_size++;
193 return retval;
194
195error:
196 free(value);
197 return NULL;
198}
199
200int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200201yang_read_if_feature(struct lys_module *module, void *ptr, char *value, struct unres_schema *unres, enum yytokentype type)
Pavol Vicane1354e92016-02-09 14:02:09 +0100202{
203 const char *exp;
204 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100205 struct lys_feature *f;
206 struct lys_node *n;
Pavol Vicane1354e92016-02-09 14:02:09 +0100207
Pavol Vican0adf01d2016-03-22 12:29:33 +0100208 if (!(exp = transform_schema2json(module, value))) {
Pavol Vicane1354e92016-02-09 14:02:09 +0100209 free(value);
210 return EXIT_FAILURE;
211 }
212 free(value);
213
214 /* hack - store pointer to the parent node for later status check */
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100215 if (type == FEATURE_KEYWORD) {
216 f = (struct lys_feature *) ptr;
217 f->features[f->features_size] = f;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100218 ret = unres_schema_add_str(module, unres, &f->features[f->features_size], UNRES_IFFEAT, exp);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100219 f->features_size++;
220 } else {
221 n = (struct lys_node *) ptr;
222 n->features[n->features_size] = (struct lys_feature *) n;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100223 ret = unres_schema_add_str(module, unres, &n->features[n->features_size], UNRES_IFFEAT, exp);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100224 n->features_size++;
225 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100226
227 lydict_remove(module->ctx, exp);
228 if (ret == -1) {
229
230 return EXIT_FAILURE;
231 }
232 return EXIT_SUCCESS;
233}
234
Pavol Vican4fb66c92016-03-17 10:32:27 +0100235int
Radek Krejci4372b4e2016-04-14 17:42:16 +0200236yang_check_flags(uint16_t *flags, uint16_t mask, char *what, char *where, uint16_t value, int shortint)
Pavol Vicane1354e92016-02-09 14:02:09 +0100237{
238 if (*flags & mask) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100239 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, what, where);
Pavol Vicane1354e92016-02-09 14:02:09 +0100240 return EXIT_FAILURE;
241 } else {
Radek Krejci4372b4e2016-04-14 17:42:16 +0200242 if (shortint) {
243 *((uint8_t *)flags) |= (uint8_t)value;
244 } else {
245 *flags |= value;
246 }
Pavol Vicane1354e92016-02-09 14:02:09 +0100247 return EXIT_SUCCESS;
248 }
249}
250
Pavol Vicanbbdef532016-02-09 14:52:12 +0100251void *
252yang_read_identity(struct lys_module *module, char *value)
253{
254 struct lys_ident *ret;
255
256 ret = &module->ident[module->ident_size];
257 ret->name = lydict_insert_zc(module->ctx, value);
258 ret->module = module;
259 module->ident_size++;
260 return ret;
261}
262
263int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100264yang_read_base(struct lys_module *module, struct lys_ident *ident, char *value, struct unres_schema *unres)
Pavol Vicanbbdef532016-02-09 14:52:12 +0100265{
266 const char *exp;
267
Pavol Vicane2368982016-03-19 14:37:56 +0100268 if (!value) {
269 /* base statement not found */
270 return EXIT_SUCCESS;
Pavol Vicanbbdef532016-02-09 14:52:12 +0100271 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100272 exp = transform_schema2json(module, value);
Pavol Vicanbbdef532016-02-09 14:52:12 +0100273 free(value);
274 if (!exp) {
275 return EXIT_FAILURE;
276 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100277 if (unres_schema_add_str(module, unres, ident, UNRES_IDENT, exp) == -1) {
Pavol Vicanbbdef532016-02-09 14:52:12 +0100278 lydict_remove(module->ctx, exp);
279 return EXIT_FAILURE;
280 }
Pavol Vican44dde2c2016-02-10 11:18:14 +0100281
Pavol Vicanbbdef532016-02-09 14:52:12 +0100282 lydict_remove(module->ctx, exp);
283 return EXIT_SUCCESS;
284}
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100285
286void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200287yang_read_must(struct lys_module *module, struct lys_node *node, char *value, enum yytokentype type)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100288{
289 struct lys_restr *retval;
290
291 switch (type) {
Pavol Vican8c82fa82016-02-10 13:13:24 +0100292 case CONTAINER_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100293 retval = &((struct lys_node_container *)node)->must[((struct lys_node_container *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100294 break;
295 case ANYXML_KEYWORD:
Pavol Vican096c6db2016-02-11 15:08:10 +0100296 retval = &((struct lys_node_anyxml *)node)->must[((struct lys_node_anyxml *)node)->must_size++];
297 break;
298 case LEAF_KEYWORD:
299 retval = &((struct lys_node_leaf *)node)->must[((struct lys_node_leaf *)node)->must_size++];
Pavol Vican8c82fa82016-02-10 13:13:24 +0100300 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100301 case LEAF_LIST_KEYWORD:
302 retval = &((struct lys_node_leaflist *)node)->must[((struct lys_node_leaflist *)node)->must_size++];
303 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100304 case LIST_KEYWORD:
305 retval = &((struct lys_node_list *)node)->must[((struct lys_node_list *)node)->must_size++];
306 break;
Pavol Vican1003ead2016-03-02 12:24:52 +0100307 case REFINE_KEYWORD:
308 retval = &((struct lys_refine *)node)->must[((struct lys_refine *)node)->must_size++];
309 break;
Pavol Vican85f12022016-03-05 16:30:35 +0100310 case ADD_KEYWORD:
311 retval = &(*((struct type_deviation *)node)->trg_must)[(*((struct type_deviation *)node)->trg_must_size)++];
312 memset(retval, 0, sizeof *retval);
313 break;
Pavol Vicanc1f5a502016-03-06 16:51:26 +0100314 case DELETE_KEYWORD:
315 retval = &((struct type_deviation *)node)->deviate->must[((struct type_deviation *)node)->deviate->must_size++];
316 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200317 default:
318 goto error;
319 break;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100320 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100321 retval->expr = transform_schema2json(module, value);
322 if (!retval->expr || lyxp_syntax_check(retval->expr)) {
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100323 goto error;
324 }
325 free(value);
326 return retval;
327
328error:
329 free(value);
330 return NULL;
331}
332
333int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100334yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message)
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100335{
336 int ret;
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100337
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100338 if (message==ERROR_APP_TAG_KEYWORD) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100339 ret = yang_check_string(module, &save->eapptag, "error_app_tag", what, value);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100340 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100341 ret = yang_check_string(module, &save->emsg, "error_app_tag", what, value);
Pavol Vicanf37eeaa2016-02-09 20:54:06 +0100342 }
343 return ret;
344}
Pavol Vicanb5687112016-02-09 22:35:59 +0100345
346int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100347yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value)
Pavol Vicanb5687112016-02-09 22:35:59 +0100348{
349 if (cont->presence) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100350 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, cont, "presence", "container");
Pavol Vicanb5687112016-02-09 22:35:59 +0100351 free(value);
352 return EXIT_FAILURE;
353 } else {
354 cont->presence = lydict_insert_zc(module->ctx, value);
355 return EXIT_SUCCESS;
356 }
357}
358
Pavol Vican235dbd42016-02-10 10:34:19 +0100359void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200360yang_read_when(struct lys_module *module, struct lys_node *node, enum yytokentype type, char *value)
Pavol Vican235dbd42016-02-10 10:34:19 +0100361{
362 struct lys_when *retval;
363
364 retval = calloc(1, sizeof *retval);
365 if (!retval) {
366 LOGMEM;
367 free(value);
368 return NULL;
369 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100370 retval->cond = transform_schema2json(module, value);
371 if (!retval->cond || lyxp_syntax_check(retval->cond)) {
Pavol Vican235dbd42016-02-10 10:34:19 +0100372 goto error;
373 }
374 switch (type) {
375 case CONTAINER_KEYWORD:
376 if (((struct lys_node_container *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100377 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "container");
Pavol Vican235dbd42016-02-10 10:34:19 +0100378 goto error;
379 }
380 ((struct lys_node_container *)node)->when = retval;
381 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100382 case ANYXML_KEYWORD:
Pavol Vican8c82fa82016-02-10 13:13:24 +0100383 if (((struct lys_node_anyxml *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100384 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "anyxml");
Pavol Vican8c82fa82016-02-10 13:13:24 +0100385 goto error;
386 }
387 ((struct lys_node_anyxml *)node)->when = retval;
388 break;
Pavol Vican1f06ba82016-02-10 17:39:50 +0100389 case CHOICE_KEYWORD:
390 if (((struct lys_node_choice *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100391 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "choice");
Pavol Vican1f06ba82016-02-10 17:39:50 +0100392 goto error;
393 }
394 ((struct lys_node_choice *)node)->when = retval;
395 break;
Pavol Vicanbd098132016-02-11 10:56:49 +0100396 case CASE_KEYWORD:
397 if (((struct lys_node_case *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100398 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "case");
Pavol Vicanbd098132016-02-11 10:56:49 +0100399 goto error;
400 }
401 ((struct lys_node_case *)node)->when = retval;
402 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100403 case LEAF_KEYWORD:
404 if (((struct lys_node_leaf *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100405 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaf");
Pavol Vican096c6db2016-02-11 15:08:10 +0100406 goto error;
407 }
408 ((struct lys_node_leaf *)node)->when = retval;
409 break;
Pavol Vican339d4ad2016-02-12 12:49:22 +0100410 case LEAF_LIST_KEYWORD:
411 if (((struct lys_node_leaflist *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100412 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "leaflist");
Pavol Vican339d4ad2016-02-12 12:49:22 +0100413 goto error;
414 }
415 ((struct lys_node_leaflist *)node)->when = retval;
416 break;
Pavol Vican5de33492016-02-22 14:03:24 +0100417 case LIST_KEYWORD:
418 if (((struct lys_node_list *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100419 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "list");
Pavol Vican5de33492016-02-22 14:03:24 +0100420 goto error;
421 }
422 ((struct lys_node_list *)node)->when = retval;
423 break;
Pavol Vican14b18562016-03-01 16:04:29 +0100424 case USES_KEYWORD:
425 if (((struct lys_node_uses *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100426 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "uses");
Pavol Vican14b18562016-03-01 16:04:29 +0100427 goto error;
428 }
429 ((struct lys_node_uses *)node)->when = retval;
430 break;
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100431 case AUGMENT_KEYWORD:
432 if (((struct lys_node_augment *)node)->when) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100433 LOGVAL(LYE_TOOMANY, LY_VLOG_LYS, node, "when", "augment");
Pavol Vican92fa0dc2016-03-02 14:20:39 +0100434 goto error;
435 }
436 ((struct lys_node_augment *)node)->when = retval;
437 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200438 default:
439 goto error;
440 break;
Pavol Vican235dbd42016-02-10 10:34:19 +0100441 }
442 free(value);
443 return retval;
444
445error:
446 free(value);
447 lys_when_free(module->ctx, retval);
448 return NULL;
449}
Pavol Vican8c82fa82016-02-10 13:13:24 +0100450
451void *
Pavol Vican7cadfe72016-02-11 12:33:34 +0100452yang_read_node(struct lys_module *module, struct lys_node *parent, char *value, int nodetype, int sizeof_struct)
Pavol Vican8c82fa82016-02-10 13:13:24 +0100453{
Pavol Vican7cadfe72016-02-11 12:33:34 +0100454 struct lys_node *node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100455
Pavol Vican7cadfe72016-02-11 12:33:34 +0100456 node = calloc(1, sizeof_struct);
457 if (!node) {
Pavol Vicand1dbfda2016-03-21 10:03:58 +0100458 free(value);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100459 LOGMEM;
460 return NULL;
461 }
Pavol Vican531a9132016-03-03 10:10:09 +0100462 if (value) {
463 node->name = lydict_insert_zc(module->ctx, value);
464 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100465 node->module = module;
Pavol Vican7cadfe72016-02-11 12:33:34 +0100466 node->nodetype = nodetype;
467 node->prev = node;
468
469 /* insert the node into the schema tree */
470 if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
Pavol Vican531a9132016-03-03 10:10:09 +0100471 if (value) {
472 lydict_remove(module->ctx, node->name);
473 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100474 free(node);
Pavol Vican8c82fa82016-02-10 13:13:24 +0100475 return NULL;
476 }
Pavol Vican7cadfe72016-02-11 12:33:34 +0100477 return node;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100478}
479
480int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200481yang_read_default(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100482{
483 int ret;
484
485 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100486 case LEAF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100487 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->dflt, "default", "leaf", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100488 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100489 case TYPEDEF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100490 ret = yang_check_string(module, &((struct lys_tpdf *) node)->dflt, "default", "typedef", value);
Pavol Vican0df02b02016-03-01 10:28:50 +0100491 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200492 default:
493 free(value);
494 LOGINT;
495 ret = EXIT_FAILURE;
496 break;
Pavol Vican096c6db2016-02-11 15:08:10 +0100497 }
498 return ret;
499}
500
501int
Pavol Vican5f0316a2016-04-05 21:21:11 +0200502yang_read_units(struct lys_module *module, void *node, char *value, enum yytokentype type)
Pavol Vican096c6db2016-02-11 15:08:10 +0100503{
504 int ret;
505
506 switch (type) {
Pavol Vican339d4ad2016-02-12 12:49:22 +0100507 case LEAF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100508 ret = yang_check_string(module, &((struct lys_node_leaf *) node)->units, "units", "leaf", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100509 break;
510 case LEAF_LIST_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100511 ret = yang_check_string(module, &((struct lys_node_leaflist *) node)->units, "units", "leaflist", value);
Pavol Vican339d4ad2016-02-12 12:49:22 +0100512 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100513 case TYPEDEF_KEYWORD:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100514 ret = yang_check_string(module, &((struct lys_tpdf *) node)->units, "units", "typedef", value);
Pavol Vican0df02b02016-03-01 10:28:50 +0100515 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200516 default:
517 free(value);
518 LOGINT;
519 ret = EXIT_FAILURE;
520 break;
Pavol Vican8c82fa82016-02-10 13:13:24 +0100521 }
522 return ret;
523}
Pavol Vican5de33492016-02-22 14:03:24 +0100524
525int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100526yang_read_key(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
Pavol Vican5de33492016-02-22 14:03:24 +0100527{
528 char *exp, *value;
529
530 exp = value = (char *) list->keys;
531 while ((value = strpbrk(value, " \t\n"))) {
532 list->keys_size++;
533 while (isspace(*value)) {
534 value++;
535 }
536 }
537 list->keys_size++;
538 list->keys = calloc(list->keys_size, sizeof *list->keys);
539 if (!list->keys) {
540 LOGMEM;
541 goto error;
542 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100543 if (unres_schema_add_str(module, unres, list, UNRES_LIST_KEYS, exp) == -1) {
Pavol Vican5de33492016-02-22 14:03:24 +0100544 goto error;
545 }
546 free(exp);
547 return EXIT_SUCCESS;
548
549error:
550 free(exp);
551 return EXIT_FAILURE;
552}
553
554int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100555yang_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 +0100556{
557 int i, j;
558 char *vaux;
559
560 /* count the number of unique leafs in the value */
561 vaux = value;
562 while ((vaux = strpbrk(vaux, " \t\n"))) {
563 unique->expr_size++;
564 while (isspace(*vaux)) {
565 vaux++;
566 }
567 }
568 unique->expr_size++;
569 unique->expr = calloc(unique->expr_size, sizeof *unique->expr);
570 if (!unique->expr) {
571 LOGMEM;
572 goto error;
573 }
574
575 for (i = 0; i < unique->expr_size; i++) {
576 vaux = strpbrk(value, " \t\n");
577 if (!vaux) {
578 /* the last token, lydict_insert() will count its size on its own */
579 vaux = value;
580 }
581
582 /* store token into unique structure */
583 unique->expr[i] = lydict_insert(module->ctx, value, vaux - value);
584
585 /* check that the expression does not repeat */
586 for (j = 0; j < i; j++) {
587 if (ly_strequal(unique->expr[j], unique->expr[i], 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100588 LOGVAL(LYE_INARG, LY_VLOG_LYS, list, unique->expr[i], "unique");
589 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The identifier is not unique");
Pavol Vican85f12022016-03-05 16:30:35 +0100590 goto error;
591 }
592 }
593 /* try to resolve leaf */
594 if (unres) {
Pavol Vican18b10212016-04-11 15:41:52 +0200595 if (unres_schema_add_str(module, unres, (struct lys_node *) list, UNRES_LIST_UNIQ, unique->expr[i]) == -1) {
596 goto error;
597 }
Pavol Vican85f12022016-03-05 16:30:35 +0100598 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100599 if (resolve_unique((struct lys_node *)list, unique->expr[i])) {
Pavol Vican85f12022016-03-05 16:30:35 +0100600 goto error;
601 }
602 }
603
604 /* move to next token */
605 value = vaux;
606 while(isspace(*value)) {
607 value++;
608 }
609 }
610
611 return EXIT_SUCCESS;
612
613error:
614 return EXIT_FAILURE;
615}
616
617int
Pavol Vican5de33492016-02-22 14:03:24 +0100618yang_read_unique(struct lys_module *module, struct lys_node_list *list, struct unres_schema *unres)
619{
620 uint8_t k;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100621 char *str;
Pavol Vican5de33492016-02-22 14:03:24 +0100622
623 for(k=0; k<list->unique_size; k++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100624 str = (char *)list->unique[k].expr;
625 if (yang_fill_unique(module, list, &list->unique[k], str, unres)) {
Pavol Vican5de33492016-02-22 14:03:24 +0100626 goto error;
627 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100628 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100629 }
630 return EXIT_SUCCESS;
631
632error:
Pavol Vican0adf01d2016-03-22 12:29:33 +0100633 free(str);
Pavol Vican5de33492016-02-22 14:03:24 +0100634 return EXIT_FAILURE;
Pavol Vican73e7c992016-02-24 12:18:05 +0100635}
636
Pavol Vican1ff0e222016-02-26 12:27:01 +0100637static int
Pavol Vican0adf01d2016-03-22 12:29:33 +0100638yang_read_identyref(struct lys_module *module, struct lys_type *type, struct unres_schema *unres)
Pavol Vican1ff0e222016-02-26 12:27:01 +0100639{
640 const char *value, *tmp;
641 int rc, ret = EXIT_FAILURE;
642
643 value = tmp = type->info.lref.path;
644 /* store in the JSON format */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100645 value = transform_schema2json(module, value);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100646 if (!value) {
647 goto end;
648 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100649 rc = unres_schema_add_str(module, unres, type, UNRES_TYPE_IDENTREF, value);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100650 lydict_remove(module->ctx, value);
651
652 if (rc == -1) {
653 goto end;
654 }
655
656 ret = EXIT_SUCCESS;
657
658end:
659 lydict_remove(module->ctx, tmp);
660 return ret;
661}
662
Pavol Vican73e7c992016-02-24 12:18:05 +0100663int
664yang_check_type(struct lys_module *module, struct lys_node *parent, struct yang_type *typ, struct unres_schema *unres)
665{
666 int i, rc;
667 int ret = -1;
668 const char *name, *value;
669 LY_DATA_TYPE base;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200670 struct lys_type *type_der;
Pavol Vican73e7c992016-02-24 12:18:05 +0100671
Pavol Vican6b072512016-04-04 10:50:21 +0200672 base = typ->base;
Pavol Vican0adf01d2016-03-22 12:29:33 +0100673 value = transform_schema2json(module, typ->name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100674 if (!value) {
675 goto error;
676 }
677
678 i = parse_identifier(value);
679 if (i < 1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100680 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, value[-i], &value[-i]);
Pavol Vican73e7c992016-02-24 12:18:05 +0100681 lydict_remove(module->ctx, value);
682 goto error;
683 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200684 /* module name */
Pavol Vican73e7c992016-02-24 12:18:05 +0100685 name = value;
686 if (value[i]) {
687 typ->type->module_name = lydict_insert(module->ctx, value, i);
688 name += i;
689 if ((name[0] != ':') || (parse_identifier(name + 1) < 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100690 LOGVAL(LYE_INCHAR, LY_VLOG_NONE, NULL, name[0], name);
Pavol Vican73e7c992016-02-24 12:18:05 +0100691 lydict_remove(module->ctx, value);
692 goto error;
693 }
694 ++name;
695 }
696
697 rc = resolve_superior_type(name, typ->type->module_name, module, parent, &typ->type->der);
Pavol Vican73e7c992016-02-24 12:18:05 +0100698 if (rc == -1) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100699 LOGVAL(LYE_INMOD, LY_VLOG_NONE, NULL, typ->type->module_name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200700 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100701 goto error;
702
Michal Vasko01c6fd22016-05-20 11:43:05 +0200703 /* the type could not be resolved or it was resolved to an unresolved typedef or leafref */
Pavol Vican73e7c992016-02-24 12:18:05 +0100704 } else if (rc == EXIT_FAILURE) {
Michal Vasko01c6fd22016-05-20 11:43:05 +0200705 LOGVAL(LYE_NORESOLV, LY_VLOG_NONE, NULL, "type", name);
Radek Krejci408ab2f2016-06-06 15:27:10 +0200706 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100707 ret = EXIT_FAILURE;
708 goto error;
709 }
Radek Krejci408ab2f2016-06-06 15:27:10 +0200710 lydict_remove(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100711 typ->type->base = typ->type->der->type.base;
712 if (base == 0) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100713 base = typ->type->der->type.base;
Pavol Vican73e7c992016-02-24 12:18:05 +0100714 }
715 switch (base) {
716 case LY_TYPE_STRING:
717 if (typ->type->base == LY_TYPE_BINARY) {
718 if (typ->type->info.str.pat_count) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100719 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100720 goto error;
721 }
722 typ->type->info.binary.length = typ->type->info.str.length;
Pavol Vican07ea68d2016-02-25 12:01:37 +0100723 if (typ->type->info.binary.length && lyp_check_length_range(typ->type->info.binary.length->expr, typ->type)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100724 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, typ->type->info.binary.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100725 goto error;
726 }
727 } else if (typ->type->base == LY_TYPE_STRING) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100728 if (typ->type->info.str.length && lyp_check_length_range(typ->type->info.str.length->expr, typ->type)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100729 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, typ->type->info.str.length->expr, "length");
Pavol Vican73e7c992016-02-24 12:18:05 +0100730 goto error;
731 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100732 } else {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200733 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100734 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +0100735 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100736 break;
737 case LY_TYPE_DEC64:
738 if (typ->type->base == LY_TYPE_DEC64) {
Pavol Vican07ea68d2016-02-25 12:01:37 +0100739 if (typ->type->info.dec64.range && lyp_check_length_range(typ->type->info.dec64.range->expr, typ->type)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100740 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, typ->type->info.dec64.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100741 goto error;
742 }
Pavol Vican07ea68d2016-02-25 12:01:37 +0100743 /* mandatory sub-statement(s) check */
744 if (!typ->type->info.dec64.dig && !typ->type->der->type.der) {
745 /* decimal64 type directly derived from built-in type requires fraction-digits */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100746 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100747 goto error;
748 }
749 if (typ->type->info.dec64.dig && typ->type->der->type.der) {
750 /* type is not directly derived from buit-in type and fraction-digits statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100751 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +0100752 goto error;
753 }
Pavol Vicanaff5c802016-02-24 15:56:45 +0100754 } else if (typ->type->base >= LY_TYPE_INT8 && typ->type->base <=LY_TYPE_UINT64) {
755 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100756 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100757 goto error;
758 }
759 typ->type->info.num.range = typ->type->info.dec64.range;
Pavol Vican07ea68d2016-02-25 12:01:37 +0100760 if (typ->type->info.num.range && lyp_check_length_range(typ->type->info.num.range->expr, typ->type)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100761 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, typ->type->info.num.range->expr, "range");
Pavol Vicanaff5c802016-02-24 15:56:45 +0100762 goto error;
763 }
764 } else {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200765 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vicanaff5c802016-02-24 15:56:45 +0100766 goto error;
767 }
768 break;
Pavol Vican79a763d2016-02-25 15:41:27 +0100769 case LY_TYPE_ENUM:
770 if (typ->type->base != LY_TYPE_ENUM) {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200771 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vican79a763d2016-02-25 15:41:27 +0100772 goto error;
773 }
Pavol Vican03a59442016-03-21 15:23:45 +0100774 if (!typ->type->der->type.der && !typ->type->info.bits.count) {
Pavol Vican79a763d2016-02-25 15:41:27 +0100775 /* type is derived directly from buit-in enumeartion type and enum statement is required */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100776 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "enum", "type");
Pavol Vican79a763d2016-02-25 15:41:27 +0100777 goto error;
778 }
779 if (typ->type->der->type.der && typ->type->info.enums.count) {
780 /* type is not directly derived from buit-in enumeration type and enum statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100781 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "enum");
Pavol Vican79a763d2016-02-25 15:41:27 +0100782 goto error;
783 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100784 break;
Pavol Vican03a59442016-03-21 15:23:45 +0100785 case LY_TYPE_BITS:
786 if (typ->type->base != LY_TYPE_BITS) {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200787 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vican03a59442016-03-21 15:23:45 +0100788 goto error;
789 }
790 if (!typ->type->der->type.der && !typ->type->info.bits.count) {
791 /* type is derived directly from buit-in bits type and bit statement is required */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100792 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "bit", "type");
Pavol Vican03a59442016-03-21 15:23:45 +0100793 goto error;
794 }
795 if (typ->type->der->type.der && typ->type->info.bits.count) {
796 /* type is not directly derived from buit-in bits type and bit statement is prohibited */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100797 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "bit");
Pavol Vican03a59442016-03-21 15:23:45 +0100798 goto error;
799 }
800 break;
Pavol Vican1ff0e222016-02-26 12:27:01 +0100801 case LY_TYPE_LEAFREF:
Pavol Vican6b072512016-04-04 10:50:21 +0200802 if (typ->type->base == LY_TYPE_IDENT && (typ->flags & LYS_TYPE_BASE)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100803 if (yang_read_identyref(module, typ->type, unres)) {
Pavol Vican1ff0e222016-02-26 12:27:01 +0100804 goto error;
805 }
Pavol Vican191613a2016-02-26 16:21:32 +0100806 } else if (typ->type->base == LY_TYPE_LEAFREF) {
Pavol Vican6b072512016-04-04 10:50:21 +0200807 if (typ->type->info.lref.path) {
Pavol Vican191613a2016-02-26 16:21:32 +0100808 value = typ->type->info.lref.path;
809 /* store in the JSON format */
Pavol Vican0adf01d2016-03-22 12:29:33 +0100810 typ->type->info.lref.path = transform_schema2json(module, value);
Pavol Vican191613a2016-02-26 16:21:32 +0100811 lydict_remove(module->ctx, value);
812 if (!typ->type->info.lref.path) {
813 goto error;
814 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100815 if (unres_schema_add_node(module, unres, typ->type, UNRES_TYPE_LEAFREF, parent) == -1) {
Pavol Vican191613a2016-02-26 16:21:32 +0100816 goto error;
817 }
Pavol Vican6b072512016-04-04 10:50:21 +0200818 } else if (!typ->type->der->type.der) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100819 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "path", "type");
Pavol Vican191613a2016-02-26 16:21:32 +0100820 goto error;
Michal Vasko01c6fd22016-05-20 11:43:05 +0200821 } else {
822 for (type_der = &typ->type->der->type; !type_der->info.lref.path && type_der->der; type_der = &type_der->der->type);
823 if (!type_der->info.lref.path || !type_der->info.lref.target) {
824 LOGINT;
825 goto error;
826 }
827 /* add pointer to leafref target, only on leaves (not in typedefs) */
828 if (lys_leaf_add_leafref_target(type_der->info.lref.target, (struct lys_node *)typ->type->parent)) {
829 goto error;
830 }
Pavol Vican191613a2016-02-26 16:21:32 +0100831 }
Pavol Vican1ff0e222016-02-26 12:27:01 +0100832 } else {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200833 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vican1ff0e222016-02-26 12:27:01 +0100834 goto error;
835 }
836 break;
837 case LY_TYPE_IDENT:
838 if (typ->type->der->type.der) {
839 /* this is just a derived type with no base specified/required */
840 break;
841 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100842 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "base", "type");
Pavol Vican1ff0e222016-02-26 12:27:01 +0100843 goto error;
844 }
845 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100846 case LY_TYPE_UNION:
847 if (typ->type->base != LY_TYPE_UNION) {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200848 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100849 goto error;
850 }
851 if (!typ->type->info.uni.types) {
852 if (typ->type->der->type.der) {
853 /* this is just a derived type with no additional type specified/required */
854 break;
855 }
Pavol Vican0adf01d2016-03-22 12:29:33 +0100856 LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "(union) type");
Pavol Vicana4f045a2016-02-29 15:01:20 +0100857 goto error;
858 }
859 for (i = 0; i < typ->type->info.uni.count; i++) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100860 if (unres_schema_add_node(module, unres, &typ->type->info.uni.types[i], UNRES_TYPE_DER, parent)) {
Pavol Vicana4f045a2016-02-29 15:01:20 +0100861 goto error;
862 }
863 if (typ->type->info.uni.types[i].base == LY_TYPE_EMPTY) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100864 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "empty", typ->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100865 goto error;
866 } else if (typ->type->info.uni.types[i].base == LY_TYPE_LEAFREF) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100867 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "leafref", typ->name);
Pavol Vicana4f045a2016-02-29 15:01:20 +0100868 goto error;
869 }
870 }
871 break;
Pavol Vicana1827962016-02-29 15:39:42 +0100872
873 default:
874 if (base >= LY_TYPE_BINARY && base <= LY_TYPE_UINT64) {
875 if (typ->type->base != base) {
Pavol Vican933aa5a2016-04-09 21:05:46 +0200876 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", typ->type->parent->name);
Pavol Vicana1827962016-02-29 15:39:42 +0100877 goto error;
878 }
879 } else {
880 LOGINT;
881 goto error;
882 }
Pavol Vican73e7c992016-02-24 12:18:05 +0100883 }
884 return EXIT_SUCCESS;
885
886error:
887 if (typ->type->module_name) {
888 lydict_remove(module->ctx, typ->type->module_name);
889 typ->type->module_name = NULL;
890 }
891 return ret;
892}
893
894void *
Pavol Vican5f0316a2016-04-05 21:21:11 +0200895yang_read_type(struct lys_module *module, void *parent, char *value, enum yytokentype type)
Pavol Vican73e7c992016-02-24 12:18:05 +0100896{
897 struct yang_type *typ;
Pavol Vican4766aca2016-03-07 12:42:36 +0100898 struct type_deviation *dev;
899 struct lys_tpdf *tmp_parent;
Pavol Vican73e7c992016-02-24 12:18:05 +0100900
Pavol Vicand01d8ae2016-03-01 10:45:59 +0100901 typ = calloc(1, sizeof *typ);
902 if (!typ) {
Pavol Vican73e7c992016-02-24 12:18:05 +0100903 LOGMEM;
904 return NULL;
905 }
Pavol Vican73e7c992016-02-24 12:18:05 +0100906
907 typ->flags = LY_YANG_STRUCTURE_FLAG;
908 switch (type) {
909 case LEAF_KEYWORD:
910 ((struct lys_node_leaf *)parent)->type.der = (struct lys_tpdf *)typ;
911 ((struct lys_node_leaf *)parent)->type.parent = (struct lys_tpdf *)parent;
912 typ->type = &((struct lys_node_leaf *)parent)->type;
913 break;
Pavol Vicana55992a2016-03-01 13:37:17 +0100914 case LEAF_LIST_KEYWORD:
915 ((struct lys_node_leaflist *)parent)->type.der = (struct lys_tpdf *)typ;
916 ((struct lys_node_leaflist *)parent)->type.parent = (struct lys_tpdf *)parent;
917 typ->type = &((struct lys_node_leaflist *)parent)->type;
918 break;
Pavol Vicana4f045a2016-02-29 15:01:20 +0100919 case UNION_KEYWORD:
920 ((struct lys_type *)parent)->der = (struct lys_tpdf *)typ;
921 typ->type = (struct lys_type *)parent;
922 break;
Pavol Vican0df02b02016-03-01 10:28:50 +0100923 case TYPEDEF_KEYWORD:
924 ((struct lys_tpdf *)parent)->type.der = (struct lys_tpdf *)typ;
925 typ->type = &((struct lys_tpdf *)parent)->type;
Pavol Vican4766aca2016-03-07 12:42:36 +0100926 break;
927 case REPLACE_KEYWORD:
928 /* deviation replace type*/
929 dev = (struct type_deviation *)parent;
930 if (dev->deviate->type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100931 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "type", "deviation");
Pavol Vican4766aca2016-03-07 12:42:36 +0100932 goto error;
933 }
934 /* check target node type */
935 if (dev->target->nodetype == LYS_LEAF) {
936 typ->type = &((struct lys_node_leaf *)dev->target)->type;
937 } else if (dev->target->nodetype == LYS_LEAFLIST) {
938 typ->type = &((struct lys_node_leaflist *)dev->target)->type;
939 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100940 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "type");
941 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"type\" property.");
Pavol Vican4766aca2016-03-07 12:42:36 +0100942 goto error;
943 }
944
945 /* remove type and initialize it */
946 lys_type_free(module->ctx, typ->type);
947 tmp_parent = typ->type->parent;
948 memset(typ->type, 0, sizeof *typ->type);
949 typ->type->parent = tmp_parent;
950
951 /* replace it with the value specified in deviation */
952 /* HACK for unres */
953 typ->type->der = (struct lys_tpdf *)typ;
954 dev->deviate->type = typ->type;
955 break;
Pavol Vican5f0316a2016-04-05 21:21:11 +0200956 default:
957 goto error;
958 break;
Pavol Vican73e7c992016-02-24 12:18:05 +0100959 }
Pavol Vican5f0316a2016-04-05 21:21:11 +0200960 typ->name = lydict_insert_zc(module->ctx, value);
Pavol Vican73e7c992016-02-24 12:18:05 +0100961 return typ;
Pavol Vican4766aca2016-03-07 12:42:36 +0100962
963error:
Pavol Vican5f0316a2016-04-05 21:21:11 +0200964 free(value);
Pavol Vican4766aca2016-03-07 12:42:36 +0100965 free(typ);
966 return NULL;
Pavol Vican73e7c992016-02-24 12:18:05 +0100967}
968
Pavol Vicanbe9e3832016-04-28 02:21:37 +0200969void
970yang_delete_type(struct lys_module *module, struct yang_type *stype)
971{
972 int i;
973
974 stype->type->base = stype->base;
975 stype->type->der = NULL;
976 lydict_remove(module->ctx, stype->name);
977 if (stype->base == LY_TYPE_UNION) {
978 for (i = 0; i < stype->type->info.uni.count; i++) {
979 if (stype->type->info.uni.types[i].der) {
980 yang_delete_type(module, (struct yang_type *)stype->type->info.uni.types[i].der);
981 }
982 }
983 }
984 free(stype);
985}
986
Pavol Vican73e7c992016-02-24 12:18:05 +0100987void *
Pavol Vican0adf01d2016-03-22 12:29:33 +0100988yang_read_length(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican73e7c992016-02-24 12:18:05 +0100989{
990 struct lys_restr **length;
991
Pavol Vican6b072512016-04-04 10:50:21 +0200992 if (typ->base == 0 || typ->base == LY_TYPE_STRING) {
Pavol Vican73e7c992016-02-24 12:18:05 +0100993 length = &typ->type->info.str.length;
Pavol Vican6b072512016-04-04 10:50:21 +0200994 typ->base = LY_TYPE_STRING;
995 } else if (typ->base == LY_TYPE_BINARY) {
Pavol Vican73e7c992016-02-24 12:18:05 +0100996 length = &typ->type->info.binary.length;
997 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +0100998 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected length statement.");
Pavol Vican73e7c992016-02-24 12:18:05 +0100999 goto error;
1000 }
1001
1002 if (*length) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001003 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "length", "type");
Pavol Vicanbe9e3832016-04-28 02:21:37 +02001004 goto error;
Pavol Vican73e7c992016-02-24 12:18:05 +01001005 }
1006 *length = calloc(1, sizeof **length);
1007 if (!*length) {
1008 LOGMEM;
1009 goto error;
1010 }
1011 (*length)->expr = lydict_insert_zc(module->ctx, value);
1012 return *length;
1013
1014error:
1015 free(value);
1016 return NULL;
1017
1018}
Pavol Vican1c203db2016-02-24 14:05:23 +01001019
1020void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001021yang_read_pattern(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican1c203db2016-02-24 14:05:23 +01001022{
Michal Vasko0aee5c12016-06-17 14:27:26 +02001023 if (lyp_check_pattern(value, NULL)) {
Pavol Vican1c203db2016-02-24 14:05:23 +01001024 free(value);
1025 return NULL;
1026 }
Pavol Vican1c203db2016-02-24 14:05:23 +01001027
1028 typ->type->info.str.patterns[typ->type->info.str.pat_count].expr = lydict_insert_zc(module->ctx, value);
1029 typ->type->info.str.pat_count++;
1030 return &typ->type->info.str.patterns[typ->type->info.str.pat_count-1];
1031}
Pavol Vicanaff5c802016-02-24 15:56:45 +01001032
1033void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001034yang_read_range(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vicanaff5c802016-02-24 15:56:45 +01001035{
Pavol Vican6b072512016-04-04 10:50:21 +02001036 if (typ->base != 0 && typ->base != LY_TYPE_DEC64) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001037 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected range statement.");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001038 goto error;
1039 }
Pavol Vican6b072512016-04-04 10:50:21 +02001040 typ->base = LY_TYPE_DEC64;
Pavol Vicanaff5c802016-02-24 15:56:45 +01001041 if (typ->type->info.dec64.range) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001042 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "range", "type");
Pavol Vicanaff5c802016-02-24 15:56:45 +01001043 goto error;
1044 }
1045 typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
1046 if (!typ->type->info.dec64.range) {
1047 LOGMEM;
1048 goto error;
1049 }
1050 typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
1051 return typ->type->info.dec64.range;
1052
1053error:
1054 free(value);
1055 return NULL;
1056}
Pavol Vican07ea68d2016-02-25 12:01:37 +01001057
1058int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001059yang_read_fraction(struct yang_type *typ, uint32_t value)
Pavol Vican07ea68d2016-02-25 12:01:37 +01001060{
Radek Krejci8c3b4b62016-06-17 14:32:12 +02001061 unsigned int i;
1062
Pavol Vican6b072512016-04-04 10:50:21 +02001063 if (typ->base == 0 || typ->base == LY_TYPE_DEC64) {
1064 typ->base = LY_TYPE_DEC64;
Pavol Vican07ea68d2016-02-25 12:01:37 +01001065 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001066 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected fraction-digits statement.");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001067 goto error;
1068 }
1069 if (typ->type->info.dec64.dig) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001070 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "fraction-digits", "type");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001071 goto error;
1072 }
1073 /* range check */
1074 if (value < 1 || value > 18) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001075 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", value, "fraction-digits");
Pavol Vican07ea68d2016-02-25 12:01:37 +01001076 goto error;
1077 }
1078 typ->type->info.dec64.dig = value;
Radek Krejci8c3b4b62016-06-17 14:32:12 +02001079 typ->type->info.dec64.div = 10;
1080 for (i = 1; i < value; i++) {
1081 typ->type->info.dec64.div *= 10;
1082 }
Pavol Vican07ea68d2016-02-25 12:01:37 +01001083 return EXIT_SUCCESS;
1084
1085error:
1086 return EXIT_FAILURE;
1087}
Pavol Vican79a763d2016-02-25 15:41:27 +01001088
1089void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001090yang_read_enum(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican79a763d2016-02-25 15:41:27 +01001091{
1092 struct lys_type_enum *enm;
1093 int i;
1094
1095 enm = &typ->type->info.enums.enm[typ->type->info.enums.count];
1096 enm->name = lydict_insert_zc(module->ctx, value);
1097
1098 /* the assigned name MUST NOT have any leading or trailing whitespace characters */
1099 if (isspace(enm->name[0]) || isspace(enm->name[strlen(enm->name) - 1])) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001100 LOGVAL(LYE_ENUM_WS, LY_VLOG_NONE, NULL, enm->name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001101 goto error;
1102 }
1103
1104 /* check the name uniqueness */
1105 for (i = 0; i < typ->type->info.enums.count; i++) {
1106 if (!strcmp(typ->type->info.enums.enm[i].name, typ->type->info.enums.enm[typ->type->info.enums.count].name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001107 LOGVAL(LYE_ENUM_DUPNAME, LY_VLOG_NONE, NULL, typ->type->info.enums.enm[i].name);
Pavol Vican79a763d2016-02-25 15:41:27 +01001108 goto error;
1109 }
1110 }
1111
1112 typ->type->info.enums.count++;
1113 return enm;
1114
1115error:
1116 typ->type->info.enums.count++;
1117 return NULL;
1118}
1119
1120int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001121yang_check_enum(struct yang_type *typ, struct lys_type_enum *enm, int64_t *value, int assign)
Pavol Vican79a763d2016-02-25 15:41:27 +01001122{
1123 int i, j;
1124
1125 if (!assign) {
1126 /* assign value automatically */
1127 if (*value > INT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001128 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "2147483648", "enum/value");
Pavol Vican79a763d2016-02-25 15:41:27 +01001129 goto error;
1130 }
1131 enm->value = *value;
1132 enm->flags |= LYS_AUTOASSIGNED;
1133 (*value)++;
1134 }
1135
1136 /* check that the value is unique */
1137 j = typ->type->info.enums.count-1;
1138 for (i = 0; i < j; i++) {
1139 if (typ->type->info.enums.enm[i].value == typ->type->info.enums.enm[j].value) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001140 LOGVAL(LYE_ENUM_DUPVAL, LY_VLOG_NONE, NULL,
Pavol Vican79a763d2016-02-25 15:41:27 +01001141 typ->type->info.enums.enm[j].value, typ->type->info.enums.enm[j].name);
1142 goto error;
1143 }
1144 }
1145
1146 return EXIT_SUCCESS;
1147
1148error:
1149 return EXIT_FAILURE;
1150}
Pavol Vican9887c682016-02-29 11:32:01 +01001151
1152void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001153yang_read_bit(struct lys_module *module, struct yang_type *typ, char *value)
Pavol Vican9887c682016-02-29 11:32:01 +01001154{
1155 int i;
1156 struct lys_type_bit *bit;
1157
1158 bit = &typ->type->info.bits.bit[typ->type->info.bits.count];
Pavol Vican0adf01d2016-03-22 12:29:33 +01001159 if (lyp_check_identifier(value, LY_IDENT_SIMPLE, NULL, NULL)) {
Pavol Vican9887c682016-02-29 11:32:01 +01001160 free(value);
1161 goto error;
1162 }
1163 bit->name = lydict_insert_zc(module->ctx, value);
1164
1165 /* check the name uniqueness */
1166 for (i = 0; i < typ->type->info.bits.count; i++) {
1167 if (!strcmp(typ->type->info.bits.bit[i].name, bit->name)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001168 LOGVAL(LYE_BITS_DUPNAME, LY_VLOG_NONE, NULL, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001169 typ->type->info.bits.count++;
1170 goto error;
1171 }
1172 }
1173 typ->type->info.bits.count++;
1174 return bit;
1175
1176error:
1177 return NULL;
1178}
1179
1180int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001181yang_check_bit(struct yang_type *typ, struct lys_type_bit *bit, int64_t *value, int assign)
Pavol Vican9887c682016-02-29 11:32:01 +01001182{
1183 int i,j;
1184 struct lys_type_bit bit_tmp;
1185
1186 if (!assign) {
1187 /* assign value automatically */
1188 if (*value > UINT32_MAX) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001189 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "4294967295", "bit/position");
Pavol Vican9887c682016-02-29 11:32:01 +01001190 goto error;
1191 }
1192 bit->pos = (uint32_t)*value;
1193 bit->flags |= LYS_AUTOASSIGNED;
1194 (*value)++;
1195 }
1196
1197 j = typ->type->info.bits.count - 1;
1198 /* check that the value is unique */
1199 for (i = 0; i < j; i++) {
1200 if (typ->type->info.bits.bit[i].pos == bit->pos) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001201 LOGVAL(LYE_BITS_DUPVAL, LY_VLOG_NONE, NULL, bit->pos, bit->name);
Pavol Vican9887c682016-02-29 11:32:01 +01001202 goto error;
1203 }
1204 }
1205
1206 /* keep them ordered by position */
1207 while (j && typ->type->info.bits.bit[j - 1].pos > typ->type->info.bits.bit[j].pos) {
1208 /* switch them */
Pavol Vican9b032132016-02-29 15:18:38 +01001209 memcpy(&bit_tmp, &typ->type->info.bits.bit[j], sizeof bit_tmp);
1210 memcpy(&typ->type->info.bits.bit[j], &typ->type->info.bits.bit[j - 1], sizeof bit_tmp);
1211 memcpy(&typ->type->info.bits.bit[j - 1], &bit_tmp, sizeof bit_tmp);
Pavol Vican9887c682016-02-29 11:32:01 +01001212 j--;
1213 }
1214
1215 return EXIT_SUCCESS;
1216
1217error:
1218 return EXIT_FAILURE;
1219}
Pavol Vican0df02b02016-03-01 10:28:50 +01001220
1221void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001222yang_read_typedef(struct lys_module *module, struct lys_node *parent, char *value)
Pavol Vican0df02b02016-03-01 10:28:50 +01001223{
1224 struct lys_tpdf *ret;
1225
Pavol Vican0adf01d2016-03-22 12:29:33 +01001226 if (lyp_check_identifier(value, LY_IDENT_TYPE, module, parent)) {
Pavol Vican0df02b02016-03-01 10:28:50 +01001227 free(value);
1228 return NULL;
1229 }
1230 if (!parent) {
1231 ret = &module->tpdf[module->tpdf_size];
Pavol Vican0df02b02016-03-01 10:28:50 +01001232 module->tpdf_size++;
Pavol Vican21238f52016-03-01 12:39:52 +01001233 } else {
1234 switch (parent->nodetype) {
1235 case LYS_GROUPING:
1236 ret = &((struct lys_node_grp *)parent)->tpdf[((struct lys_node_grp *)parent)->tpdf_size];
Pavol Vican21238f52016-03-01 12:39:52 +01001237 ((struct lys_node_grp *)parent)->tpdf_size++;
1238 break;
Pavol Vican535d50e2016-03-01 13:05:33 +01001239 case LYS_CONTAINER:
1240 ret = &((struct lys_node_container *)parent)->tpdf[((struct lys_node_container *)parent)->tpdf_size];
1241 ((struct lys_node_container *)parent)->tpdf_size++;
1242 break;
Pavol Vican09f04b82016-03-01 14:02:28 +01001243 case LYS_LIST:
1244 ret = &((struct lys_node_list *)parent)->tpdf[((struct lys_node_list *)parent)->tpdf_size];
1245 ((struct lys_node_list *)parent)->tpdf_size++;
1246 break;
Pavol Vican52ed67d2016-03-02 17:46:15 +01001247 case LYS_RPC:
1248 ret = &((struct lys_node_rpc *)parent)->tpdf[((struct lys_node_rpc *)parent)->tpdf_size];
1249 ((struct lys_node_rpc *)parent)->tpdf_size++;
1250 break;
Pavol Vican531a9132016-03-03 10:10:09 +01001251 case LYS_INPUT:
1252 case LYS_OUTPUT:
1253 ret = &((struct lys_node_rpc_inout *)parent)->tpdf[((struct lys_node_rpc_inout *)parent)->tpdf_size];
1254 ((struct lys_node_rpc_inout *)parent)->tpdf_size++;
1255 break;
Pavol Vican41267fd2016-03-03 10:47:42 +01001256 case LYS_NOTIF:
1257 ret = &((struct lys_node_notif *)parent)->tpdf[((struct lys_node_notif *)parent)->tpdf_size];
1258 ((struct lys_node_notif *)parent)->tpdf_size++;
1259 break;
Pavol Vicand1dbfda2016-03-21 10:03:58 +01001260 default:
1261 /* another type of nodetype is error*/
1262 LOGINT;
1263 free(value);
1264 return NULL;
Pavol Vican21238f52016-03-01 12:39:52 +01001265 }
Pavol Vican0df02b02016-03-01 10:28:50 +01001266 }
1267
Pavol Vican79436472016-04-04 11:22:02 +02001268 ret->type.parent = ret;
Pavol Vican0df02b02016-03-01 10:28:50 +01001269 ret->name = lydict_insert_zc(module->ctx, value);
1270 ret->module = module;
1271 return ret;
1272}
Pavol Vican1003ead2016-03-02 12:24:52 +01001273
1274void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001275yang_read_refine(struct lys_module *module, struct lys_node_uses *uses, char *value)
Pavol Vican1003ead2016-03-02 12:24:52 +01001276{
1277 struct lys_refine *rfn;
1278
1279 rfn = &uses->refine[uses->refine_size];
1280 uses->refine_size++;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001281 rfn->target_name = transform_schema2json(module, value);
Pavol Vican1003ead2016-03-02 12:24:52 +01001282 free(value);
1283 if (!rfn->target_name) {
1284 return NULL;
1285 }
1286 return rfn;
1287}
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001288
1289void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001290yang_read_augment(struct lys_module *module, struct lys_node *parent, char *value)
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001291{
1292 struct lys_node_augment *aug;
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001293
1294 if (parent) {
1295 aug = &((struct lys_node_uses *)parent)->augment[((struct lys_node_uses *)parent)->augment_size];
1296 } else {
1297 aug = &module->augment[module->augment_size];
1298 }
1299 aug->nodetype = LYS_AUGMENT;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001300 aug->target_name = transform_schema2json(module, value);
Pavol Vican92fa0dc2016-03-02 14:20:39 +01001301 free(value);
1302 if (!aug->target_name) {
1303 return NULL;
1304 }
1305 aug->parent = parent;
1306 aug->module = module;
1307 if (parent) {
1308 ((struct lys_node_uses *)parent)->augment_size++;
1309 } else {
1310 module->augment_size++;
1311 }
1312 return aug;
1313}
Pavol Vican220e5a12016-03-03 14:19:43 +01001314
1315void *
Pavol Vican0adf01d2016-03-22 12:29:33 +01001316yang_read_deviation(struct lys_module *module, char *value)
Pavol Vican220e5a12016-03-03 14:19:43 +01001317{
1318 struct lys_node *dev_target = NULL;
1319 struct lys_deviation *dev;
1320 struct type_deviation *deviation = NULL;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02001321 int rc;
Pavol Vican220e5a12016-03-03 14:19:43 +01001322
Pavol Vican220e5a12016-03-03 14:19:43 +01001323 dev = &module->deviation[module->deviation_size];
Pavol Vican0adf01d2016-03-22 12:29:33 +01001324 dev->target_name = transform_schema2json(module, value);
Pavol Vican220e5a12016-03-03 14:19:43 +01001325 free(value);
1326 if (!dev->target_name) {
1327 goto error;
1328 }
1329
Pavol Vican974377b2016-03-23 00:38:53 +01001330 deviation = calloc(1, sizeof *deviation);
1331 if (!deviation) {
1332 LOGMEM;
1333 goto error;
1334 }
1335
Pavol Vican220e5a12016-03-03 14:19:43 +01001336 /* resolve target node */
1337 rc = resolve_augment_schema_nodeid(dev->target_name, NULL, module, (const struct lys_node **)&dev_target);
1338 if (rc || !dev_target) {
Michal Vasko75c8daf2016-05-19 10:56:39 +02001339 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
Pavol Vican220e5a12016-03-03 14:19:43 +01001340 goto error;
1341 }
Radek Krejcic4283442016-04-22 09:19:27 +02001342 if (dev_target->module == lys_main_module(module)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001343 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->target_name, "deviation");
1344 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Deviating own module is not allowed.");
Pavol Vican220e5a12016-03-03 14:19:43 +01001345 goto error;
1346 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02001347
1348 lys_deviation_add_ext_imports(lys_node_module(dev_target), module);
1349
Pavol Vican220e5a12016-03-03 14:19:43 +01001350 /*save pointer to the deviation and deviated target*/
1351 deviation->deviation = dev;
1352 deviation->target = dev_target;
1353
Pavol Vican220e5a12016-03-03 14:19:43 +01001354 return deviation;
1355
1356error:
1357 free(deviation);
1358 lydict_remove(module->ctx, dev->target_name);
1359 return NULL;
1360}
Pavol Vican4c90c642016-03-03 15:06:47 +01001361
1362int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001363yang_read_deviate_unsupported(struct type_deviation *dev)
Pavol Vican4c90c642016-03-03 15:06:47 +01001364{
1365 int i;
1366
1367 if (dev->deviation->deviate_size) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001368 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
Pavol Vican4c90c642016-03-03 15:06:47 +01001369 return EXIT_FAILURE;
1370 }
1371 dev->deviation->deviate[dev->deviation->deviate_size].mod = LY_DEVIATE_NO;
1372
1373 /* you cannot remove a key leaf */
1374 if ((dev->target->nodetype == LYS_LEAF) && dev->target->parent && (dev->target->parent->nodetype == LYS_LIST)) {
1375 for (i = 0; i < ((struct lys_node_list *)dev->target->parent)->keys_size; ++i) {
1376 if (((struct lys_node_list *)dev->target->parent)->keys[i] == (struct lys_node_leaf *)dev->target) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001377 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, "not-supported", "deviation");
1378 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot remove a list key.");
Pavol Vican4c90c642016-03-03 15:06:47 +01001379 return EXIT_FAILURE;
1380 }
1381 }
1382 }
Michal Vaskofe7e5a72016-05-02 14:49:23 +02001383
Pavol Vican4c90c642016-03-03 15:06:47 +01001384 /* unlink and store the original node */
Michal Vaskod921d682016-05-19 10:56:51 +02001385 lys_node_unlink(dev->target);
Pavol Vican4c90c642016-03-03 15:06:47 +01001386 dev->deviation->orig_node = dev->target;
1387
1388 dev->deviation->deviate_size = 1;
1389 return EXIT_SUCCESS;
1390}
Pavol Vican85f12022016-03-05 16:30:35 +01001391
1392int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001393yang_read_deviate(struct type_deviation *dev, LYS_DEVIATE_TYPE mod)
Pavol Vican85f12022016-03-05 16:30:35 +01001394{
1395 struct unres_schema tmp_unres;
1396
1397 dev->deviation->deviate[dev->deviation->deviate_size].mod = mod;
1398 dev->deviate = &dev->deviation->deviate[dev->deviation->deviate_size];
1399 dev->deviation->deviate_size++;
1400 if (dev->deviation->deviate[0].mod == LY_DEVIATE_NO) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001401 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "not-supported");
1402 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "\"not-supported\" deviation cannot be combined with any other deviation.");
Pavol Vican85f12022016-03-05 16:30:35 +01001403 return EXIT_FAILURE;
1404 }
1405
1406 /* store a shallow copy of the original node */
1407 if (!dev->deviation->orig_node) {
1408 memset(&tmp_unres, 0, sizeof tmp_unres);
1409 dev->deviation->orig_node = lys_node_dup(dev->target->module, NULL, dev->target, 0, 0, &tmp_unres, 1);
1410 /* just to be safe */
1411 if (tmp_unres.count) {
1412 LOGINT;
1413 return EXIT_FAILURE;
1414 }
1415 }
1416
1417 return EXIT_SUCCESS;
1418}
1419
1420int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001421yang_read_deviate_units(struct ly_ctx *ctx, struct type_deviation *dev, char *value)
Pavol Vican85f12022016-03-05 16:30:35 +01001422{
1423 const char **stritem;
1424
1425 if (dev->deviate->units) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001426 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "units", "deviate");
Pavol Vican85f12022016-03-05 16:30:35 +01001427 free(value);
1428 goto error;
1429 }
1430
1431 /* check target node type */
1432 if (dev->target->nodetype == LYS_LEAFLIST) {
1433 stritem = &((struct lys_node_leaflist *)dev->target)->units;
1434 } else if (dev->target->nodetype == LYS_LEAF) {
1435 stritem = &((struct lys_node_leaf *)dev->target)->units;
1436 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001437 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1438 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"units\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001439 free(value);
1440 goto error;
1441 }
1442
1443 dev->deviate->units = lydict_insert_zc(ctx, value);
1444
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001445 if (dev->deviate->mod == LY_DEVIATE_DEL) {
1446 /* check values */
Michal Vaskob42b6972016-06-06 14:21:30 +02001447 if (!ly_strequal(*stritem, dev->deviate->units, 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001448 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->units, "units");
1449 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001450 goto error;
1451 }
1452 /* remove current units value of the target */
1453 lydict_remove(ctx, *stritem);
Pavol Vican4766aca2016-03-07 12:42:36 +01001454 } else {
1455 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1456 /* check that there is no current value */
1457 if (*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001458 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1459 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001460 goto error;
1461 }
1462 } else { /* replace */
1463 if (!*stritem) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001464 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "units");
1465 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001466 goto error;
1467 }
1468 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001469 /* remove current units value of the target ... */
1470 lydict_remove(ctx, *stritem);
1471
1472 /* ... and replace it with the value specified in deviation */
1473 *stritem = lydict_insert(ctx, dev->deviate->units, 0);
1474 }
1475
Pavol Vican85f12022016-03-05 16:30:35 +01001476 return EXIT_SUCCESS;
1477
1478error:
1479 return EXIT_FAILURE;
1480}
1481
1482int
Pavol Vican974377b2016-03-23 00:38:53 +01001483yang_read_deviate_must(struct type_deviation *dev, uint8_t c_must)
Pavol Vican85f12022016-03-05 16:30:35 +01001484{
Pavol Vican85f12022016-03-05 16:30:35 +01001485 /* check target node type */
1486 switch (dev->target->nodetype) {
1487 case LYS_LEAF:
1488 dev->trg_must = &((struct lys_node_leaf *)dev->target)->must;
1489 dev->trg_must_size = &((struct lys_node_leaf *)dev->target)->must_size;
1490 break;
1491 case LYS_CONTAINER:
1492 dev->trg_must = &((struct lys_node_container *)dev->target)->must;
1493 dev->trg_must_size = &((struct lys_node_container *)dev->target)->must_size;
1494 break;
1495 case LYS_LEAFLIST:
1496 dev->trg_must = &((struct lys_node_leaflist *)dev->target)->must;
1497 dev->trg_must_size = &((struct lys_node_leaflist *)dev->target)->must_size;
1498 break;
1499 case LYS_LIST:
1500 dev->trg_must = &((struct lys_node_list *)dev->target)->must;
1501 dev->trg_must_size = &((struct lys_node_list *)dev->target)->must_size;
1502 break;
1503 case LYS_ANYXML:
1504 dev->trg_must = &((struct lys_node_anyxml *)dev->target)->must;
1505 dev->trg_must_size = &((struct lys_node_anyxml *)dev->target)->must_size;
1506 break;
1507 default:
Pavol Vican0adf01d2016-03-22 12:29:33 +01001508 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "must");
1509 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"must\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001510 goto error;
1511 }
1512
1513 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1514 /* reallocate the must array of the target */
1515 dev->deviate->must = ly_realloc(*dev->trg_must, (c_must + *dev->trg_must_size) * sizeof *dev->deviate->must);
1516 if (!dev->deviate->must) {
1517 LOGMEM;
1518 goto error;
1519 }
1520 *dev->trg_must = dev->deviate->must;
1521 dev->deviate->must = &((*dev->trg_must)[*dev->trg_must_size]);
1522 dev->deviate->must_size = c_must;
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001523 } else {
1524 /* LY_DEVIATE_DEL */
1525 dev->deviate->must = calloc(c_must, sizeof *dev->deviate->must);
1526 if (!dev->deviate->must) {
1527 LOGMEM;
1528 goto error;
1529 }
Pavol Vican85f12022016-03-05 16:30:35 +01001530 }
1531
1532 return EXIT_SUCCESS;
1533
1534error:
1535 return EXIT_FAILURE;
1536}
1537
1538int
Pavol Vican974377b2016-03-23 00:38:53 +01001539yang_read_deviate_unique(struct type_deviation *dev, uint8_t c_uniq)
Pavol Vican85f12022016-03-05 16:30:35 +01001540{
Pavol Vican85f12022016-03-05 16:30:35 +01001541 struct lys_node_list *list;
1542
1543 /* check target node type */
1544 if (dev->target->nodetype != LYS_LIST) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001545 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "unique");
1546 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"unique\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001547 goto error;
1548 }
1549
1550 list = (struct lys_node_list *)dev->target;
1551 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1552 /* reallocate the unique array of the target */
1553 dev->deviate->unique = ly_realloc(list->unique, (c_uniq + list->unique_size) * sizeof *dev->deviate->unique);
1554 if (!dev->deviate->unique) {
1555 LOGMEM;
1556 goto error;
1557 }
1558 list->unique = dev->deviate->unique;
1559 dev->deviate->unique = &list->unique[list->unique_size];
1560 dev->deviate->unique_size = c_uniq;
1561 memset(dev->deviate->unique, 0, c_uniq * sizeof *dev->deviate->unique);
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001562 } else {
1563 /* LY_DEVIATE_DEL */
1564 dev->deviate->unique = calloc(c_uniq, sizeof *dev->deviate->unique);
1565 if (!dev->deviate->unique) {
1566 LOGMEM;
1567 goto error;
1568 }
Pavol Vican85f12022016-03-05 16:30:35 +01001569 }
1570
1571 return EXIT_SUCCESS;
1572
1573error:
1574 return EXIT_FAILURE;
1575}
1576
1577int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001578yang_read_deviate_default(struct ly_ctx *ctx, struct type_deviation *dev, char *value)
Pavol Vican85f12022016-03-05 16:30:35 +01001579{
1580 int rc;
1581 struct lys_node_choice *choice;
1582 struct lys_node_leaf *leaf;
1583 struct lys_node *node;
1584
1585 if (dev->deviate->dflt) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001586 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "default", "deviate");
Pavol Vican85f12022016-03-05 16:30:35 +01001587 free(value);
1588 goto error;
1589 }
1590
1591 dev->deviate->dflt = lydict_insert_zc(ctx, value);
1592
1593 if (dev->target->nodetype == LYS_CHOICE) {
1594 choice = (struct lys_node_choice *)dev->target;
1595
Pavol Vican85f12022016-03-05 16:30:35 +01001596 rc = resolve_choice_default_schema_nodeid(dev->deviate->dflt, choice->child, (const struct lys_node **)&node);
1597 if (rc || !node) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001598 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->dflt, "default");
Pavol Vican85f12022016-03-05 16:30:35 +01001599 goto error;
1600 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001601 if (dev->deviate->mod == LY_DEVIATE_DEL) {
1602 if (!choice->dflt || (choice->dflt != node)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001603 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->dflt, "default");
1604 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001605 goto error;
1606 }
1607 choice->dflt = NULL;
Pavol Vican4766aca2016-03-07 12:42:36 +01001608 } else {
1609 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1610 /* check that there is no current value */
1611 if (choice->dflt) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001612 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1613 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001614 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001615 } else if (choice->flags & LYS_MAND_TRUE) {
1616 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "choice");
1617 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"default\" statement is forbidden on choices with \"mandatory\".");
1618 goto error;
Pavol Vican4766aca2016-03-07 12:42:36 +01001619 }
1620 } else { /* replace*/
1621 if (!choice->dflt) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001622 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1623 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001624 goto error;
1625 }
1626 }
1627
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001628 choice->dflt = node;
1629 if (!choice->dflt) {
1630 /* default branch not found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001631 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->dflt, "default");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001632 goto error;
1633 }
Pavol Vican85f12022016-03-05 16:30:35 +01001634 }
1635 } else if (dev->target->nodetype == LYS_LEAF) {
1636 leaf = (struct lys_node_leaf *)dev->target;
1637
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001638 if (dev->deviate->mod == LY_DEVIATE_DEL) {
Michal Vaskob42b6972016-06-06 14:21:30 +02001639 if (!leaf->dflt || !ly_strequal(leaf->dflt, dev->deviate->dflt, 1)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001640 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->dflt, "default");
1641 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001642 goto error;
1643 }
1644 /* remove value */
1645 lydict_remove(ctx, leaf->dflt);
1646 leaf->dflt = NULL;
Pavol Vican4766aca2016-03-07 12:42:36 +01001647 } else {
1648 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1649 /* check that there is no current value */
1650 if (leaf->dflt) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001651 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1652 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001653 goto error;
Pavol Vicanfdf81c42016-04-05 15:55:31 +02001654 } else if (leaf->flags & LYS_MAND_TRUE) {
1655 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1656 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "default", "leaf");
1657 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"default\" statement is forbidden on leaf with \"mandatory\".");
1658 goto error;
Pavol Vican4766aca2016-03-07 12:42:36 +01001659 }
1660 } else { /* replace*/
1661 if (!leaf->dflt) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001662 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1663 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001664 goto error;
1665 }
1666 }
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001667 /* remove value */
1668 lydict_remove(ctx, leaf->dflt);
Pavol Vican85f12022016-03-05 16:30:35 +01001669
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001670 /* set new value */
1671 leaf->dflt = lydict_insert(ctx, dev->deviate->dflt, 0);
1672 }
Pavol Vican85f12022016-03-05 16:30:35 +01001673 } else {
1674 /* invalid target for default value */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001675 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "default");
1676 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"default\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001677 goto error;
1678 }
1679
1680 return EXIT_SUCCESS;
1681
1682error:
1683 return EXIT_FAILURE;
1684}
1685
1686int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001687yang_read_deviate_config(struct type_deviation *dev, uint8_t value)
Pavol Vican85f12022016-03-05 16:30:35 +01001688{
1689 if (dev->deviate->flags & LYS_CONFIG_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001690 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "config", "deviate");
Pavol Vican85f12022016-03-05 16:30:35 +01001691 goto error;
1692 }
1693
1694 /* for we deviate from RFC 6020 and allow config property even it is/is not
1695 * specified in the target explicitly since config property inherits. So we expect
1696 * that config is specified in every node. But for delete, we check that the value
1697 * is the same as here in deviation
1698 */
1699 dev->deviate->flags |= value;
1700
1701 /* add and replace are the same in this case */
1702 /* remove current config value of the target ... */
1703 dev->target->flags &= ~LYS_CONFIG_MASK;
1704
1705 /* ... and replace it with the value specified in deviation */
1706 dev->target->flags |= dev->deviate->flags & LYS_CONFIG_MASK;
1707
1708 return EXIT_SUCCESS;
1709
1710error:
1711 return EXIT_FAILURE;
1712}
1713
1714int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001715yang_read_deviate_mandatory(struct type_deviation *dev, uint8_t value)
Pavol Vican85f12022016-03-05 16:30:35 +01001716{
1717 if (dev->deviate->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001718 LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "mandatory", "deviate");
Pavol Vican85f12022016-03-05 16:30:35 +01001719 goto error;
1720 }
1721
1722 /* check target node type */
1723 if (!(dev->target->nodetype & (LYS_LEAF | LYS_CHOICE | LYS_ANYXML))) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001724 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1725 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Target node does not allow \"mandatory\" property.");
Pavol Vican85f12022016-03-05 16:30:35 +01001726 goto error;
1727 }
1728
1729 dev->deviate->flags |= value;
1730
1731 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1732 /* check that there is no current value */
1733 if (dev->target->flags & LYS_MAND_MASK) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001734 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1735 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001736 goto error;
Pavol Vican321a02e2016-04-05 16:11:59 +02001737 } else {
1738 if (dev->target->nodetype == LYS_LEAF && ((struct lys_node_leaf *)dev->target)->dflt) {
1739 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */
1740 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "leaf");
1741 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on leaf with \"default\".");
1742 goto error;
1743 } else if (dev->target->nodetype == LYS_CHOICE && ((struct lys_node_choice *)dev->target)->dflt) {
1744 LOGVAL(LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "choice");
1745 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "The \"mandatory\" statement is forbidden on choices with \"default\".");
1746 goto error;
1747 }
Pavol Vican85f12022016-03-05 16:30:35 +01001748 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001749 } else { /* replace */
1750 if (!(dev->target->flags & LYS_MAND_MASK)) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001751 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "mandatory");
1752 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Replacing a property that does not exist.");
Pavol Vican4766aca2016-03-07 12:42:36 +01001753 goto error;
1754 }
Pavol Vican85f12022016-03-05 16:30:35 +01001755 }
1756
Pavol Vican85f12022016-03-05 16:30:35 +01001757 /* remove current mandatory value of the target ... */
1758 dev->target->flags &= ~LYS_MAND_MASK;
1759
1760 /* ... and replace it with the value specified in deviation */
1761 dev->target->flags |= dev->deviate->flags & LYS_MAND_MASK;
1762
1763 return EXIT_SUCCESS;
1764
1765error:
1766 return EXIT_FAILURE;
1767}
1768
1769int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001770yang_read_deviate_minmax(struct type_deviation *dev, uint32_t value, int type)
Pavol Vican85f12022016-03-05 16:30:35 +01001771{
1772 uint32_t *ui32val;
1773
1774 /* check target node type */
1775 if (dev->target->nodetype == LYS_LEAFLIST) {
1776 if (type) {
1777 ui32val = &((struct lys_node_leaflist *)dev->target)->max;
1778 } else {
1779 ui32val = &((struct lys_node_leaflist *)dev->target)->min;
1780 }
1781 } else if (dev->target->nodetype == LYS_LIST) {
1782 if (type) {
1783 ui32val = &((struct lys_node_list *)dev->target)->max;
1784 } else {
1785 ui32val = &((struct lys_node_list *)dev->target)->min;
1786 }
1787 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001788 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1789 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 +01001790 goto error;
1791 }
1792
1793 if (type) {
1794 dev->deviate->max = value;
Pavol Vican4766aca2016-03-07 12:42:36 +01001795 dev->deviate->max_set = 1;
Pavol Vican85f12022016-03-05 16:30:35 +01001796 } else {
1797 dev->deviate->min = value;
Pavol Vican4766aca2016-03-07 12:42:36 +01001798 dev->deviate->min_set = 1;
Pavol Vican85f12022016-03-05 16:30:35 +01001799 }
1800
1801 if (dev->deviate->mod == LY_DEVIATE_ADD) {
1802 /* check that there is no current value */
1803 if (*ui32val) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001804 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, (type) ? "max-elements" : "min-elements");
1805 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Adding property that already exists.");
Pavol Vican85f12022016-03-05 16:30:35 +01001806 goto error;
1807 }
Pavol Vican4766aca2016-03-07 12:42:36 +01001808 } else if (dev->deviate->mod == LY_DEVIATE_RPL) {
1809 /* unfortunately, there is no way to check reliably that there
1810 * was a value before, it could have been the default */
Pavol Vican85f12022016-03-05 16:30:35 +01001811 }
1812
1813 /* add (already checked) and replace */
1814 /* set new value specified in deviation */
1815 *ui32val = value;
1816
1817 return EXIT_SUCCESS;
1818
1819error:
1820 return EXIT_FAILURE;
1821}
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001822
1823int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001824yang_check_deviate_must(struct ly_ctx *ctx, struct type_deviation *dev)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001825{
1826 int i;
1827
1828 /* find must to delete, we are ok with just matching conditions */
1829 for (i = 0; i < *dev->trg_must_size; i++) {
1830 if (ly_strequal(dev->deviate->must[dev->deviate->must_size - 1].expr, (*dev->trg_must)[i].expr, 1)) {
1831 /* we have a match, free the must structure ... */
1832 lys_restr_free(ctx, &((*dev->trg_must)[i]));
1833 /* ... and maintain the array */
1834 (*dev->trg_must_size)--;
1835 if (i != *dev->trg_must_size) {
1836 (*dev->trg_must)[i].expr = (*dev->trg_must)[*dev->trg_must_size].expr;
1837 (*dev->trg_must)[i].dsc = (*dev->trg_must)[*dev->trg_must_size].dsc;
1838 (*dev->trg_must)[i].ref = (*dev->trg_must)[*dev->trg_must_size].ref;
1839 (*dev->trg_must)[i].eapptag = (*dev->trg_must)[*dev->trg_must_size].eapptag;
1840 (*dev->trg_must)[i].emsg = (*dev->trg_must)[*dev->trg_must_size].emsg;
1841 }
1842 if (!(*dev->trg_must_size)) {
1843 free(*dev->trg_must);
1844 *dev->trg_must = NULL;
1845 } else {
1846 (*dev->trg_must)[*dev->trg_must_size].expr = NULL;
1847 (*dev->trg_must)[*dev->trg_must_size].dsc = NULL;
1848 (*dev->trg_must)[*dev->trg_must_size].ref = NULL;
1849 (*dev->trg_must)[*dev->trg_must_size].eapptag = NULL;
1850 (*dev->trg_must)[*dev->trg_must_size].emsg = NULL;
1851 }
1852
1853 i = -1; /* set match flag */
1854 break;
1855 }
1856 }
1857 if (i != -1) {
1858 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001859 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, dev->deviate->must[dev->deviate->must_size - 1].expr, "must");
1860 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value does not match any must from the target.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001861 return EXIT_FAILURE;
1862 }
1863
1864 return EXIT_SUCCESS;
1865}
1866
1867int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001868yang_check_deviate_unique(struct lys_module *module, struct type_deviation *dev, char *value)
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001869{
1870 struct lys_node_list *list;
1871 int i, j;
1872
1873 list = (struct lys_node_list *)dev->target;
Pavol Vican0adf01d2016-03-22 12:29:33 +01001874 if (yang_fill_unique(module, list, &dev->deviate->unique[dev->deviate->unique_size], value, NULL)) {
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001875 dev->deviate->unique_size++;
1876 goto error;
1877 }
1878
1879 /* find unique structures to delete */
1880 for (i = 0; i < list->unique_size; i++) {
1881 if (list->unique[i].expr_size != dev->deviate->unique[dev->deviate->unique_size].expr_size) {
1882 continue;
1883 }
1884
1885 for (j = 0; j < dev->deviate->unique[dev->deviate->unique_size].expr_size; j++) {
1886 if (!ly_strequal(list->unique[i].expr[j], dev->deviate->unique[dev->deviate->unique_size].expr[j], 1)) {
1887 break;
1888 }
1889 }
1890
1891 if (j == dev->deviate->unique[dev->deviate->unique_size].expr_size) {
1892 /* we have a match, free the unique structure ... */
1893 for (j = 0; j < list->unique[i].expr_size; j++) {
1894 lydict_remove(module->ctx, list->unique[i].expr[j]);
1895 }
1896 free(list->unique[i].expr);
1897 /* ... and maintain the array */
1898 list->unique_size--;
1899 if (i != list->unique_size) {
1900 list->unique[i].expr_size = list->unique[list->unique_size].expr_size;
1901 list->unique[i].expr = list->unique[list->unique_size].expr;
1902 }
1903
1904 if (!list->unique_size) {
1905 free(list->unique);
1906 list->unique = NULL;
1907 } else {
1908 list->unique[list->unique_size].expr_size = 0;
1909 list->unique[list->unique_size].expr = NULL;
1910 }
1911
1912 i = -1; /* set match flag */
1913 break;
1914 }
1915 }
1916 dev->deviate->unique_size++;
1917
1918 if (i != -1) {
1919 /* no match found */
Pavol Vican0adf01d2016-03-22 12:29:33 +01001920 LOGVAL(LYE_INARG, LY_VLOG_NONE, NULL, value, "unique");
1921 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Value differs from the target being deleted.");
Pavol Vicanc1f5a502016-03-06 16:51:26 +01001922 goto error;
1923 }
1924
1925 free(value);
1926 return EXIT_SUCCESS;
1927
1928error:
1929 free(value);
1930 return EXIT_FAILURE;
1931}
Pavol Vicane92421d2016-03-08 10:12:33 +01001932
1933int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001934yang_check_deviation(struct lys_module *module, struct type_deviation *dev, struct unres_schema *unres)
Pavol Vicane92421d2016-03-08 10:12:33 +01001935{
1936 int i, rc;
1937
1938 if (dev->target->nodetype == LYS_LEAF) {
1939 for(i = 0; i < dev->deviation->deviate_size; ++i) {
1940 if (dev->deviation->deviate[i].mod != LY_DEVIATE_DEL) {
1941 if (dev->deviation->deviate[i].dflt || dev->deviation->deviate[i].type) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001942 rc = unres_schema_add_str(module, unres, &((struct lys_node_leaf *)dev->target)->type, UNRES_TYPE_DFLT, ((struct lys_node_leaf *)dev->target)->dflt);
Pavol Vicane92421d2016-03-08 10:12:33 +01001943 if (rc == -1) {
1944 return EXIT_FAILURE;
1945 } else if (rc == EXIT_FAILURE) {
Pavol Vican0adf01d2016-03-22 12:29:33 +01001946 LOGVAL(LYE_SPEC, LY_VLOG_NONE, NULL, "Leaf \"%s\" default value no longer matches its type.", dev->deviation->target_name);
Pavol Vicane92421d2016-03-08 10:12:33 +01001947 return EXIT_FAILURE;
1948 }
1949 break;
1950 }
1951 }
1952 }
1953 }
1954 return EXIT_SUCCESS;
Pavol Vican9b89dda2016-03-09 15:36:55 +01001955}
1956
1957int
1958yang_fill_include(struct lys_module *module, struct lys_submodule *submodule, char *value,
Radek Krejci4dcd3392016-06-22 10:28:40 +02001959 char *rev, struct unres_schema *unres)
Pavol Vican9b89dda2016-03-09 15:36:55 +01001960{
1961 struct lys_include inc;
1962 struct lys_module *trg;
Pavol Vican55870412016-03-10 12:36:21 +01001963 const char *str;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02001964 int rc;
Radek Krejci83e3f5b2016-06-24 14:55:25 +02001965 int ret = 0;
Pavol Vican9b89dda2016-03-09 15:36:55 +01001966
Pavol Vican55870412016-03-10 12:36:21 +01001967 str = lydict_insert_zc(module->ctx, value);
Pavol Vican9b89dda2016-03-09 15:36:55 +01001968 trg = (submodule) ? (struct lys_module *)submodule : module;
1969 inc.submodule = NULL;
1970 inc.external = 0;
1971 memcpy(inc.rev, rev, LY_REV_SIZE);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02001972 rc = lyp_check_include(module, submodule, str, &inc, unres);
1973 if (!rc) {
1974 /* success, copy the filled data into the final array */
Radek Krejci4dcd3392016-06-22 10:28:40 +02001975 memcpy(&trg->inc[trg->inc_size], &inc, sizeof inc);
1976 trg->inc_size++;
Radek Krejci5b2c8a82016-06-17 15:36:03 +02001977 } else if (rc == -1) {
Radek Krejci83e3f5b2016-06-24 14:55:25 +02001978 ret = -1;
Pavol Vican9b89dda2016-03-09 15:36:55 +01001979 }
Pavol Vican9b89dda2016-03-09 15:36:55 +01001980
Pavol Vican55870412016-03-10 12:36:21 +01001981 lydict_remove(module->ctx, str);
Radek Krejci5b2c8a82016-06-17 15:36:03 +02001982 return ret;
Pavol Vican9b89dda2016-03-09 15:36:55 +01001983}
Pavol Vicanf4717e62016-03-16 11:30:01 +01001984
1985int
Pavol Vican0adf01d2016-03-22 12:29:33 +01001986yang_use_extension(struct lys_module *module, struct lys_node *data_node, void *actual, char *value)
Pavol Vicanf4717e62016-03-16 11:30:01 +01001987{
1988 char *prefix;
1989 char *identif;
1990 const char *ns = NULL;
1991 int i;
1992
Pavol Vicanf4717e62016-03-16 11:30:01 +01001993 /* check to the same pointer */
1994 if (data_node != actual) {
1995 return EXIT_SUCCESS;
1996 }
1997
Pavol Vicana302aa62016-03-17 10:45:35 +01001998 prefix = strdup(value);
1999 if (!prefix) {
2000 LOGMEM;
2001 goto error;
2002 }
2003 /* find prefix anf identificator*/
2004 identif = strchr(prefix, ':');
2005 *identif = '\0';
2006 identif++;
2007
Pavol Vicanf4717e62016-03-16 11:30:01 +01002008 for(i = 0; i < module->imp_size; ++i) {
2009 if (!strcmp(module->imp[i].prefix, prefix)) {
2010 ns = module->imp[i].module->ns;
2011 break;
2012 }
2013 }
Pavol Vican1ff1b7b2016-04-07 09:51:49 +02002014 if (!ns && !strcmp(module->prefix, prefix)) {
2015 ns = (module->type) ? ((struct lys_submodule *)module)->belongsto->ns : module->ns;
2016 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002017 if (ns && !strcmp(ns, LY_NSNACM)) {
2018 if (!strcmp(identif, "default-deny-write")) {
2019 data_node->nacm |= LYS_NACM_DENYW;
2020 } else if (!strcmp(identif, "default-deny-all")) {
2021 data_node->nacm |= LYS_NACM_DENYA;
2022 } else {
Pavol Vican0adf01d2016-03-22 12:29:33 +01002023 LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, identif);
Pavol Vicana302aa62016-03-17 10:45:35 +01002024 goto error;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002025 }
2026 }
Pavol Vicana302aa62016-03-17 10:45:35 +01002027 free(prefix);
Pavol Vicanf4717e62016-03-16 11:30:01 +01002028 return EXIT_SUCCESS;
Pavol Vicana302aa62016-03-17 10:45:35 +01002029
2030error:
2031 free(prefix);
2032 return EXIT_FAILURE;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002033}
2034
2035void
2036nacm_inherit(struct lys_module *module)
2037{
Pavol Vican10ffba52016-04-04 12:21:22 +02002038 struct lys_node *next, *elem, *tmp_node, *tmp_child;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002039
2040 LY_TREE_DFS_BEGIN(module->data, next, elem) {
Pavol Vican10ffba52016-04-04 12:21:22 +02002041 tmp_node = NULL;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002042 if (elem->parent) {
2043 switch (elem->nodetype) {
Pavol Vican10ffba52016-04-04 12:21:22 +02002044 case LYS_GROUPING:
2045 /* extension nacm not inherited*/
2046 break;
2047 case LYS_CHOICE:
2048 case LYS_ANYXML:
2049 case LYS_USES:
2050 if (elem->parent->nodetype != LYS_GROUPING) {
2051 elem->nacm |= elem->parent->nacm;
2052 }
2053 break;
2054 case LYS_CONTAINER:
2055 case LYS_LIST:
2056 case LYS_CASE:
2057 case LYS_NOTIF:
2058 case LYS_RPC:
2059 case LYS_INPUT:
2060 case LYS_OUTPUT:
2061 case LYS_AUGMENT:
2062 elem->nacm |= elem->parent->nacm;
2063 break;
2064 case LYS_LEAF:
2065 case LYS_LEAFLIST:
2066 tmp_node = elem;
2067 tmp_child = elem->child;
2068 elem->child = NULL;
2069 default:
2070 break;
Pavol Vicanf4717e62016-03-16 11:30:01 +01002071 }
2072 }
2073 LY_TREE_DFS_END(module->data, next, elem);
Pavol Vican10ffba52016-04-04 12:21:22 +02002074 if (tmp_node) {
2075 tmp_node->child = tmp_child;
2076 }
Pavol Vicanf4717e62016-03-16 11:30:01 +01002077 }
2078}
Pavol Vican4fb66c92016-03-17 10:32:27 +01002079
2080void
2081store_flags(struct lys_node *node, uint8_t flags, int config_inherit)
2082{
2083 node->flags |= flags;
2084 if (!(node->flags & LYS_CONFIG_MASK) && config_inherit) {
2085 /* get config flag from parent */
2086 if (node->parent) {
2087 node->flags |= node->parent->flags & LYS_CONFIG_MASK;
2088 } else {
2089 /* default config is true */
2090 node->flags |= LYS_CONFIG_W;
2091 }
2092 }
2093}
Pavol Vican8e7110b2016-03-22 17:00:26 +01002094
Pavol Vican1938d882016-04-10 13:36:31 +02002095static int
2096yang_parse(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres, const char *data,
2097 unsigned int size, struct lys_array_size *size_arrays, int type_read)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002098{
2099 YY_BUFFER_STATE bp;
Pavol Vican802af1e2016-03-23 20:42:26 +01002100 yyscan_t scanner = NULL;
Pavol Vican1938d882016-04-10 13:36:31 +02002101 int ret = EXIT_SUCCESS;
2102
2103 yylex_init(&scanner);
2104 bp = yy_scan_buffer((char *)data, size, scanner);
2105 yy_switch_to_buffer(bp, scanner);
2106 if (yyparse(scanner, module, submodule, unres, size_arrays, type_read)) {
2107 ret = EXIT_FAILURE;
2108 }
2109 yy_delete_buffer(bp, scanner);
2110 yylex_destroy(scanner);
2111 return ret;
2112}
2113
2114int
2115yang_parse_mem(struct lys_module *module, struct lys_submodule *submodule, struct unres_schema *unres, const char *data, unsigned int size_data)
2116{
Pavol Vican8e7110b2016-03-22 17:00:26 +01002117 struct lys_array_size *size_arrays=NULL;
Pavol Vican974377b2016-03-23 00:38:53 +01002118 unsigned int size;
Pavol Vican1938d882016-04-10 13:36:31 +02002119 int ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002120
2121 size_arrays = calloc(1, sizeof *size_arrays);
2122 if (!size_arrays) {
2123 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002124 return EXIT_FAILURE;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002125 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002126 size = (size_data) ? size_data : strlen(data) + 2;
Pavol Vican1938d882016-04-10 13:36:31 +02002127 ret = yang_parse(module, submodule, unres, data, size, size_arrays, LY_READ_ONLY_SIZE);
2128 if (!ret) {
2129 ret = yang_parse(module, submodule, unres, data, size, size_arrays, LY_READ_ALL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002130 }
Pavol Vican8e7110b2016-03-22 17:00:26 +01002131 free(size_arrays->node);
2132 free(size_arrays);
Pavol Vican1938d882016-04-10 13:36:31 +02002133 return ret;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002134}
2135
2136struct lys_module *
Pavol Vican974377b2016-03-23 00:38:53 +01002137yang_read_module(struct ly_ctx *ctx, const char* data, unsigned int size, const char *revision, int implement)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002138{
2139
Pavol Vican10ffba52016-04-04 12:21:22 +02002140 struct lys_module *tmp_module, *module = NULL;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002141 struct unres_schema *unres = NULL;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002142 int i;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002143
2144 unres = calloc(1, sizeof *unres);
2145 if (!unres) {
2146 LOGMEM;
2147 goto error;
2148 }
2149
2150 module = calloc(1, sizeof *module);
2151 if (!module) {
2152 LOGMEM;
Pavol Vicanf7994fb2016-04-05 21:55:53 +02002153 goto error;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002154 }
2155
2156 /* initiale module */
Michal Vaskofe7e5a72016-05-02 14:49:23 +02002157 module->ctx = ctx;
Pavol Vican8e7110b2016-03-22 17:00:26 +01002158 module->type = 0;
2159 module->implemented = (implement ? 1 : 0);
2160
2161 if (yang_parse_mem(module, NULL, unres, data, size)) {
2162 goto error;
2163 }
2164
2165 if (module && unres->count && resolve_unres_schema(module, unres)) {
2166 goto error;
2167 }
2168
2169 if (revision) {
2170 /* check revision of the parsed model */
2171 if (!module->rev_size || strcmp(revision, module->rev[0].date)) {
2172 LOGVRB("Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
2173 module->name, module->rev[0].date, revision);
2174 goto error;
2175 }
2176 }
2177
Pavol Vican10ffba52016-04-04 12:21:22 +02002178 tmp_module = module;
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002179 if (lyp_ctx_add_module(&module)) {
Pavol Vican8e7110b2016-03-22 17:00:26 +01002180 goto error;
2181 }
2182
Pavol Vican10ffba52016-04-04 12:21:22 +02002183 if (module == tmp_module) {
2184 nacm_inherit(module);
2185 }
2186
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002187 if (module->augment_size || module->deviation_size) {
Michal Vasko5cec3312016-05-04 08:59:41 +02002188 if (!module->implemented) {
2189 LOGVRB("Module \"%s\" includes augments or deviations, changing conformance to \"implement\".", module->name);
2190 }
Michal Vasko26055752016-05-03 11:36:31 +02002191 if (lys_module_set_implement(module)) {
2192 goto error;
2193 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002194
Michal Vasko26055752016-05-03 11:36:31 +02002195 if (lys_sub_module_set_dev_aug_target_implement(module)) {
2196 goto error;
2197 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002198 for (i = 0; i < module->inc_size; ++i) {
Radek Krejci4dcd3392016-06-22 10:28:40 +02002199 if (!module->inc[i].submodule) {
2200 continue;
2201 }
Michal Vasko26055752016-05-03 11:36:31 +02002202 if (lys_sub_module_set_dev_aug_target_implement((struct lys_module *)module->inc[i].submodule)) {
2203 goto error;
2204 }
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002205 }
2206 }
2207
Pavol Vican8e7110b2016-03-22 17:00:26 +01002208 unres_schema_free(NULL, &unres);
2209 LOGVRB("Module \"%s\" successfully parsed.", module->name);
2210 return module;
2211
2212error:
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002213 /* cleanup */
Pavol Vican8e7110b2016-03-22 17:00:26 +01002214 unres_schema_free(module, &unres);
2215 if (!module || !module->name) {
2216 free(module);
2217 LOGERR(ly_errno, "Module parsing failed.");
2218 return NULL;
2219 }
2220
2221 LOGERR(ly_errno, "Module \"%s\" parsing failed.", module->name);
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002222
2223 lys_sub_module_remove_devs_augs(module);
2224 lys_free(module, NULL, 1);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002225 return NULL;
2226}
2227
2228struct lys_submodule *
Pavol Vican974377b2016-03-23 00:38:53 +01002229yang_read_submodule(struct lys_module *module, const char *data, unsigned int size, struct unres_schema *unres)
Pavol Vican8e7110b2016-03-22 17:00:26 +01002230{
2231 struct lys_submodule *submodule;
2232
2233 submodule = calloc(1, sizeof *submodule);
2234 if (!submodule) {
2235 LOGMEM;
2236 goto error;
2237 }
2238
2239 submodule->ctx = module->ctx;
2240 submodule->type = 1;
2241 submodule->belongsto = module;
2242
2243 if (yang_parse_mem(module, submodule, unres, data, size)) {
2244 goto error;
2245 }
2246
Pavol Vican8e7110b2016-03-22 17:00:26 +01002247 LOGVRB("Submodule \"%s\" successfully parsed.", submodule->name);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002248 return submodule;
2249
2250error:
2251 /* cleanup */
2252 unres_schema_free((struct lys_module *)submodule, &unres);
2253
2254 if (!submodule || !submodule->name) {
2255 free(submodule);
2256 LOGERR(ly_errno, "Submodule parsing failed.");
2257 return NULL;
2258 }
2259
2260 LOGERR(ly_errno, "Submodule \"%s\" parsing failed.", submodule->name);
2261
Michal Vasko9eb6dd02016-05-02 14:52:40 +02002262 lys_sub_module_remove_devs_augs((struct lys_module *)submodule);
2263 lys_submodule_module_data_free(submodule);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002264 lys_submodule_free(submodule, NULL);
Pavol Vican8e7110b2016-03-22 17:00:26 +01002265 return NULL;
2266}
Pavol Vican8760bb72016-04-07 09:44:01 +02002267
2268static int
2269count_substring(const char *str, char c)
2270{
2271 const char *tmp = str;
2272 int count = 0;
2273
2274 while ((tmp = strchr(tmp, c))) {
2275 tmp++;
2276 count++;
2277 }
2278 return count;
2279}
2280
2281static int
2282read_indent(const char *input, int indent, int size, int in_index, int *out_index, char *output)
2283{
2284 int k = 0, j;
2285
2286 while (in_index < size) {
2287 if (input[in_index] == ' ') {
2288 k++;
2289 } else if (input[in_index] == '\t') {
2290 /* RFC 6020 6.1.3 tab character is treated as 8 space characters */
2291 k += 8;
2292 } else {
2293 break;
2294 }
2295 ++in_index;
2296 if (k >= indent) {
2297 for (j = k - indent; j > 0; --j) {
2298 output[*out_index] = ' ';
2299 ++(*out_index);
2300 }
2301 break;
2302 }
2303 }
2304 return in_index;
2305}
2306
2307char *
2308yang_read_string(const char *input, int size, int indent)
2309{
2310 int space, count;
2311 int in_index, out_index;
2312 char *value;
2313 char *retval = NULL;
2314
2315 value = malloc(size + 1);
2316 if (!value) {
2317 LOGMEM;
2318 return NULL;
2319 }
2320 /* replace special character in escape sequence */
2321 in_index = out_index = 0;
2322 while (in_index < size) {
2323 if (input[in_index] == '\\') {
2324 if (input[in_index + 1] == 'n') {
2325 value[out_index] = '\n';
2326 ++in_index;
2327 } else if (input[in_index + 1] == 't') {
2328 value[out_index] = '\t';
2329 ++in_index;
2330 } else if (input[in_index + 1] == '\\') {
2331 value[out_index] = '\\';
2332 ++in_index;
2333 } else if ((in_index + 1) != size && input[in_index + 1] == '"') {
2334 value[out_index] = '"';
2335 ++in_index;
2336 } else {
2337 value[out_index] = input[in_index];
2338 }
2339 } else {
2340 value[out_index] = input[in_index];
2341 }
2342 ++in_index;
2343 ++out_index;
2344 }
2345 value[out_index] = '\0';
2346 size = out_index;
2347 count = count_substring(value, '\t');
2348
2349 /* extend size of string due to replacing character '\t' with 8 spaces */
2350 retval = malloc(size + 1 + 7 * count);
2351 if (!retval) {
2352 LOGMEM;
2353 goto error;
2354 }
2355 in_index = out_index = space = 0;
2356 while (in_index < size) {
2357 if (value[in_index] == '\n') {
2358 out_index -= space;
2359 space = 0;
2360 retval[out_index] = '\n';
2361 ++out_index;
2362 ++in_index;
2363 in_index = read_indent(value, indent, size, in_index, &out_index, retval);
2364 continue;
2365 } else {
2366 space = (value[in_index] == ' ' || value[in_index] == '\t') ? space + 1 : 0;
2367 retval[out_index] = value[in_index];
2368 ++out_index;
2369 }
2370 ++in_index;
2371 }
2372 retval[out_index] = '\0';
2373 if (out_index != size) {
2374 retval = ly_realloc(retval, out_index + 1);
2375 }
2376 free(value);
2377 return retval;
2378error:
2379 free(value);
2380 return NULL;
2381}