blob: 433fa8f7ab44de9f65ba3417c4aba7c6a3c1b94c [file] [log] [blame]
Radek Krejcida04f4a2015-05-21 12:54:09 +02001/**
2 * @file tree.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Manipulation with libyang data structures
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of the Company nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 */
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +020021#define _GNU_SOURCE
Radek Krejcida04f4a2015-05-21 12:54:09 +020022
Radek Krejci812b10a2015-05-28 16:48:25 +020023#include <assert.h>
Radek Krejci5a988152015-07-15 11:16:26 +020024#include <ctype.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020025#include <stdlib.h>
26#include <sys/mman.h>
27#include <sys/stat.h>
Radek Krejci8bc9ca02015-06-04 15:52:46 +020028#include <string.h>
Radek Krejcida04f4a2015-05-21 12:54:09 +020029
30#include "common.h"
31#include "context.h"
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +020032#include "parse.h"
Radek Krejci3045cf32015-05-28 10:58:52 +020033#include "parser.h"
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +020034#include "resolve.h"
Radek Krejci106efc02015-06-10 14:36:27 +020035#include "xml.h"
Radek Krejci8bc9ca02015-06-04 15:52:46 +020036#include "tree_internal.h"
Radek Krejciefaeba32015-05-27 14:30:57 +020037
Radek Krejci48061fb2015-08-05 15:41:07 +020038API struct lys_feature *
39lys_is_disabled(struct lys_node *node, int recursive)
40{
41 int i;
42
43check:
44 if (node->nodetype != LYS_INPUT && node->nodetype != LYS_OUTPUT) {
45 /* input/output does not have if-feature, so skip them */
46
47 /* check local if-features */
48 for (i = 0; i < node->features_size; i++) {
49 if (!(node->features[i]->flags & LYS_FENABLED)) {
50 return node->features[i];
51 }
52 }
53 }
54
55 if (!recursive) {
56 return NULL;
57 }
58
59 /* go through parents */
60 if (node->nodetype == LYS_AUGMENT) {
61 /* go to parent actually means go to the target node */
62 node = ((struct lys_node_augment *)node)->target;
63 goto check;
64 } else if (node->parent) {
65 node = node->parent;
66 goto check;
67 }
68
69 return NULL;
70}
71
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020072void
Radek Krejci1d82ef62015-08-07 14:44:40 +020073lys_node_unlink(struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +020074{
Radek Krejci76512572015-08-04 09:47:08 +020075 struct lys_node *parent, *first;
Radek Krejcida04f4a2015-05-21 12:54:09 +020076
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020077 if (!node) {
78 return;
79 }
Radek Krejcida04f4a2015-05-21 12:54:09 +020080
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020081 /* unlink from data model if necessary */
82 if (node->module) {
83 if (node->module->data == node) {
84 node->module->data = node->next;
Radek Krejci21181962015-06-30 14:11:00 +020085 } else if (node->module->rpc == node) {
86 node->module->rpc = node->next;
87 } else if (node->module->notif == node) {
88 node->module->notif = node->next;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020089 }
90 }
Radek Krejcida04f4a2015-05-21 12:54:09 +020091
Radek Krejci6e4ffbb2015-06-16 10:34:41 +020092 /* store pointers to important nodes */
93 parent = node->parent;
94 if (parent && !parent->nodetype) {
95 /* handle augments - first, unlink it from the augment parent ... */
96 if (parent->child == node) {
97 parent->child = node->next;
98 }
99 /* and then continue with the target parent */
Radek Krejci76512572015-08-04 09:47:08 +0200100 parent = ((struct lys_node_augment *)parent)->target;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200101 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200102
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200103 /* unlink from parent */
104 if (parent) {
105 if (parent->child == node) {
106 parent->child = node->next;
107 }
108 node->parent = NULL;
109 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200110
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200111 /* unlink from siblings */
112 if (node->prev == node) {
113 /* there are no more siblings */
114 return;
115 }
116 if (node->next) {
117 node->next->prev = node->prev;
118 } else {
119 /* unlinking the last element */
120 if (parent) {
121 first = parent->child;
122 } else {
123 first = node;
124 while (node->prev->next) {
125 first = node->prev;
126 }
127 }
128 first->prev = node->prev;
129 }
130 if (node->prev->next) {
131 node->prev->next = node->next;
132 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200133
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200134 /* clean up the unlinked element */
135 node->next = NULL;
136 node->prev = node;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200137}
138
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200139int
Radek Krejci1d82ef62015-08-07 14:44:40 +0200140lys_node_addchild(struct lys_node *parent, struct lys_node *child)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200141{
Radek Krejci76512572015-08-04 09:47:08 +0200142 struct lys_node *last;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200143
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200144 assert(parent);
145 assert(child);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200146
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200147 /* checks */
148 switch (parent->nodetype) {
Radek Krejci76512572015-08-04 09:47:08 +0200149 case LYS_CONTAINER:
150 case LYS_LIST:
151 case LYS_GROUPING:
152 case LYS_USES:
153 case LYS_INPUT:
154 case LYS_OUTPUT:
155 case LYS_NOTIF:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200156 if (!(child->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200157 (LYS_ANYXML | LYS_CHOICE | LYS_CONTAINER | LYS_GROUPING | LYS_LEAF |
158 LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200159 LOGVAL(LYE_SPEC, 0, "Unexpected substatement \"%s\" in \"%s\" (%s).",
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200160 strnodetype(child->nodetype), strnodetype(parent->nodetype), parent->name);
161 return EXIT_FAILURE;
162 }
163 break;
Radek Krejci76512572015-08-04 09:47:08 +0200164 case LYS_CHOICE:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200165 if (!(child->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200166 (LYS_ANYXML | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST))) {
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200167 LOGVAL(LYE_SPEC, 0, "Unexpected substatement \"%s\" in \"choice\" %s.",
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200168 strnodetype(child->nodetype), parent->name);
169 return EXIT_FAILURE;
170 }
171 break;
Radek Krejci76512572015-08-04 09:47:08 +0200172 case LYS_CASE:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200173 if (!(child->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200174 (LYS_ANYXML | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200175 LOGVAL(LYE_SPEC, 0, "Unexpected substatement \"%s\" in \"case\" %s.",
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200176 strnodetype(child->nodetype), parent->name);
177 return EXIT_FAILURE;
178 }
179 break;
Radek Krejci76512572015-08-04 09:47:08 +0200180 case LYS_RPC:
181 if (!(child->nodetype & (LYS_INPUT | LYS_OUTPUT | LYS_GROUPING))) {
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200182 LOGVAL(LYE_SPEC, 0, "Unexpected substatement \"%s\" in \"rpc\" %s.",
Michal Vasko38d01f72015-06-15 09:41:06 +0200183 strnodetype(child->nodetype), parent->name);
184 return EXIT_FAILURE;
185 }
186 break;
Radek Krejci76512572015-08-04 09:47:08 +0200187 case LYS_LEAF:
188 case LYS_LEAFLIST:
189 case LYS_ANYXML:
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200190 LOGVAL(LYE_SPEC, 0, "The \"%s\" statement (%s) cannot have any substatement.",
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200191 strnodetype(parent->nodetype), parent->name);
192 return EXIT_FAILURE;
Radek Krejci76512572015-08-04 09:47:08 +0200193 case LYS_AUGMENT:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200194 if (!(child->nodetype &
Radek Krejci76512572015-08-04 09:47:08 +0200195 (LYS_ANYXML | LYS_CASE | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF
196 | LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
Michal Vaskoe7fc19c2015-08-05 16:24:39 +0200197 LOGVAL(LYE_SPEC, 0, "Unexpected substatement \"%s\" in \"%s\" (%s).",
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200198 strnodetype(child->nodetype), strnodetype(parent->nodetype), parent->name);
199 return EXIT_FAILURE;
200 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200201 }
Radek Krejcib7155b52015-06-10 17:03:01 +0200202
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200203 if (child->parent) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200204 lys_node_unlink(child);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200205 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200206
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200207 if (!parent->child) {
208 /* the only/first child of the parent */
209 parent->child = child;
210 child->parent = parent;
211 last = child;
212 } else {
213 /* add a new child at the end of parent's child list */
214 last = parent->child->prev;
215 last->next = child;
216 child->prev = last;
217 }
218 while (last->next) {
219 last = last->next;
220 last->parent = parent;
221 }
222 parent->child->prev = last;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200223
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200224 return EXIT_SUCCESS;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200225}
226
Radek Krejcib8048692015-08-05 13:36:34 +0200227API struct lys_module *
Radek Krejcia9167ef2015-08-03 11:01:11 +0200228lys_parse(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200229{
Michal Vaskof02e3742015-08-05 16:27:02 +0200230 struct unres_schema *unres;
Radek Krejcib8048692015-08-05 13:36:34 +0200231 struct lys_module *mod;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200232
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200233 if (!ctx || !data) {
234 LOGERR(LY_EINVAL, "%s: Invalid parameter.", __func__);
235 return NULL;
236 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200237
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200238 unres = calloc(1, sizeof *unres);
239
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200240 switch (format) {
Radek Krejcia9167ef2015-08-03 11:01:11 +0200241 case LYS_IN_YIN:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200242 mod = yin_read_module(ctx, data, 1, unres);
243 break;
Radek Krejcia9167ef2015-08-03 11:01:11 +0200244 case LYS_IN_YANG:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200245 /* TODO */
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200246 mod = NULL;
247 break;
248 default:
249 mod = NULL;
250 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200251 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200252
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200253 if (resolve_unres(mod, unres)) {
254 LOGERR(LY_EVALID, "There are unresolved items left.");
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200255 lys_free(mod);
256 mod = NULL;
257 }
258 free(unres->item);
259 free(unres->type);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200260 free(unres->str_snode);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200261 free(unres->line);
262 free(unres);
263
264 return mod;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200265}
266
Radek Krejcib8048692015-08-05 13:36:34 +0200267struct lys_submodule *
Radek Krejci1d82ef62015-08-07 14:44:40 +0200268lys_submodule_parse(struct lys_module *module, const char *data, LYS_INFORMAT format, int implement)
Radek Krejciefaeba32015-05-27 14:30:57 +0200269{
Michal Vaskof02e3742015-08-05 16:27:02 +0200270 struct unres_schema *unres;
Radek Krejcib8048692015-08-05 13:36:34 +0200271 struct lys_submodule *submod;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200272
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200273 assert(module);
274 assert(data);
Radek Krejciefaeba32015-05-27 14:30:57 +0200275
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200276 unres = calloc(1, sizeof *unres);
277
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200278 switch (format) {
Radek Krejcia9167ef2015-08-03 11:01:11 +0200279 case LYS_IN_YIN:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200280 submod = yin_read_submodule(module, data, implement, unres);
281 break;
Radek Krejcia9167ef2015-08-03 11:01:11 +0200282 case LYS_IN_YANG:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200283 /* TODO */
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200284 submod = NULL;
285 break;
286 default:
287 submod = NULL;
288 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200289 }
Radek Krejciefaeba32015-05-27 14:30:57 +0200290
Radek Krejcib8048692015-08-05 13:36:34 +0200291 if (resolve_unres((struct lys_module *)submod, unres)) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200292 LOGERR(LY_EVALID, "There are unresolved items left.");
Radek Krejci1d82ef62015-08-07 14:44:40 +0200293 lys_submodule_free(submod);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200294 submod = NULL;
295 }
296 free(unres->item);
297 free(unres->type);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200298 free(unres->str_snode);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200299 free(unres->line);
300 free(unres);
301
302 return submod;
Radek Krejciefaeba32015-05-27 14:30:57 +0200303}
304
Radek Krejcib8048692015-08-05 13:36:34 +0200305API struct lys_module *
Radek Krejcia9167ef2015-08-03 11:01:11 +0200306lys_read(struct ly_ctx *ctx, int fd, LYS_INFORMAT format)
Radek Krejci63a91a92015-07-29 13:31:04 +0200307{
Radek Krejcib8048692015-08-05 13:36:34 +0200308 struct lys_module *module;
Radek Krejci63a91a92015-07-29 13:31:04 +0200309 struct stat sb;
310 char *addr;
311
312 if (!ctx || fd < 0) {
313 LOGERR(LY_EINVAL, "%s: Invalid parameter.", __func__);
314 return NULL;
315 }
316
317 /*
318 * TODO
319 * This is just a temporary solution to make working automatic search for
320 * imported modules. This doesn't work e.g. for streams (stdin)
321 */
322 fstat(fd, &sb);
323 addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
324 module = lys_parse(ctx, addr, format);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200325 munmap(addr, sb.st_size);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200326
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200327 return module;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200328}
329
Radek Krejcib8048692015-08-05 13:36:34 +0200330struct lys_submodule *
Radek Krejci1d82ef62015-08-07 14:44:40 +0200331lys_submodule_read(struct lys_module *module, int fd, LYS_INFORMAT format, int implement)
Radek Krejciefaeba32015-05-27 14:30:57 +0200332{
Radek Krejcib8048692015-08-05 13:36:34 +0200333 struct lys_submodule *submodule;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200334 struct stat sb;
335 char *addr;
Radek Krejciefaeba32015-05-27 14:30:57 +0200336
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200337 assert(module);
338 assert(fd >= 0);
Radek Krejciefaeba32015-05-27 14:30:57 +0200339
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200340 /*
341 * TODO
342 * This is just a temporary solution to make working automatic search for
343 * imported modules. This doesn't work e.g. for streams (stdin)
344 */
345 fstat(fd, &sb);
346 addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
347 /* TODO addr error check */
Radek Krejci1d82ef62015-08-07 14:44:40 +0200348 submodule = lys_submodule_parse(module, addr, format, implement);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200349 munmap(addr, sb.st_size);
Radek Krejciefaeba32015-05-27 14:30:57 +0200350
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200351 return submodule;
Radek Krejciefaeba32015-05-27 14:30:57 +0200352
353}
354
Radek Krejci1d82ef62015-08-07 14:44:40 +0200355static struct lys_restr *
356lys_restr_dup(struct ly_ctx *ctx, struct lys_restr *old, int size)
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200357{
Radek Krejci1574a8d2015-08-03 14:16:52 +0200358 struct lys_restr *result;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200359 int i;
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200360
Radek Krejci3733a802015-06-19 13:43:21 +0200361 if (!size) {
362 return NULL;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200363 }
Radek Krejci3733a802015-06-19 13:43:21 +0200364
365 result = calloc(size, sizeof *result);
366 for (i = 0; i < size; i++) {
367 result[i].expr = lydict_insert(ctx, old[i].expr, 0);
368 result[i].dsc = lydict_insert(ctx, old[i].dsc, 0);
369 result[i].ref = lydict_insert(ctx, old[i].ref, 0);
370 result[i].eapptag = lydict_insert(ctx, old[i].eapptag, 0);
371 result[i].emsg = lydict_insert(ctx, old[i].emsg, 0);
372 }
373
374 return result;
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200375}
376
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200377void
Radek Krejci1d82ef62015-08-07 14:44:40 +0200378lys_restr_free(struct ly_ctx *ctx, struct lys_restr *restr)
Radek Krejci0bd5db42015-06-19 13:30:07 +0200379{
380 assert(ctx);
381 if (!restr) {
382 return;
383 }
384
385 lydict_remove(ctx, restr->expr);
386 lydict_remove(ctx, restr->dsc);
387 lydict_remove(ctx, restr->ref);
388 lydict_remove(ctx, restr->eapptag);
389 lydict_remove(ctx, restr->emsg);
390}
391
Radek Krejci1d82ef62015-08-07 14:44:40 +0200392static void
393lys_type_dup(struct lys_module *mod, struct lys_node *parent, struct lys_type *new, struct lys_type *old,
Michal Vaskof02e3742015-08-05 16:27:02 +0200394 struct unres_schema *unres)
Radek Krejci3733a802015-06-19 13:43:21 +0200395{
396 int i;
397
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200398 new->prefix = lydict_insert(mod->ctx, old->prefix, 0);
Radek Krejci3733a802015-06-19 13:43:21 +0200399 new->base = old->base;
400 new->der = old->der;
401
Radek Krejci1d82ef62015-08-07 14:44:40 +0200402 i = unres_find(unres, old, UNRES_TYPE_DER);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200403 if (i != -1) {
404 /* HACK for unres */
Radek Krejci1574a8d2015-08-03 14:16:52 +0200405 new->der = (struct lys_tpdf *)parent;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200406 unres_add_str(mod, unres, new, UNRES_TYPE_DER, unres->str_snode[i], 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200407 return;
408 }
409
Radek Krejci3733a802015-06-19 13:43:21 +0200410 switch (new->base) {
411 case LY_TYPE_BINARY:
Radek Krejci425adf02015-06-26 16:23:28 +0200412 if (old->info.binary.length) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200413 new->info.binary.length = lys_restr_dup(mod->ctx, old->info.binary.length, 1);
Radek Krejci425adf02015-06-26 16:23:28 +0200414 }
Radek Krejci3733a802015-06-19 13:43:21 +0200415 break;
416
417 case LY_TYPE_BITS:
418 new->info.bits.count = old->info.bits.count;
419 if (new->info.bits.count) {
420 new->info.bits.bit = calloc(new->info.bits.count, sizeof *new->info.bits.bit);
421 for (i = 0; i < new->info.bits.count; i++) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200422 new->info.bits.bit[i].name = lydict_insert(mod->ctx, old->info.bits.bit[i].name, 0);
423 new->info.bits.bit[i].dsc = lydict_insert(mod->ctx, old->info.bits.bit[i].dsc, 0);
424 new->info.bits.bit[i].ref = lydict_insert(mod->ctx, old->info.bits.bit[i].ref, 0);
Radek Krejci3733a802015-06-19 13:43:21 +0200425 new->info.bits.bit[i].status = old->info.bits.bit[i].status;
426 new->info.bits.bit[i].pos = old->info.bits.bit[i].pos;
427 }
428 }
429 break;
430
Radek Krejcif9401c32015-06-26 16:47:36 +0200431 case LY_TYPE_DEC64:
432 new->info.dec64.dig = old->info.dec64.dig;
433 if (old->info.dec64.range) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200434 new->info.dec64.range = lys_restr_dup(mod->ctx, old->info.dec64.range, 1);
Radek Krejcif9401c32015-06-26 16:47:36 +0200435 }
436 break;
437
Radek Krejci3733a802015-06-19 13:43:21 +0200438 case LY_TYPE_ENUM:
439 new->info.enums.count = old->info.enums.count;
440 if (new->info.enums.count) {
Radek Krejci1574a8d2015-08-03 14:16:52 +0200441 new->info.enums.enm = calloc(new->info.enums.count, sizeof *new->info.enums.enm);
Radek Krejci3733a802015-06-19 13:43:21 +0200442 for (i = 0; i < new->info.enums.count; i++) {
Radek Krejci1574a8d2015-08-03 14:16:52 +0200443 new->info.enums.enm[i].name = lydict_insert(mod->ctx, old->info.enums.enm[i].name, 0);
444 new->info.enums.enm[i].dsc = lydict_insert(mod->ctx, old->info.enums.enm[i].dsc, 0);
445 new->info.enums.enm[i].ref = lydict_insert(mod->ctx, old->info.enums.enm[i].ref, 0);
446 new->info.enums.enm[i].status = old->info.enums.enm[i].status;
447 new->info.enums.enm[i].value = old->info.enums.enm[i].value;
Radek Krejci3733a802015-06-19 13:43:21 +0200448 }
449 }
450 break;
451
Radek Krejci4a7b5ee2015-06-19 14:56:43 +0200452 case LY_TYPE_IDENT:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200453 if (old->info.ident.ref) {
454 new->info.ident.ref = old->info.ident.ref;
455 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200456 i = unres_find(unres, old, UNRES_TYPE_IDENTREF);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200457 assert(i != -1);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200458 unres_add_str(mod, unres, new, UNRES_TYPE_IDENTREF, unres->str_snode[i], 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200459 }
Radek Krejci4a7b5ee2015-06-19 14:56:43 +0200460 break;
461
Radek Krejciaf351422015-06-19 14:49:38 +0200462 case LY_TYPE_INST:
463 new->info.inst.req = old->info.inst.req;
464 break;
465
Radek Krejcif2860132015-06-20 12:37:20 +0200466 case LY_TYPE_INT8:
467 case LY_TYPE_INT16:
468 case LY_TYPE_INT32:
469 case LY_TYPE_INT64:
470 case LY_TYPE_UINT8:
471 case LY_TYPE_UINT16:
472 case LY_TYPE_UINT32:
473 case LY_TYPE_UINT64:
Radek Krejci425adf02015-06-26 16:23:28 +0200474 if (old->info.num.range) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200475 new->info.num.range = lys_restr_dup(mod->ctx, old->info.num.range, 1);
Radek Krejci425adf02015-06-26 16:23:28 +0200476 }
Radek Krejcif2860132015-06-20 12:37:20 +0200477 break;
478
Radek Krejcidc4c1412015-06-19 15:39:54 +0200479 case LY_TYPE_LEAFREF:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200480 new->info.lref.path = lydict_insert(mod->ctx, old->info.lref.path, 0);
Radek Krejci1d82ef62015-08-07 14:44:40 +0200481 unres_add_node(mod, unres, new, UNRES_TYPE_LEAFREF, parent, 0);
Radek Krejcidc4c1412015-06-19 15:39:54 +0200482 break;
483
Radek Krejci3733a802015-06-19 13:43:21 +0200484 case LY_TYPE_STRING:
Radek Krejci5fbc9162015-06-19 14:11:11 +0200485 if (old->info.str.length) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200486 new->info.str.length = lys_restr_dup(mod->ctx, old->info.str.length, 1);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200487 }
Radek Krejci1d82ef62015-08-07 14:44:40 +0200488 new->info.str.patterns = lys_restr_dup(mod->ctx, old->info.str.patterns, old->info.str.pat_count);
Radek Krejci3733a802015-06-19 13:43:21 +0200489 break;
490
Radek Krejcie4c366b2015-07-02 10:11:31 +0200491 case LY_TYPE_UNION:
492 new->info.uni.count = old->info.uni.count;
493 if (new->info.uni.count) {
Radek Krejci1574a8d2015-08-03 14:16:52 +0200494 new->info.uni.types = calloc(new->info.uni.count, sizeof *new->info.uni.types);
Radek Krejcie4c366b2015-07-02 10:11:31 +0200495 for (i = 0; i < new->info.uni.count; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200496 lys_type_dup(mod, parent, &(new->info.uni.types[i]), &(old->info.uni.types[i]), unres);
Radek Krejcie4c366b2015-07-02 10:11:31 +0200497 }
498 }
499 break;
500
Radek Krejci3733a802015-06-19 13:43:21 +0200501 default:
Radek Krejcic7c85532015-07-02 10:16:54 +0200502 /* nothing to do for LY_TYPE_BOOL, LY_TYPE_EMPTY */
Radek Krejci3733a802015-06-19 13:43:21 +0200503 break;
504 }
505}
506
507void
Radek Krejci1d82ef62015-08-07 14:44:40 +0200508lys_type_free(struct ly_ctx *ctx, struct lys_type *type)
Radek Krejci5a065542015-05-22 15:02:07 +0200509{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200510 int i;
Radek Krejci5a065542015-05-22 15:02:07 +0200511
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200512 assert(ctx);
513 if (!type) {
514 return;
515 }
Radek Krejci812b10a2015-05-28 16:48:25 +0200516
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200517 lydict_remove(ctx, type->prefix);
Radek Krejci5a065542015-05-22 15:02:07 +0200518
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200519 switch (type->base) {
Radek Krejci0bd5db42015-06-19 13:30:07 +0200520 case LY_TYPE_BINARY:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200521 lys_restr_free(ctx, type->info.binary.length);
Radek Krejci0bd5db42015-06-19 13:30:07 +0200522 free(type->info.binary.length);
523 break;
Radek Krejci994b6f62015-06-18 16:47:27 +0200524 case LY_TYPE_BITS:
525 for (i = 0; i < type->info.bits.count; i++) {
526 lydict_remove(ctx, type->info.bits.bit[i].name);
527 lydict_remove(ctx, type->info.bits.bit[i].dsc);
528 lydict_remove(ctx, type->info.bits.bit[i].ref);
529 }
530 free(type->info.bits.bit);
531 break;
Radek Krejcif9401c32015-06-26 16:47:36 +0200532
533 case LY_TYPE_DEC64:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200534 lys_restr_free(ctx, type->info.dec64.range);
Radek Krejcif9401c32015-06-26 16:47:36 +0200535 free(type->info.dec64.range);
536 break;
537
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200538 case LY_TYPE_ENUM:
539 for (i = 0; i < type->info.enums.count; i++) {
Radek Krejci1574a8d2015-08-03 14:16:52 +0200540 lydict_remove(ctx, type->info.enums.enm[i].name);
541 lydict_remove(ctx, type->info.enums.enm[i].dsc);
542 lydict_remove(ctx, type->info.enums.enm[i].ref);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200543 }
Radek Krejci1574a8d2015-08-03 14:16:52 +0200544 free(type->info.enums.enm);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200545 break;
Radek Krejcidc4c1412015-06-19 15:39:54 +0200546
Radek Krejci6fcb9dd2015-06-22 10:16:37 +0200547 case LY_TYPE_INT8:
548 case LY_TYPE_INT16:
549 case LY_TYPE_INT32:
550 case LY_TYPE_INT64:
551 case LY_TYPE_UINT8:
552 case LY_TYPE_UINT16:
553 case LY_TYPE_UINT32:
554 case LY_TYPE_UINT64:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200555 lys_restr_free(ctx, type->info.num.range);
Radek Krejci6fcb9dd2015-06-22 10:16:37 +0200556 free(type->info.num.range);
557 break;
558
Radek Krejcidc4c1412015-06-19 15:39:54 +0200559 case LY_TYPE_LEAFREF:
560 lydict_remove(ctx, type->info.lref.path);
561 break;
562
Radek Krejci3733a802015-06-19 13:43:21 +0200563 case LY_TYPE_STRING:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200564 lys_restr_free(ctx, type->info.str.length);
Radek Krejci3733a802015-06-19 13:43:21 +0200565 free(type->info.str.length);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200566 for (i = 0; i < type->info.str.pat_count; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200567 lys_restr_free(ctx, &type->info.str.patterns[i]);
Radek Krejci5fbc9162015-06-19 14:11:11 +0200568 }
569 free(type->info.str.patterns);
Radek Krejci3733a802015-06-19 13:43:21 +0200570 break;
Radek Krejci4a7b5ee2015-06-19 14:56:43 +0200571
Radek Krejcie4c366b2015-07-02 10:11:31 +0200572 case LY_TYPE_UNION:
573 for (i = 0; i < type->info.uni.count; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200574 lys_type_free(ctx, &type->info.uni.types[i]);
Radek Krejcie4c366b2015-07-02 10:11:31 +0200575 }
Radek Krejci1574a8d2015-08-03 14:16:52 +0200576 free(type->info.uni.types);
Radek Krejci4a7b5ee2015-06-19 14:56:43 +0200577 break;
578
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200579 default:
Radek Krejcic7c85532015-07-02 10:16:54 +0200580 /* nothing to do for LY_TYPE_IDENT, LY_TYPE_INST, LY_TYPE_BOOL, LY_TYPE_EMPTY */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200581 break;
582 }
Radek Krejci5a065542015-05-22 15:02:07 +0200583}
584
Radek Krejci1d82ef62015-08-07 14:44:40 +0200585static struct lys_tpdf *
586lys_tpdf_dup(struct lys_module *mod, struct lys_node *parent, struct lys_tpdf *old, int size, struct unres_schema *unres)
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200587{
Radek Krejci1574a8d2015-08-03 14:16:52 +0200588 struct lys_tpdf *result;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200589 int i;
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200590
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200591 if (!size) {
592 return NULL;
593 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200594
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200595 result = calloc(size, sizeof *result);
596 for (i = 0; i < size; i++) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200597 result[i].name = lydict_insert(mod->ctx, old[i].name, 0);
598 result[i].dsc = lydict_insert(mod->ctx, old[i].dsc, 0);
599 result[i].ref = lydict_insert(mod->ctx, old[i].ref, 0);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200600 result[i].flags = old[i].flags;
601 result[i].module = old[i].module;
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200602
Radek Krejci1d82ef62015-08-07 14:44:40 +0200603 lys_type_dup(mod, parent, &(result[i].type), &(old[i].type), unres);
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200604
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200605 result[i].dflt = lydict_insert(mod->ctx, old[i].dflt, 0);
606 result[i].units = lydict_insert(mod->ctx, old[i].units, 0);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200607 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200608
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200609 return result;
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200610}
611
Radek Krejci1d82ef62015-08-07 14:44:40 +0200612static void
613lys_tpdf_free(struct ly_ctx *ctx, struct lys_tpdf *tpdf)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200614{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200615 assert(ctx);
616 if (!tpdf) {
617 return;
618 }
Radek Krejci812b10a2015-05-28 16:48:25 +0200619
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200620 lydict_remove(ctx, tpdf->name);
621 lydict_remove(ctx, tpdf->dsc);
622 lydict_remove(ctx, tpdf->ref);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200623
Radek Krejci1d82ef62015-08-07 14:44:40 +0200624 lys_type_free(ctx, &tpdf->type);
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200625
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200626 lydict_remove(ctx, tpdf->units);
627 lydict_remove(ctx, tpdf->dflt);
Radek Krejci8bc9ca02015-06-04 15:52:46 +0200628}
629
Radek Krejci1d82ef62015-08-07 14:44:40 +0200630static struct lys_when *
631lys_when_dup(struct ly_ctx *ctx, struct lys_when *old)
Radek Krejci00768f42015-06-18 17:04:04 +0200632{
Radek Krejci76512572015-08-04 09:47:08 +0200633 struct lys_when *new;
Radek Krejci00768f42015-06-18 17:04:04 +0200634
635 if (!old) {
636 return NULL;
637 }
638
639 new = calloc(1, sizeof *new);
640 new->cond = lydict_insert(ctx, old->cond, 0);
641 new->dsc = lydict_insert(ctx, old->dsc, 0);
642 new->ref = lydict_insert(ctx, old->ref, 0);
643
644 return new;
645}
646
Radek Krejci1d82ef62015-08-07 14:44:40 +0200647static void
648lys_when_free(struct ly_ctx *ctx, struct lys_when *w)
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200649{
650 if (!w) {
651 return;
652 }
653
654 lydict_remove(ctx, w->cond);
655 lydict_remove(ctx, w->dsc);
656 lydict_remove(ctx, w->ref);
657
658 free(w);
659}
660
Radek Krejci76512572015-08-04 09:47:08 +0200661static struct lys_node_augment *
Radek Krejci1d82ef62015-08-07 14:44:40 +0200662lys_augment_dup(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *old, int size,
Michal Vasko41de7352015-08-06 09:53:34 +0200663 struct unres_schema *unres)
Radek Krejci106efc02015-06-10 14:36:27 +0200664{
Radek Krejci76512572015-08-04 09:47:08 +0200665 struct lys_node_augment *new = NULL;
Michal Vasko41de7352015-08-06 09:53:34 +0200666 struct lys_node *snode;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200667 int i = -1;
Radek Krejci106efc02015-06-10 14:36:27 +0200668
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200669 if (!size) {
670 return NULL;
671 }
Radek Krejci106efc02015-06-10 14:36:27 +0200672
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200673 new = calloc(size, sizeof *new);
674 for (i = 0; i < size; i++) {
675 new[i].target_name = lydict_insert(module->ctx, old[i].target_name, 0);
676 new[i].dsc = lydict_insert(module->ctx, old[i].dsc, 0);
677 new[i].ref = lydict_insert(module->ctx, old[i].ref, 0);
678 new[i].flags = old[i].flags;
679 /* .target = NULL; .nodetype = 0 */
Radek Krejci106efc02015-06-10 14:36:27 +0200680
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200681 new[i].parent = parent;
Radek Krejci106efc02015-06-10 14:36:27 +0200682
Michal Vasko41de7352015-08-06 09:53:34 +0200683 /* copy the augment nodes */
684 assert(old[i].child);
685 LY_TREE_FOR(old[i].child, snode) {
Michal Vasko71e1aa82015-08-12 12:17:51 +0200686 lys_node_addchild((struct lys_node *)&new[i], lys_node_dup(module, snode, snode->flags, snode->nacm, 1, unres));
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200687 }
688 }
Radek Krejci106efc02015-06-10 14:36:27 +0200689
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200690 return new;
Radek Krejci106efc02015-06-10 14:36:27 +0200691}
692
Radek Krejci76512572015-08-04 09:47:08 +0200693static struct lys_refine *
Radek Krejci1d82ef62015-08-07 14:44:40 +0200694lys_refine_dup(struct lys_module *mod, struct lys_refine *old, int size, struct lys_node_uses *uses,
Michal Vaskof02e3742015-08-05 16:27:02 +0200695 struct unres_schema *unres)
Michal Vasko1982cad2015-06-08 15:49:30 +0200696{
Radek Krejci76512572015-08-04 09:47:08 +0200697 struct lys_refine *result;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200698 int i, j;
Michal Vasko1982cad2015-06-08 15:49:30 +0200699
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200700 if (!size) {
701 return NULL;
702 }
Michal Vasko1982cad2015-06-08 15:49:30 +0200703
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200704 result = calloc(size, sizeof *result);
705 for (i = 0; i < size; i++) {
Radek Krejci76512572015-08-04 09:47:08 +0200706 result[i].target_name = lydict_insert(mod->ctx, old[i].target_name, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200707 result[i].dsc = lydict_insert(mod->ctx, old[i].dsc, 0);
708 result[i].ref = lydict_insert(mod->ctx, old[i].ref, 0);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200709 result[i].flags = old[i].flags;
710 result[i].target_type = old[i].target_type;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200711
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200712 result[i].must_size = old[i].must_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +0200713 result[i].must = lys_restr_dup(mod->ctx, old[i].must, old[i].must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200714 for (j = 0; j < result[i].must_size; ++j) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200715 unres_add_node(mod, unres, &result[i].must[j], UNRES_MUST, (struct lys_node *)uses, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200716 }
717
Radek Krejci76512572015-08-04 09:47:08 +0200718 if (result[i].target_type & (LYS_LEAF | LYS_CHOICE)) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200719 result[i].mod.dflt = lydict_insert(mod->ctx, old[i].mod.dflt, 0);
Radek Krejci76512572015-08-04 09:47:08 +0200720 } else if (result[i].target_type == LYS_CONTAINER) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +0200721 result[i].mod.presence = lydict_insert(mod->ctx, old[i].mod.presence, 0);
Radek Krejci76512572015-08-04 09:47:08 +0200722 } else if (result[i].target_type & (LYS_LIST | LYS_LEAFLIST)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200723 result[i].mod.list = old[i].mod.list;
724 }
725 }
Michal Vasko1982cad2015-06-08 15:49:30 +0200726
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200727 return result;
Michal Vasko1982cad2015-06-08 15:49:30 +0200728}
729
Radek Krejci1d82ef62015-08-07 14:44:40 +0200730static void
731lys_ident_free(struct ly_ctx *ctx, struct lys_ident *ident)
Radek Krejci6793db02015-05-22 17:49:54 +0200732{
Radek Krejcia52656e2015-08-05 13:41:50 +0200733 struct lys_ident_der *der;
Radek Krejci6793db02015-05-22 17:49:54 +0200734
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200735 assert(ctx);
736 if (!ident) {
737 return;
738 }
Radek Krejci812b10a2015-05-28 16:48:25 +0200739
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200740 /*
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200741 * if caller free only a single data model which is used (its identity is
742 * reference from identity in another module), this silly freeing can lead
743 * to segmentation fault. But without noting if the module is used by some
744 * other, it cannot be solved.
Radek Krejcia3390692015-06-16 14:13:31 +0200745 *
746 * Possible solution is to not allow caller to remove particular schema
Radek Krejci1d82ef62015-08-07 14:44:40 +0200747 * from the context. This is the current approach.
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200748 */
749 while (ident->der) {
750 der = ident->der;
751 ident->der = der->next;
752 free(der);
753 }
Radek Krejci6793db02015-05-22 17:49:54 +0200754
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200755 lydict_remove(ctx, ident->name);
756 lydict_remove(ctx, ident->dsc);
757 lydict_remove(ctx, ident->ref);
Radek Krejci6793db02015-05-22 17:49:54 +0200758
759}
760
Radek Krejci1d82ef62015-08-07 14:44:40 +0200761static void
762lys_grp_free(struct ly_ctx *ctx, struct lys_node_grp *grp)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200763{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200764 int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200765
Radek Krejcid12f57b2015-08-06 10:43:39 +0200766 /* handle only specific parts for LYS_GROUPING */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200767 for (i = 0; i < grp->tpdf_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200768 lys_tpdf_free(ctx, &grp->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200769 }
770 free(grp->tpdf);
Radek Krejci537cf382015-06-04 11:07:01 +0200771}
772
Radek Krejci1d82ef62015-08-07 14:44:40 +0200773static void
Radek Krejcid12f57b2015-08-06 10:43:39 +0200774lys_rpc_inout_free(struct ly_ctx *ctx, struct lys_node_rpc_inout *io)
775{
776 int i;
777
778 /* handle only specific parts for LYS_INPUT and LYS_OUTPUT */
779 for (i = 0; i < io->tpdf_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200780 lys_tpdf_free(ctx, &io->tpdf[i]);
Radek Krejcid12f57b2015-08-06 10:43:39 +0200781 }
782 free(io->tpdf);
783}
784
Radek Krejci1d82ef62015-08-07 14:44:40 +0200785static void
786lys_anyxml_free(struct ly_ctx *ctx, struct lys_node_anyxml *anyxml)
Radek Krejci537cf382015-06-04 11:07:01 +0200787{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200788 int i;
Radek Krejci537cf382015-06-04 11:07:01 +0200789
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200790 for (i = 0; i < anyxml->must_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200791 lys_restr_free(ctx, &anyxml->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200792 }
793 free(anyxml->must);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200794
Radek Krejci1d82ef62015-08-07 14:44:40 +0200795 lys_when_free(ctx, anyxml->when);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200796}
797
Radek Krejci1d82ef62015-08-07 14:44:40 +0200798static void
799lys_leaf_free(struct ly_ctx *ctx, struct lys_node_leaf *leaf)
Radek Krejci5a065542015-05-22 15:02:07 +0200800{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200801 int i;
Radek Krejci537cf382015-06-04 11:07:01 +0200802
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200803 for (i = 0; i < leaf->must_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200804 lys_restr_free(ctx, &leaf->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200805 }
806 free(leaf->must);
Radek Krejci537cf382015-06-04 11:07:01 +0200807
Radek Krejci1d82ef62015-08-07 14:44:40 +0200808 lys_when_free(ctx, leaf->when);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200809
Radek Krejci1d82ef62015-08-07 14:44:40 +0200810 lys_type_free(ctx, &leaf->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200811 lydict_remove(ctx, leaf->units);
812 lydict_remove(ctx, leaf->dflt);
Radek Krejci5a065542015-05-22 15:02:07 +0200813}
814
Radek Krejci1d82ef62015-08-07 14:44:40 +0200815static void
816lys_leaflist_free(struct ly_ctx *ctx, struct lys_node_leaflist *llist)
Radek Krejci5a065542015-05-22 15:02:07 +0200817{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200818 int i;
Radek Krejci537cf382015-06-04 11:07:01 +0200819
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200820 for (i = 0; i < llist->must_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200821 lys_restr_free(ctx, &llist->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200822 }
823 free(llist->must);
Radek Krejci537cf382015-06-04 11:07:01 +0200824
Radek Krejci1d82ef62015-08-07 14:44:40 +0200825 lys_when_free(ctx, llist->when);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200826
Radek Krejci1d82ef62015-08-07 14:44:40 +0200827 lys_type_free(ctx, &llist->type);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200828 lydict_remove(ctx, llist->units);
Radek Krejci5a065542015-05-22 15:02:07 +0200829}
830
Radek Krejci1d82ef62015-08-07 14:44:40 +0200831static void
832lys_list_free(struct ly_ctx *ctx, struct lys_node_list *list)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200833{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200834 int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200835
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200836 /* handle only specific parts for LY_NODE_LIST */
837 for (i = 0; i < list->tpdf_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200838 lys_tpdf_free(ctx, &list->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200839 }
840 free(list->tpdf);
Radek Krejci537cf382015-06-04 11:07:01 +0200841
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200842 for (i = 0; i < list->must_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200843 lys_restr_free(ctx, &list->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200844 }
845 free(list->must);
Radek Krejci537cf382015-06-04 11:07:01 +0200846
Radek Krejci1d82ef62015-08-07 14:44:40 +0200847 lys_when_free(ctx, list->when);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200848
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200849 for (i = 0; i < list->unique_size; i++) {
850 free(list->unique[i].leafs);
851 }
852 free(list->unique);
Radek Krejcid7f0d012015-05-25 15:04:52 +0200853
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200854 free(list->keys);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200855}
856
Radek Krejci1d82ef62015-08-07 14:44:40 +0200857static void
858lys_container_free(struct ly_ctx *ctx, struct lys_node_container *cont)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200859{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200860 int i;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200861
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200862 /* handle only specific parts for LY_NODE_CONTAINER */
863 lydict_remove(ctx, cont->presence);
Radek Krejci800af702015-06-02 13:46:01 +0200864
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200865 for (i = 0; i < cont->tpdf_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200866 lys_tpdf_free(ctx, &cont->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200867 }
868 free(cont->tpdf);
Radek Krejci800af702015-06-02 13:46:01 +0200869
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200870 for (i = 0; i < cont->must_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200871 lys_restr_free(ctx, &cont->must[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200872 }
873 free(cont->must);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200874
Radek Krejci1d82ef62015-08-07 14:44:40 +0200875 lys_when_free(ctx, cont->when);
Radek Krejcida04f4a2015-05-21 12:54:09 +0200876}
877
Radek Krejci1d82ef62015-08-07 14:44:40 +0200878static void
879lys_feature_free(struct ly_ctx *ctx, struct lys_feature *f)
Radek Krejci3cf9e222015-06-18 11:37:50 +0200880{
881 lydict_remove(ctx, f->name);
882 lydict_remove(ctx, f->dsc);
883 lydict_remove(ctx, f->ref);
884 free(f->features);
885}
886
Radek Krejci1d82ef62015-08-07 14:44:40 +0200887static void
888lys_deviation_free(struct ly_ctx *ctx, struct lys_deviation *dev)
Radek Krejcieb00f512015-07-01 16:44:58 +0200889{
890 int i, j;
891
892 lydict_remove(ctx, dev->target_name);
893 lydict_remove(ctx, dev->dsc);
894 lydict_remove(ctx, dev->ref);
895
896 for (i = 0; i < dev->deviate_size; i++) {
897 lydict_remove(ctx, dev->deviate[i].dflt);
898 lydict_remove(ctx, dev->deviate[i].units);
899
900 if (dev->deviate[i].mod == LY_DEVIATE_DEL) {
901 for (j = 0; j < dev->deviate[i].must_size; j++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200902 lys_restr_free(ctx, &dev->deviate[i].must[j]);
Radek Krejcieb00f512015-07-01 16:44:58 +0200903 }
904 free(dev->deviate[i].must);
905
906 for (j = 0; j < dev->deviate[i].unique_size; j++) {
907 free(dev->deviate[j].unique[j].leafs);
908 }
909 free(dev->deviate[i].unique);
910 }
911 }
912 free(dev->deviate);
913}
914
Radek Krejci1d82ef62015-08-07 14:44:40 +0200915static void
916lys_augment_free(struct ly_ctx *ctx, struct lys_node_augment *aug)
Radek Krejcif5be10f2015-06-16 13:29:36 +0200917{
918 lydict_remove(ctx, aug->target_name);
919 lydict_remove(ctx, aug->dsc);
920 lydict_remove(ctx, aug->ref);
921
Michal Vasko25b39612015-07-07 16:11:07 +0200922 free(aug->features);
923
Radek Krejci1d82ef62015-08-07 14:44:40 +0200924 lys_when_free(ctx, aug->when);
Radek Krejcib0af6ba2015-06-18 15:01:03 +0200925
Radek Krejcif5be10f2015-06-16 13:29:36 +0200926 lyxml_free_elem(ctx, (struct lyxml_elem *)aug->child);
927}
928
Radek Krejci1d82ef62015-08-07 14:44:40 +0200929static void
930lys_uses_free(struct ly_ctx *ctx, struct lys_node_uses *uses)
Radek Krejcie1fa8582015-06-08 09:46:45 +0200931{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200932 int i, j;
Radek Krejcie1fa8582015-06-08 09:46:45 +0200933
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200934 for (i = 0; i < uses->refine_size; i++) {
Radek Krejci76512572015-08-04 09:47:08 +0200935 lydict_remove(ctx, uses->refine[i].target_name);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200936 lydict_remove(ctx, uses->refine[i].dsc);
937 lydict_remove(ctx, uses->refine[i].ref);
Radek Krejcie1fa8582015-06-08 09:46:45 +0200938
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200939 for (j = 0; j < uses->refine[j].must_size; j++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200940 lys_restr_free(ctx, &uses->refine[i].must[j]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200941 }
942 free(uses->refine[i].must);
Radek Krejcie1fa8582015-06-08 09:46:45 +0200943
Radek Krejci76512572015-08-04 09:47:08 +0200944 if (uses->refine[i].target_type & (LYS_LEAF | LYS_CHOICE)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200945 lydict_remove(ctx, uses->refine[i].mod.dflt);
Radek Krejci76512572015-08-04 09:47:08 +0200946 } else if (uses->refine[i].target_type & LYS_CONTAINER) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200947 lydict_remove(ctx, uses->refine[i].mod.presence);
948 }
949 }
950 free(uses->refine);
Radek Krejcie1fa8582015-06-08 09:46:45 +0200951
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200952 for (i = 0; i < uses->augment_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200953 lys_augment_free(ctx, &uses->augment[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200954 }
955 free(uses->augment);
Radek Krejcie1fa8582015-06-08 09:46:45 +0200956
Radek Krejci1d82ef62015-08-07 14:44:40 +0200957 lys_when_free(ctx, uses->when);
Radek Krejcie1fa8582015-06-08 09:46:45 +0200958}
959
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200960void
Radek Krejci1d82ef62015-08-07 14:44:40 +0200961lys_node_free(struct lys_node *node)
Radek Krejcida04f4a2015-05-21 12:54:09 +0200962{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200963 struct ly_ctx *ctx;
Radek Krejci76512572015-08-04 09:47:08 +0200964 struct lys_node *sub, *next;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200965
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200966 if (!node) {
967 return;
968 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200969
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200970 assert(node->module);
971 assert(node->module->ctx);
Radek Krejci812b10a2015-05-28 16:48:25 +0200972
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200973 ctx = node->module->ctx;
Radek Krejcida04f4a2015-05-21 12:54:09 +0200974
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200975 /* common part */
976 LY_TREE_FOR_SAFE(node->child, next, sub) {
Radek Krejci1d82ef62015-08-07 14:44:40 +0200977 lys_node_free(sub);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200978 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200979
Radek Krejcid12f57b2015-08-06 10:43:39 +0200980 if (!(node->nodetype & (LYS_INPUT | LYS_OUTPUT))) {
981 free(node->features);
982 lydict_remove(ctx, node->name);
983 lydict_remove(ctx, node->dsc);
984 lydict_remove(ctx, node->ref);
985 }
Radek Krejcida04f4a2015-05-21 12:54:09 +0200986
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200987 /* specific part */
988 switch (node->nodetype) {
Radek Krejci76512572015-08-04 09:47:08 +0200989 case LYS_CONTAINER:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200990 lys_container_free(ctx, (struct lys_node_container *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200991 break;
Radek Krejci76512572015-08-04 09:47:08 +0200992 case LYS_CHOICE:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200993 lys_when_free(ctx, ((struct lys_node_choice *)node)->when);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200994 break;
Radek Krejci76512572015-08-04 09:47:08 +0200995 case LYS_LEAF:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200996 lys_leaf_free(ctx, (struct lys_node_leaf *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +0200997 break;
Radek Krejci76512572015-08-04 09:47:08 +0200998 case LYS_LEAFLIST:
Radek Krejci1d82ef62015-08-07 14:44:40 +0200999 lys_leaflist_free(ctx, (struct lys_node_leaflist *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001000 break;
Radek Krejci76512572015-08-04 09:47:08 +02001001 case LYS_LIST:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001002 lys_list_free(ctx, (struct lys_node_list *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001003 break;
Radek Krejci76512572015-08-04 09:47:08 +02001004 case LYS_ANYXML:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001005 lys_anyxml_free(ctx, (struct lys_node_anyxml *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001006 break;
Radek Krejci76512572015-08-04 09:47:08 +02001007 case LYS_USES:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001008 lys_uses_free(ctx, (struct lys_node_uses *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001009 break;
Radek Krejci76512572015-08-04 09:47:08 +02001010 case LYS_CASE:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001011 lys_when_free(ctx, ((struct lys_node_case *)node)->when);
Radek Krejcib0af6ba2015-06-18 15:01:03 +02001012 break;
Radek Krejci76512572015-08-04 09:47:08 +02001013 case LYS_AUGMENT:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001014 /* do nothing */
1015 break;
Radek Krejci76512572015-08-04 09:47:08 +02001016 case LYS_GROUPING:
1017 case LYS_RPC:
Radek Krejci76512572015-08-04 09:47:08 +02001018 case LYS_NOTIF:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001019 lys_grp_free(ctx, (struct lys_node_grp *)node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001020 break;
Radek Krejcid12f57b2015-08-06 10:43:39 +02001021
1022 case LYS_INPUT:
1023 case LYS_OUTPUT:
1024 lys_rpc_inout_free(ctx, (struct lys_node_rpc_inout *)node);
1025 break;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001026 }
Radek Krejci5a065542015-05-22 15:02:07 +02001027
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001028 /* again common part */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001029 lys_node_unlink(node);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001030 free(node);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001031}
1032
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001033static void
Radek Krejcib8048692015-08-05 13:36:34 +02001034module_free_common(struct lys_module *module)
Radek Krejcida04f4a2015-05-21 12:54:09 +02001035{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001036 struct ly_ctx *ctx;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001037 unsigned int i;
Radek Krejcidce51452015-06-16 15:20:08 +02001038 int j, l;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001039
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001040 assert(module->ctx);
1041 ctx = module->ctx;
Radek Krejcida04f4a2015-05-21 12:54:09 +02001042
Radek Krejcidce51452015-06-16 15:20:08 +02001043 /* as first step, free the imported modules */
1044 for (i = 0; i < module->imp_size; i++) {
1045 /* get the imported module from the context and then free,
1046 * this check is necessary because the imported module can
1047 * be already removed
1048 */
1049 l = ctx->models.used;
1050 for (j = 0; j < l; j++) {
1051 if (ctx->models.list[j] == module->imp[i].module) {
Radek Krejci912da452015-07-29 14:10:06 +02001052 lys_free(module->imp[i].module);
Radek Krejcidce51452015-06-16 15:20:08 +02001053 break;
1054 }
1055 }
1056 }
1057 free(module->imp);
1058
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001059 while (module->data) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001060 lys_node_free(module->data);
Radek Krejci21181962015-06-30 14:11:00 +02001061 }
1062 while (module->rpc) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001063 lys_node_free(module->rpc);
Radek Krejci21181962015-06-30 14:11:00 +02001064 }
1065 while (module->notif) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001066 lys_node_free(module->notif);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001067 }
Radek Krejci5a065542015-05-22 15:02:07 +02001068
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001069 lydict_remove(ctx, module->dsc);
1070 lydict_remove(ctx, module->ref);
1071 lydict_remove(ctx, module->org);
1072 lydict_remove(ctx, module->contact);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001073
Radek Krejcieb00f512015-07-01 16:44:58 +02001074 /* revisions */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001075 for (i = 0; i < module->rev_size; i++) {
1076 lydict_remove(ctx, module->rev[i].dsc);
1077 lydict_remove(ctx, module->rev[i].ref);
1078 }
1079 free(module->rev);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001080
Radek Krejcieb00f512015-07-01 16:44:58 +02001081 /* identities */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001082 for (i = 0; i < module->ident_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001083 lys_ident_free(ctx, &module->ident[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001084 }
1085 module->ident_size = 0;
1086 free(module->ident);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001087
Radek Krejcieb00f512015-07-01 16:44:58 +02001088 /* typedefs */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001089 for (i = 0; i < module->tpdf_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001090 lys_tpdf_free(ctx, &module->tpdf[i]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001091 }
1092 free(module->tpdf);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001093
Radek Krejcieb00f512015-07-01 16:44:58 +02001094 /* include */
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001095 for (i = 0; i < module->inc_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001096 lys_submodule_free(module->inc[i].submodule);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001097 }
1098 free(module->inc);
Radek Krejciefaeba32015-05-27 14:30:57 +02001099
Radek Krejcieb00f512015-07-01 16:44:58 +02001100 /* augment */
Radek Krejcif5be10f2015-06-16 13:29:36 +02001101 for (i = 0; i < module->augment_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001102 lys_augment_free(ctx, &module->augment[i]);
Radek Krejcif5be10f2015-06-16 13:29:36 +02001103 }
1104 free(module->augment);
1105
Radek Krejcieb00f512015-07-01 16:44:58 +02001106 /* features */
Radek Krejci3cf9e222015-06-18 11:37:50 +02001107 for (i = 0; i < module->features_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001108 lys_feature_free(ctx, &module->features[i]);
Radek Krejci3cf9e222015-06-18 11:37:50 +02001109 }
1110 free(module->features);
1111
Radek Krejcieb00f512015-07-01 16:44:58 +02001112 /* deviations */
1113 for (i = 0; i < module->deviation_size; i++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001114 lys_deviation_free(ctx, &module->deviation[i]);
Radek Krejcieb00f512015-07-01 16:44:58 +02001115 }
1116 free(module->deviation);
1117
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001118 lydict_remove(ctx, module->name);
Radek Krejciefaeba32015-05-27 14:30:57 +02001119}
1120
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001121void
Radek Krejci1d82ef62015-08-07 14:44:40 +02001122lys_submodule_free(struct lys_submodule *submodule)
Radek Krejciefaeba32015-05-27 14:30:57 +02001123{
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001124 if (!submodule) {
1125 return;
1126 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001127
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001128 submodule->inc_size = 0;
1129 free(submodule->inc);
1130 submodule->inc = NULL;
Radek Krejcif3886932015-06-04 17:36:06 +02001131
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001132 /* common part with struct ly_module */
Radek Krejcib8048692015-08-05 13:36:34 +02001133 module_free_common((struct lys_module *)submodule);
Radek Krejciefaeba32015-05-27 14:30:57 +02001134
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001135 /* no specific items to free */
Radek Krejciefaeba32015-05-27 14:30:57 +02001136
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001137 free(submodule);
Radek Krejciefaeba32015-05-27 14:30:57 +02001138}
1139
Radek Krejcib8048692015-08-05 13:36:34 +02001140static struct lys_node_leaf *
Radek Krejci1d82ef62015-08-07 14:44:40 +02001141lys_uniq_find(struct lys_node_list *list, struct lys_node_leaf *orig_leaf)
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001142{
Radek Krejci1d82ef62015-08-07 14:44:40 +02001143 struct lys_node *node, *node2, *ret = NULL, *parent1, *parent2;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001144 int depth = 1, i;
1145
1146 /* find the correct direct descendant of list in orig_leaf */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001147 node = (struct lys_node *)orig_leaf;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001148 while (1) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001149 if (!node->parent) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001150 return NULL;
1151 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001152 if (!strcmp(node->parent->name, list->name)) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001153 break;
1154 }
1155
Radek Krejci1d82ef62015-08-07 14:44:40 +02001156 node = node->parent;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001157 ++depth;
1158 }
1159
1160 /* make sure the nodes are equal */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001161 parent1 = node->parent->parent;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001162 parent2 = list->parent;
1163 while (1) {
1164 if ((parent1 && !parent2) || (!parent1 && parent2)) {
1165 return NULL;
1166 }
1167
1168 if (parent1 == parent2) {
1169 break;
1170 }
1171
1172 parent1 = parent1->parent;
1173 parent2 = parent2->parent;
1174 }
1175
1176 /* find the descendant in the list */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001177 LY_TREE_FOR(list->child, node2) {
1178 if (!strcmp(node2->name, node->name)) {
1179 ret = node2;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001180 break;
1181 }
1182 }
1183
1184 if (!ret) {
1185 return NULL;
1186 }
1187
1188 /* continue traversing both trees, the nodes are always truly equal */
1189 while (1) {
1190 --depth;
1191 if (!depth) {
Radek Krejci76512572015-08-04 09:47:08 +02001192 if (ret->nodetype != LYS_LEAF) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001193 return NULL;
1194 }
Radek Krejcib8048692015-08-05 13:36:34 +02001195 return (struct lys_node_leaf *)ret;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001196 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001197 node = (struct lys_node *)orig_leaf;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001198 for (i = 0; i < depth-1; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001199 node = node->parent;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001200 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001201 LY_TREE_FOR(ret->child, node2) {
1202 if (!strcmp(node2->name, node->name)) {
1203 ret = node2;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001204 break;
1205 }
1206 }
Radek Krejci1d82ef62015-08-07 14:44:40 +02001207 if (!node2) {
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001208 return NULL;
1209 }
1210 }
1211}
1212
Radek Krejci76512572015-08-04 09:47:08 +02001213struct lys_node *
Michal Vasko71e1aa82015-08-12 12:17:51 +02001214lys_node_dup(struct lys_module *module, struct lys_node *node, uint8_t flags, uint8_t nacm, int recursive,
Michal Vaskof02e3742015-08-05 16:27:02 +02001215 struct unres_schema *unres)
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001216{
Radek Krejci76512572015-08-04 09:47:08 +02001217 struct lys_node *retval = NULL, *aux, *child;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001218 struct ly_ctx *ctx = module->ctx;
1219 int i, j;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001220
Radek Krejcib8048692015-08-05 13:36:34 +02001221 struct lys_node_container *cont;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001222 struct lys_node_container *cont_orig = (struct lys_node_container *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001223 struct lys_node_choice *choice;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001224 struct lys_node_choice *choice_orig = (struct lys_node_choice *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001225 struct lys_node_leaf *leaf;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001226 struct lys_node_leaf *leaf_orig = (struct lys_node_leaf *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001227 struct lys_node_leaflist *llist;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001228 struct lys_node_leaflist *llist_orig = (struct lys_node_leaflist *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001229 struct lys_node_list *list;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001230 struct lys_node_list *list_orig = (struct lys_node_list *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001231 struct lys_node_anyxml *anyxml;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001232 struct lys_node_anyxml *anyxml_orig = (struct lys_node_anyxml *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001233 struct lys_node_uses *uses;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001234 struct lys_node_uses *uses_orig = (struct lys_node_uses *)node;
Radek Krejcid12f57b2015-08-06 10:43:39 +02001235 struct lys_node_grp *grp;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001236 struct lys_node_grp *grp_orig = (struct lys_node_grp *)node;
Radek Krejcid12f57b2015-08-06 10:43:39 +02001237 struct lys_node_rpc *rpc;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001238 struct lys_node_rpc *rpc_orig = (struct lys_node_rpc *)node;
Radek Krejcid12f57b2015-08-06 10:43:39 +02001239 struct lys_node_rpc_inout *io;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001240 struct lys_node_rpc_inout *io_orig = (struct lys_node_rpc_inout *)node;
Radek Krejcid12f57b2015-08-06 10:43:39 +02001241 struct lys_node_rpc *ntf;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001242 struct lys_node_rpc *ntf_orig = (struct lys_node_rpc *)node;
Radek Krejcib8048692015-08-05 13:36:34 +02001243 struct lys_node_case *cs;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001244 struct lys_node_case *cs_orig = (struct lys_node_case *)node;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001245
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001246 /* we cannot just duplicate memory since the strings are stored in
1247 * dictionary and we need to update dictionary counters.
1248 */
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001249
Radek Krejci1d82ef62015-08-07 14:44:40 +02001250 switch (node->nodetype) {
Radek Krejci76512572015-08-04 09:47:08 +02001251 case LYS_CONTAINER:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001252 cont = calloc(1, sizeof *cont);
Radek Krejci76512572015-08-04 09:47:08 +02001253 retval = (struct lys_node *)cont;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001254 break;
1255
Radek Krejci76512572015-08-04 09:47:08 +02001256 case LYS_CHOICE:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001257 choice = calloc(1, sizeof *choice);
Radek Krejci76512572015-08-04 09:47:08 +02001258 retval = (struct lys_node *)choice;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001259 break;
1260
Radek Krejci76512572015-08-04 09:47:08 +02001261 case LYS_LEAF:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001262 leaf = calloc(1, sizeof *leaf);
Radek Krejci76512572015-08-04 09:47:08 +02001263 retval = (struct lys_node *)leaf;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001264 break;
1265
Radek Krejci76512572015-08-04 09:47:08 +02001266 case LYS_LEAFLIST:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001267 llist = calloc(1, sizeof *llist);
Radek Krejci76512572015-08-04 09:47:08 +02001268 retval = (struct lys_node *)llist;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001269 break;
1270
Radek Krejci76512572015-08-04 09:47:08 +02001271 case LYS_LIST:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001272 list = calloc(1, sizeof *list);
Radek Krejci76512572015-08-04 09:47:08 +02001273 retval = (struct lys_node *)list;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001274 break;
1275
Radek Krejci76512572015-08-04 09:47:08 +02001276 case LYS_ANYXML:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001277 anyxml = calloc(1, sizeof *anyxml);
Radek Krejci76512572015-08-04 09:47:08 +02001278 retval = (struct lys_node *)anyxml;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001279 break;
1280
Radek Krejci76512572015-08-04 09:47:08 +02001281 case LYS_USES:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001282 uses = calloc(1, sizeof *uses);
Radek Krejci76512572015-08-04 09:47:08 +02001283 retval = (struct lys_node *)uses;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001284 break;
1285
Radek Krejci76512572015-08-04 09:47:08 +02001286 case LYS_CASE:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001287 cs = calloc(1, sizeof *cs);
Radek Krejci76512572015-08-04 09:47:08 +02001288 retval = (struct lys_node *)cs;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001289 break;
1290
Radek Krejci76512572015-08-04 09:47:08 +02001291 case LYS_GROUPING:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001292 grp = calloc(1, sizeof *grp);
1293 retval = (struct lys_node *)grp;
1294 break;
1295
Radek Krejci76512572015-08-04 09:47:08 +02001296 case LYS_RPC:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001297 rpc = calloc(1, sizeof *rpc);
1298 retval = (struct lys_node *)rpc;
1299 break;
1300
Radek Krejci76512572015-08-04 09:47:08 +02001301 case LYS_INPUT:
1302 case LYS_OUTPUT:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001303 io = calloc(1, sizeof *io);
1304 retval = (struct lys_node *)io;
1305 break;
1306
Radek Krejci76512572015-08-04 09:47:08 +02001307 case LYS_NOTIF:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001308 ntf = calloc(1, sizeof *ntf);
1309 retval = (struct lys_node *)ntf;
Michal Vasko38d01f72015-06-15 09:41:06 +02001310 break;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001311
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001312 default:
Michal Vaskod23ce592015-08-06 09:55:37 +02001313 LOGINT;
1314 return NULL;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001315 }
Radek Krejcib388c152015-06-04 17:03:03 +02001316
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001317 /*
1318 * duplicate generic part of the structure
1319 */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001320 retval->name = lydict_insert(ctx, node->name, 0);
1321 retval->dsc = lydict_insert(ctx, node->dsc, 0);
1322 retval->ref = lydict_insert(ctx, node->ref, 0);
Michal Vasko71e1aa82015-08-12 12:17:51 +02001323 retval->nacm = nacm;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001324 retval->flags = node->flags;
Radek Krejci1574a8d2015-08-03 14:16:52 +02001325 if (!(retval->flags & LYS_CONFIG_MASK)) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001326 /* set parent's config flag */
Radek Krejci1574a8d2015-08-03 14:16:52 +02001327 retval->flags |= flags & LYS_CONFIG_MASK;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001328 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001329
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001330 retval->module = module;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001331 retval->nodetype = node->nodetype;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001332
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001333 retval->prev = retval;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001334
Radek Krejci1d82ef62015-08-07 14:44:40 +02001335 retval->features_size = node->features_size;
Radek Krejci3cf9e222015-06-18 11:37:50 +02001336 retval->features = calloc(retval->features_size, sizeof *retval->features);
Radek Krejci1d82ef62015-08-07 14:44:40 +02001337 for (i = 0; i < node->features_size; ++i) {
1338 if (unres_dup(module, unres, &node->features[i], UNRES_IFFEAT, &retval->features[i])) {
1339 retval->features[i] = node->features[i];
Michal Vaskod23ce592015-08-06 09:55:37 +02001340 }
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001341 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001342
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001343 if (recursive) {
1344 /* go recursively */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001345 LY_TREE_FOR(node->child, child) {
Michal Vasko71e1aa82015-08-12 12:17:51 +02001346 aux = lys_node_dup(module, child, retval->flags, retval->nacm, 1, unres);
Radek Krejci1d82ef62015-08-07 14:44:40 +02001347 if (!aux || lys_node_addchild(retval, aux)) {
Michal Vaskod23ce592015-08-06 09:55:37 +02001348 LOGINT;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001349 lys_node_free(retval);
Michal Vaskod23ce592015-08-06 09:55:37 +02001350 return NULL;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001351 }
1352 }
1353 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001354
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001355 /*
1356 * duplicate specific part of the structure
1357 */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001358 switch (node->nodetype) {
Radek Krejci76512572015-08-04 09:47:08 +02001359 case LYS_CONTAINER:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001360 if (cont_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001361 cont->when = lys_when_dup(ctx, cont_orig->when);
1362 unres_add_node(module, unres, cont->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001363 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001364 cont->presence = lydict_insert(ctx, cont_orig->presence, 0);
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001365
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001366 cont->must_size = cont_orig->must_size;
1367 cont->tpdf_size = cont_orig->tpdf_size;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001368
Radek Krejci1d82ef62015-08-07 14:44:40 +02001369 cont->must = lys_restr_dup(ctx, cont_orig->must, cont->must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001370 for (i = 0; i < cont->must_size; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001371 unres_add_node(module, unres, &cont->must[i], UNRES_MUST, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001372 }
1373
Radek Krejci1d82ef62015-08-07 14:44:40 +02001374 cont->tpdf = lys_tpdf_dup(module, node->parent, cont_orig->tpdf, cont->tpdf_size, unres);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001375 break;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001376
Radek Krejci76512572015-08-04 09:47:08 +02001377 case LYS_CHOICE:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001378 if (choice_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001379 choice->when = lys_when_dup(ctx, choice_orig->when);
1380 unres_add_node(module, unres, choice->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001381 }
1382
1383 if (choice_orig->dflt) {
Radek Krejci76512572015-08-04 09:47:08 +02001384 choice->dflt = resolve_child((struct lys_node *)choice, choice_orig->dflt->name, 0, LYS_ANYXML
1385 | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST
1386 | LYS_LIST);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001387 assert(choice->dflt);
1388 } else {
Michal Vaskoc68a2a22015-08-06 09:57:24 +02001389 /* useless to check return value, we don't know whether
1390 * there really wasn't any default defined or it just hasn't
1391 * been resolved, we just hope for the best :)
1392 */
Radek Krejci1d82ef62015-08-07 14:44:40 +02001393 unres_dup(module, unres, choice_orig, UNRES_CHOICE_DFLT, choice);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001394 }
1395 break;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001396
Radek Krejci76512572015-08-04 09:47:08 +02001397 case LYS_LEAF:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001398 lys_type_dup(module, node->parent, &(leaf->type), &(leaf_orig->type), unres);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001399 leaf->units = lydict_insert(module->ctx, leaf_orig->units, 0);
1400
1401 if (leaf_orig->dflt) {
1402 leaf->dflt = lydict_insert(ctx, leaf_orig->dflt, 0);
Radek Krejci1d82ef62015-08-07 14:44:40 +02001403 unres_add_str(module, unres, &leaf->type, UNRES_TYPE_DFLT, leaf->dflt, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001404 }
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001405
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001406 leaf->must_size = leaf_orig->must_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001407 leaf->must = lys_restr_dup(ctx, leaf_orig->must, leaf->must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001408 for (i = 0; i < leaf->must_size; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001409 unres_add_node(module, unres, &leaf->must[i], UNRES_MUST, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001410 }
Radek Krejci00768f42015-06-18 17:04:04 +02001411
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001412 if (leaf_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001413 leaf->when = lys_when_dup(ctx, leaf_orig->when);
1414 unres_add_node(module, unres, leaf->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001415 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001416 break;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001417
Radek Krejci76512572015-08-04 09:47:08 +02001418 case LYS_LEAFLIST:
Radek Krejci1d82ef62015-08-07 14:44:40 +02001419 lys_type_dup(module, node->parent, &(llist->type), &(llist_orig->type), unres);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001420 llist->units = lydict_insert(module->ctx, llist_orig->units, 0);
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001421
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001422 llist->min = llist_orig->min;
1423 llist->max = llist_orig->max;
1424
1425 llist->must_size = llist_orig->must_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001426 llist->must = lys_restr_dup(ctx, llist_orig->must, llist->must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001427 for (i = 0; i < llist->must_size; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001428 unres_add_node(module, unres, &llist->must[i], UNRES_MUST, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001429 }
Radek Krejci00768f42015-06-18 17:04:04 +02001430
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001431 if (llist_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001432 llist->when = lys_when_dup(ctx, llist_orig->when);
1433 unres_add_node(module, unres, llist->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001434 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001435 break;
1436
Radek Krejci76512572015-08-04 09:47:08 +02001437 case LYS_LIST:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001438 list->min = list_orig->min;
1439 list->max = list_orig->max;
1440
1441 list->must_size = list_orig->must_size;
1442 list->tpdf_size = list_orig->tpdf_size;
1443 list->keys_size = list_orig->keys_size;
1444 list->unique_size = list_orig->unique_size;
1445
Radek Krejci1d82ef62015-08-07 14:44:40 +02001446 list->must = lys_restr_dup(ctx, list_orig->must, list->must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001447 for (i = 0; i < list->must_size; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001448 unres_add_node(module, unres, &list->must[i], UNRES_MUST, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001449 }
1450
Radek Krejci1d82ef62015-08-07 14:44:40 +02001451 list->tpdf = lys_tpdf_dup(module, node->parent, list_orig->tpdf, list->tpdf_size, unres);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001452
1453 if (list->keys_size) {
1454 list->keys = calloc(list->keys_size, sizeof *list->keys);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001455
1456 /* we managed to resolve it before, resolve it again manually */
1457 if (list_orig->keys[0]) {
1458 for (i = 0; i < list->keys_size; ++i) {
Radek Krejcib8048692015-08-05 13:36:34 +02001459 list->keys[i] = (struct lys_node_leaf *)resolve_child((struct lys_node *)list,
Radek Krejci76512572015-08-04 09:47:08 +02001460 list_orig->keys[i]->name, 0, LYS_LEAF);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001461 assert(list->keys[i]);
1462 }
1463 /* it was not resolved yet, add unres copy */
1464 } else {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001465 if (unres_dup(module, unres, list_orig, UNRES_LIST_KEYS, list)) {
Michal Vaskod23ce592015-08-06 09:55:37 +02001466 LOGINT;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001467 lys_node_free(retval);
Michal Vaskod23ce592015-08-06 09:55:37 +02001468 return NULL;
1469 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001470 }
1471 }
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001472
1473 list->unique = calloc(list->unique_size, sizeof *list->unique);
1474 if (list_orig->unique) {
1475 for (i = 0; i < list->unique_size; ++i) {
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001476 list->unique[i].leafs = calloc(list->unique[i].leafs_size, sizeof *list->unique[i].leafs);
1477 for (j = 0; j < list->unique[i].leafs_size; j++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001478 list->unique[i].leafs[j] = lys_uniq_find(list, list_orig->unique[i].leafs[j]);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001479 }
1480 }
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001481 } else {
1482 for (i = 0; i < list->unique_size; ++i) {
1483 /* HACK for unres */
Radek Krejcib8048692015-08-05 13:36:34 +02001484 list->unique[i].leafs = (struct lys_node_leaf **)list;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001485 unres_dup(module, unres, &list_orig->unique[i], UNRES_LIST_UNIQ, &list->unique[i]);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001486 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001487 }
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001488
1489 if (list_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001490 list->when = lys_when_dup(ctx, list_orig->when);
1491 unres_add_node(module, unres, list->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001492 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001493 break;
1494
Radek Krejci76512572015-08-04 09:47:08 +02001495 case LYS_ANYXML:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001496 anyxml->must_size = anyxml_orig->must_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001497 anyxml->must = lys_restr_dup(ctx, anyxml_orig->must, anyxml->must_size);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001498 for (i = 0; i < anyxml->must_size; ++i) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001499 unres_add_node(module, unres, &anyxml->must[i], UNRES_MUST, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001500 }
1501
1502 if (anyxml_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001503 anyxml->when = lys_when_dup(ctx, anyxml_orig->when);
1504 unres_add_node(module, unres, anyxml->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001505 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001506 break;
1507
Radek Krejci76512572015-08-04 09:47:08 +02001508 case LYS_USES:
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001509 uses->grp = uses_orig->grp;
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001510
1511 if (uses_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001512 uses->when = lys_when_dup(ctx, uses_orig->when);
1513 unres_add_node(module, unres, uses->when, UNRES_WHEN, (struct lys_node *)uses, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001514 }
1515
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001516 uses->refine_size = uses_orig->refine_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001517 uses->refine = lys_refine_dup(module, uses_orig->refine, uses_orig->refine_size, uses, unres);
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001518 uses->augment_size = uses_orig->augment_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001519 uses->augment = lys_augment_dup(module, (struct lys_node *)uses, uses_orig->augment, uses_orig->augment_size, unres);
Michal Vaskof8c128d2015-08-06 15:25:28 +02001520 if (!uses->child) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001521 unres_add_node(module, unres, uses, UNRES_USES, NULL, 0);
Michal Vaskof8c128d2015-08-06 15:25:28 +02001522 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001523 break;
1524
Radek Krejci76512572015-08-04 09:47:08 +02001525 case LYS_CASE:
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001526 if (cs_orig->when) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001527 cs->when = lys_when_dup(ctx, cs_orig->when);
1528 unres_add_node(module, unres, cs->when, UNRES_WHEN, retval, 0);
Michal Vaskoc3d9f8c2015-07-31 14:37:24 +02001529 }
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001530 break;
1531
Radek Krejci76512572015-08-04 09:47:08 +02001532 case LYS_GROUPING:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001533 grp->tpdf_size = grp_orig->tpdf_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001534 grp->tpdf = lys_tpdf_dup(module, node->parent, grp_orig->tpdf, grp->tpdf_size, unres);
Radek Krejcid12f57b2015-08-06 10:43:39 +02001535 break;
1536
Radek Krejci76512572015-08-04 09:47:08 +02001537 case LYS_RPC:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001538 rpc->tpdf_size = rpc_orig->tpdf_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001539 rpc->tpdf = lys_tpdf_dup(module, node->parent, rpc_orig->tpdf, rpc->tpdf_size, unres);
Radek Krejcid12f57b2015-08-06 10:43:39 +02001540 break;
1541
Radek Krejci76512572015-08-04 09:47:08 +02001542 case LYS_INPUT:
1543 case LYS_OUTPUT:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001544 io->tpdf_size = io_orig->tpdf_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001545 io->tpdf = lys_tpdf_dup(module, node->parent, io_orig->tpdf, io->tpdf_size, unres);
Radek Krejcid12f57b2015-08-06 10:43:39 +02001546 break;
1547
Radek Krejci76512572015-08-04 09:47:08 +02001548 case LYS_NOTIF:
Radek Krejcid12f57b2015-08-06 10:43:39 +02001549 ntf->tpdf_size = ntf_orig->tpdf_size;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001550 ntf->tpdf = lys_tpdf_dup(module, node->parent, ntf_orig->tpdf, ntf->tpdf_size, unres);
Radek Krejcia01e5432015-06-16 10:35:25 +02001551 break;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001552
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001553 default:
Radek Krejci00768f42015-06-18 17:04:04 +02001554 /* LY_NODE_AUGMENT */
Michal Vaskod23ce592015-08-06 09:55:37 +02001555 LOGINT;
Radek Krejci1d82ef62015-08-07 14:44:40 +02001556 lys_node_free(retval);
Michal Vaskod23ce592015-08-06 09:55:37 +02001557 return NULL;
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001558 }
1559
1560 return retval;
Radek Krejci8bc9ca02015-06-04 15:52:46 +02001561}
1562
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001563API void
Radek Krejcib8048692015-08-05 13:36:34 +02001564lys_free(struct lys_module *module)
Radek Krejciefaeba32015-05-27 14:30:57 +02001565{
Radek Krejcidce51452015-06-16 15:20:08 +02001566 struct ly_ctx *ctx;
1567 int i;
1568
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001569 if (!module) {
1570 return;
1571 }
Radek Krejciefaeba32015-05-27 14:30:57 +02001572
Radek Krejcidce51452015-06-16 15:20:08 +02001573 /* remove schema from the context */
1574 ctx = module->ctx;
1575 if (ctx->models.used) {
1576 for (i = 0; i < ctx->models.used; i++) {
1577 if (ctx->models.list[i] == module) {
1578 /* replace the position in the list by the last module in the list */
1579 ctx->models.used--;
1580 ctx->models.list[i] = ctx->models.list[ctx->models.used];
1581 ctx->models.list[ctx->models.used] = NULL;
1582 /* we are done */
1583 break;
1584 }
1585 }
1586 }
1587
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001588 /* common part with struct ly_submodule */
1589 module_free_common(module);
Radek Krejciefaeba32015-05-27 14:30:57 +02001590
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001591 /* specific items to free */
1592 lydict_remove(module->ctx, module->ns);
1593 lydict_remove(module->ctx, module->prefix);
Radek Krejci6793db02015-05-22 17:49:54 +02001594
Radek Krejci6e4ffbb2015-06-16 10:34:41 +02001595 free(module);
Radek Krejcida04f4a2015-05-21 12:54:09 +02001596}
Radek Krejci7e97c352015-06-19 16:26:34 +02001597
1598/*
1599 * op: 1 - enable, 0 - disable
1600 */
1601static int
Radek Krejci1d82ef62015-08-07 14:44:40 +02001602lys_features_change(struct lys_module *module, const char *name, int op)
Radek Krejci7e97c352015-06-19 16:26:34 +02001603{
1604 int all = 0;
1605 int i, j, k;
1606
1607 if (!module || !name || !strlen(name)) {
1608 return EXIT_FAILURE;
1609 }
1610
1611 if (!strcmp(name, "*")) {
1612 /* enable all */
1613 all = 1;
1614 }
1615
1616 /* module itself */
1617 for (i = 0; i < module->features_size; i++) {
1618 if (all || !strcmp(module->features[i].name, name)) {
1619 if (op) {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001620 module->features[i].flags |= LYS_FENABLED;
Radek Krejci7e97c352015-06-19 16:26:34 +02001621 /* enable referenced features (recursion) */
1622 for (k = 0; k < module->features[i].features_size; k++) {
Radek Krejci1d82ef62015-08-07 14:44:40 +02001623 lys_features_change(module->features[i].features[k]->module,
Radek Krejci7e97c352015-06-19 16:26:34 +02001624 module->features[i].features[k]->name, op);
1625 }
1626 } else {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001627 module->features[i].flags &= ~LYS_FENABLED;
Radek Krejci7e97c352015-06-19 16:26:34 +02001628 }
1629 if (!all) {
1630 return EXIT_SUCCESS;
1631 }
1632 }
1633 }
1634
1635 /* submodules */
1636 for (j = 0; j < module->inc_size; j++) {
1637 for (i = 0; i < module->inc[j].submodule->features_size; i++) {
1638 if (all || !strcmp(module->inc[j].submodule->features[i].name, name)) {
1639 if (op) {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001640 module->inc[j].submodule->features[i].flags |= LYS_FENABLED;
Radek Krejci7e97c352015-06-19 16:26:34 +02001641 } else {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001642 module->inc[j].submodule->features[i].flags &= ~LYS_FENABLED;
Radek Krejci7e97c352015-06-19 16:26:34 +02001643 }
1644 if (!all) {
1645 return EXIT_SUCCESS;
1646 }
1647 }
1648 }
1649 }
1650
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001651 /* TODO submodules of submodules ... */
1652
Radek Krejci7e97c352015-06-19 16:26:34 +02001653 if (all) {
1654 return EXIT_SUCCESS;
1655 } else {
1656 return EXIT_FAILURE;
1657 }
1658}
1659
1660API int
Radek Krejcib8048692015-08-05 13:36:34 +02001661lys_features_enable(struct lys_module *module, const char *feature)
Radek Krejci7e97c352015-06-19 16:26:34 +02001662{
Radek Krejci1d82ef62015-08-07 14:44:40 +02001663 return lys_features_change(module, feature, 1);
Radek Krejci7e97c352015-06-19 16:26:34 +02001664}
1665
1666API int
Radek Krejcib8048692015-08-05 13:36:34 +02001667lys_features_disable(struct lys_module *module, const char *feature)
Radek Krejci7e97c352015-06-19 16:26:34 +02001668{
Radek Krejci1d82ef62015-08-07 14:44:40 +02001669 return lys_features_change(module, feature, 0);
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001670}
1671
1672API int
Radek Krejcib8048692015-08-05 13:36:34 +02001673lys_features_state(struct lys_module *module, const char *feature)
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001674{
1675 int i, j;
1676
1677 if (!module || !feature) {
1678 return -1;
1679 }
1680
1681 /* search for the specified feature */
1682 /* module itself */
1683 for (i = 0; i < module->features_size; i++) {
1684 if (!strcmp(feature, module->features[i].name)) {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001685 if (module->features[i].flags & LYS_FENABLED) {
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001686 return 1;
1687 } else {
1688 return 0;
1689 }
1690 }
1691 }
1692
1693 /* submodules */
1694 for (j = 0; j < module->inc_size; j++) {
1695 for (i = 0; i < module->inc[j].submodule->features_size; i++) {
1696 if (!strcmp(feature, module->inc[j].submodule->features[i].name)) {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001697 if (module->inc[j].submodule->features[i].flags & LYS_FENABLED) {
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001698 return 1;
1699 } else {
1700 return 0;
1701 }
1702 }
1703 }
1704 }
1705
1706 /* TODO submodules of submodules ... */
1707
1708 /* feature definition not found */
1709 return -1;
Radek Krejci7e97c352015-06-19 16:26:34 +02001710}
Michal Vasko2367e7c2015-07-07 11:33:44 +02001711
Radek Krejci96a10da2015-07-30 11:00:14 +02001712API const char **
Radek Krejcib8048692015-08-05 13:36:34 +02001713lys_features_list(struct lys_module *module, uint8_t **states)
Michal Vasko2367e7c2015-07-07 11:33:44 +02001714{
Radek Krejci96a10da2015-07-30 11:00:14 +02001715 const char **result = NULL;
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001716 int i, j;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001717 unsigned int count;
1718
1719 if (!module) {
1720 return NULL;
1721 }
1722
1723 count = module->features_size;
1724 for (i = 0; i < module->inc_size; i++) {
1725 count += module->inc[i].submodule->features_size;
1726 }
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001727 result = malloc((count + 1) * sizeof *result);
1728 if (states) {
1729 *states = malloc((count + 1) * sizeof **states);
Michal Vasko2367e7c2015-07-07 11:33:44 +02001730 }
Michal Vasko2367e7c2015-07-07 11:33:44 +02001731 count = 0;
1732
1733 /* module itself */
1734 for (i = 0; i < module->features_size; i++) {
Radek Krejci96a10da2015-07-30 11:00:14 +02001735 result[count] = module->features[i].name;
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001736 if (states) {
Radek Krejci1574a8d2015-08-03 14:16:52 +02001737 if (module->features[i].flags & LYS_FENABLED) {
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001738 (*states)[count] = 1;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001739 } else {
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001740 (*states)[count] = 0;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001741 }
1742 }
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001743 count++;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001744 }
1745
1746 /* submodules */
1747 for (j = 0; j < module->inc_size; j++) {
1748 for (i = 0; i < module->inc[j].submodule->features_size; i++) {
Radek Krejci96a10da2015-07-30 11:00:14 +02001749 result[count] = module->inc[j].submodule->features[i].name;
Radek Krejci1574a8d2015-08-03 14:16:52 +02001750 if (module->inc[j].submodule->features[i].flags & LYS_FENABLED) {
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001751 (*states)[count] = 1;
1752 } else {
1753 (*states)[count] = 0;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001754 }
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001755 count++;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001756 }
1757 }
1758
Radek Krejcie98bb4b2015-07-30 14:21:41 +02001759 /* TODO submodules of submodules ... */
1760
1761 /* terminating NULL byte */
Michal Vasko2367e7c2015-07-07 11:33:44 +02001762 result[count] = NULL;
Michal Vasko2367e7c2015-07-07 11:33:44 +02001763
1764 return result;
1765}
Radek Krejcib20c62d2015-07-07 17:07:14 +02001766
1767API struct lyd_node *
Radek Krejci25b9fd32015-08-10 15:06:07 +02001768lyd_parse(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options)
Radek Krejcib20c62d2015-07-07 17:07:14 +02001769{
1770 if (!ctx || !data) {
1771 LOGERR(LY_EINVAL, "%s: Invalid parameter.", __func__);
1772 return NULL;
1773 }
1774
1775 switch (format) {
Radek Krejcia9167ef2015-08-03 11:01:11 +02001776 case LYD_XML:
Radek Krejci25b9fd32015-08-10 15:06:07 +02001777 return xml_read_data(ctx, data, options);
Radek Krejcia9167ef2015-08-03 11:01:11 +02001778 case LYD_JSON:
Radek Krejcib20c62d2015-07-07 17:07:14 +02001779 default:
1780 /* TODO */
1781 return NULL;
1782 }
1783
1784 return NULL;
1785}
1786
Radek Krejci0e1d1a62015-07-31 11:17:01 +02001787API void
Radek Krejci912da452015-07-29 14:10:06 +02001788lyd_free(struct lyd_node *node)
Radek Krejcib20c62d2015-07-07 17:07:14 +02001789{
1790 struct lyd_node *next, *child;
1791
Radek Krejci52f791c2015-07-15 11:14:17 +02001792 if (!node) {
1793 return;
1794 }
1795
Radek Krejci76512572015-08-04 09:47:08 +02001796 if (!(node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYXML))) {
Radek Krejcie4748472015-07-08 18:00:22 +02001797 /* free children */
1798 LY_TREE_FOR_SAFE(node->child, next, child) {
Radek Krejci912da452015-07-29 14:10:06 +02001799 lyd_free(child);
Radek Krejcie4748472015-07-08 18:00:22 +02001800 }
Radek Krejci76512572015-08-04 09:47:08 +02001801 } else if (node->schema->nodetype == LYS_ANYXML) {
Radek Krejci9566b092015-07-31 11:18:15 +02001802 lyxml_free_elem(node->schema->module->ctx, ((struct lyd_node_anyxml *)node)->value);
Radek Krejcie4748472015-07-08 18:00:22 +02001803 } else {
1804 /* free value */
1805 switch(((struct lyd_node_leaf *)node)->value_type) {
1806 case LY_TYPE_BINARY:
1807 case LY_TYPE_STRING:
1808 lydict_remove(node->schema->module->ctx, ((struct lyd_node_leaf *)node)->value.string);
1809 break;
Radek Krejci3e3affe2015-07-09 15:38:40 +02001810 case LY_TYPE_BITS:
1811 if (((struct lyd_node_leaf *)node)->value.bit) {
1812 free(((struct lyd_node_leaf *)node)->value.bit);
1813 }
1814 break;
Radek Krejcie4748472015-07-08 18:00:22 +02001815 default:
Radek Krejci7511f402015-07-10 09:56:30 +02001816 /* TODO nothing needed : LY_TYPE_BOOL, LY_TYPE_DEC64*/
Radek Krejcie4748472015-07-08 18:00:22 +02001817 break;
1818 }
Radek Krejcib20c62d2015-07-07 17:07:14 +02001819 }
1820
1821 if (node->prev->next) {
1822 node->prev->next = node->next;
1823 } else if (node->parent) {
1824 /* first node */
1825 node->parent->child = node->next;
1826 }
1827 if (node->next) {
1828 node->next->prev = node->prev;
1829 }
1830
1831 free(node);
1832}
Michal Vaskof54f2f82015-07-17 13:12:05 +02001833
Radek Krejci2dbed4c2015-07-20 13:02:04 +02001834API int
Radek Krejci9566b092015-07-31 11:18:15 +02001835lyd_is_last(struct lyd_node *node)
Radek Krejci2dbed4c2015-07-20 13:02:04 +02001836{
1837 struct lyd_node *n;
1838
1839 if (!node->next) {
1840 return 1;
1841 }
1842
1843 for (n = node->next; n; n = n->next) {
1844 switch (n->schema->nodetype) {
Radek Krejci76512572015-08-04 09:47:08 +02001845 case LYS_LIST:
Radek Krejci2dbed4c2015-07-20 13:02:04 +02001846 if (!((struct lyd_node_list *)n)->lprev) {
1847 return 0;
1848 }
1849 break;
Radek Krejci76512572015-08-04 09:47:08 +02001850 case LYS_LEAFLIST:
Radek Krejci2dbed4c2015-07-20 13:02:04 +02001851 if (!((struct lyd_node_leaflist *)n)->lprev) {
1852 return 0;
1853 }
1854 break;
1855 default:
1856 return 0;
1857 }
1858 }
1859 return 1;
1860}