blob: 0d58a4da4b9c01e3d18af5c48df865a5ca617ac0 [file] [log] [blame]
Radek Krejci19a96102018-11-15 13:38:09 +01001/**
2 * @file tree_schema.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Schema tree implementation
5 *
6 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#include "common.h"
16
Radek Krejci19a96102018-11-15 13:38:09 +010017#include "libyang.h"
18#include "context.h"
19#include "tree_schema_internal.h"
20#include "xpath.h"
21
22#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, &(ARRAY)[c__]);}LY_ARRAY_FREE(ARRAY);}
23#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
Radek Krejci19a96102018-11-15 13:38:09 +010024#define FREE_STRINGS(CTX, ARRAY) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__]);}LY_ARRAY_FREE(ARRAY);}
25
26static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
27static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
28
29static void
30lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
31{
32 struct lysp_stmt *child, *next;
33
34 FREE_STRING(ctx, stmt->stmt);
35 FREE_STRING(ctx, stmt->arg);
36
37 LY_LIST_FOR_SAFE(stmt->child, next, child) {
38 lysp_stmt_free(ctx, child);
39 }
40
41 free(stmt);
42}
43
44static void
45lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
46{
47 struct lysp_stmt *stmt, *next;
48
49 FREE_STRING(ctx, ext->name);
50 FREE_STRING(ctx, ext->argument);
51
52 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
53 lysp_stmt_free(ctx, stmt);
54 }
55}
56
57static void
58lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
59{
60 /* imported module is freed directly from the context's list */
61 FREE_STRING(ctx, import->name);
62 FREE_STRING(ctx, import->prefix);
63 FREE_STRING(ctx, import->dsc);
64 FREE_STRING(ctx, import->ref);
65 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
66}
67
68static void
69lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
70{
71 if (include->submodule) {
72 lysp_module_free(include->submodule);
73 }
74 FREE_STRING(ctx, include->name);
75 FREE_STRING(ctx, include->dsc);
76 FREE_STRING(ctx, include->ref);
77 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
78}
79
80static void
81lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
82{
83 FREE_STRING(ctx, rev->dsc);
84 FREE_STRING(ctx, rev->ref);
85 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
86}
87
88static void
89lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
90{
91 FREE_STRING(ctx, ext->name);
92 FREE_STRING(ctx, ext->argument);
93 FREE_STRING(ctx, ext->dsc);
94 FREE_STRING(ctx, ext->ref);
95 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
96}
97
98static void
99lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
100{
101 FREE_STRING(ctx, feat->name);
102 FREE_STRINGS(ctx, feat->iffeatures);
103 FREE_STRING(ctx, feat->dsc);
104 FREE_STRING(ctx, feat->ref);
105 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
106}
107
108static void
109lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
110{
111 FREE_STRING(ctx, ident->name);
112 FREE_STRINGS(ctx, ident->iffeatures);
113 FREE_STRINGS(ctx, ident->bases);
114 FREE_STRING(ctx, ident->dsc);
115 FREE_STRING(ctx, ident->ref);
116 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
117}
118
119static void
120lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
121{
122 FREE_STRING(ctx, restr->arg);
123 FREE_STRING(ctx, restr->emsg);
124 FREE_STRING(ctx, restr->eapptag);
125 FREE_STRING(ctx, restr->dsc);
126 FREE_STRING(ctx, restr->ref);
127 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
128}
129
130static void
131lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
132{
133 FREE_STRING(ctx, item->name);
134 FREE_STRING(ctx, item->dsc);
135 FREE_STRING(ctx, item->ref);
136 FREE_STRINGS(ctx, item->iffeatures);
137 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
138}
139
Radek Krejcicdfecd92018-11-26 11:27:32 +0100140void lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type);
Radek Krejci19a96102018-11-15 13:38:09 +0100141static void
142lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
143{
144 FREE_STRING(ctx, type->name);
145 FREE_MEMBER(ctx, type->range, lysp_restr_free);
146 FREE_MEMBER(ctx, type->length, lysp_restr_free);
147 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
148 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
149 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
150 FREE_STRING(ctx, type->path);
151 FREE_STRINGS(ctx, type->bases);
152 FREE_ARRAY(ctx, type->types, lysp_type_free);
153 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
154 if (type->compiled) {
155 lysc_type_free(ctx, type->compiled);
156 }
157}
158
159static void
160lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
161{
162 FREE_STRING(ctx, tpdf->name);
163 FREE_STRING(ctx, tpdf->units);
164 FREE_STRING(ctx, tpdf->dflt);
165 FREE_STRING(ctx, tpdf->dsc);
166 FREE_STRING(ctx, tpdf->ref);
167 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
168
169 lysp_type_free(ctx, &tpdf->type);
170
171}
172
173static void
174lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
175{
176 struct lysp_node *node, *next;
177
178 FREE_ARRAY(ctx, inout->musts, lysp_restr_free);
179 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
180 FREE_ARRAY(ctx, inout->groupings, lysp_grp_free);
181 LY_LIST_FOR_SAFE(inout->data, next, node) {
182 lysp_node_free(ctx, node);
183 }
184 FREE_ARRAY(ctx, inout->exts, lysp_ext_instance_free);
185
186}
187
188static void
189lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
190{
191 FREE_STRING(ctx, action->name);
192 FREE_STRING(ctx, action->dsc);
193 FREE_STRING(ctx, action->ref);
194 FREE_STRINGS(ctx, action->iffeatures);
195 FREE_ARRAY(ctx, action->typedefs, lysp_tpdf_free);
196 FREE_ARRAY(ctx, action->groupings, lysp_grp_free);
197 FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
198 FREE_MEMBER(ctx, action->output, lysp_action_inout_free);
199 FREE_ARRAY(ctx, action->exts, lysp_ext_instance_free);
200}
201
202static void
203lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
204{
205 struct lysp_node *node, *next;
206
207 FREE_STRING(ctx, notif->name);
208 FREE_STRING(ctx, notif->dsc);
209 FREE_STRING(ctx, notif->ref);
210 FREE_STRINGS(ctx, notif->iffeatures);
211 FREE_ARRAY(ctx, notif->musts, lysp_restr_free);
212 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
213 FREE_ARRAY(ctx, notif->groupings, lysp_grp_free);
214 LY_LIST_FOR_SAFE(notif->data, next, node) {
215 lysp_node_free(ctx, node);
216 }
217 FREE_ARRAY(ctx, notif->exts, lysp_ext_instance_free);
218}
219
220static void
221lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
222{
223 struct lysp_node *node, *next;
224
225 FREE_STRING(ctx, grp->name);
226 FREE_STRING(ctx, grp->dsc);
227 FREE_STRING(ctx, grp->ref);
228 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
229 FREE_ARRAY(ctx, grp->groupings, lysp_grp_free);
230 LY_LIST_FOR_SAFE(grp->data, next, node) {
231 lysp_node_free(ctx, node);
232 }
233 FREE_ARRAY(ctx, grp->actions, lysp_action_free);
234 FREE_ARRAY(ctx, grp->notifs, lysp_notif_free);
235 FREE_ARRAY(ctx, grp->exts, lysp_ext_instance_free);
236}
237
238static void
239lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
240{
241 FREE_STRING(ctx, when->cond);
242 FREE_STRING(ctx, when->dsc);
243 FREE_STRING(ctx, when->ref);
244 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
245}
246
247static void
248lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
249{
250 struct lysp_node *node, *next;
251
252 FREE_STRING(ctx, augment->nodeid);
253 FREE_STRING(ctx, augment->dsc);
254 FREE_STRING(ctx, augment->ref);
255 FREE_MEMBER(ctx, augment->when, lysp_when_free);
256 FREE_STRINGS(ctx, augment->iffeatures);
257 LY_LIST_FOR_SAFE(augment->child, next, node) {
258 lysp_node_free(ctx, node);
259 }
260 FREE_ARRAY(ctx, augment->actions, lysp_action_free);
261 FREE_ARRAY(ctx, augment->notifs, lysp_notif_free);
262 FREE_ARRAY(ctx, augment->exts, lysp_ext_instance_free);
263}
264
265static void
266lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
267{
268 struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
269 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
270
271 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
272 switch(d->mod) {
273 case LYS_DEV_NOT_SUPPORTED:
274 /* nothing to do */
275 break;
276 case LYS_DEV_ADD:
277 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
278 FREE_STRING(ctx, add->units);
279 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
280 FREE_STRINGS(ctx, add->uniques);
281 FREE_STRINGS(ctx, add->dflts);
282 break;
283 case LYS_DEV_REPLACE:
284 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
285 FREE_STRING(ctx, rpl->units);
286 FREE_STRING(ctx, rpl->dflt);
287 break;
288 default:
289 LOGINT(ctx);
290 break;
291 }
292}
293
294static void
295lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
296{
297 struct lysp_deviate *next, *iter;
298
299 FREE_STRING(ctx, dev->nodeid);
300 FREE_STRING(ctx, dev->dsc);
301 FREE_STRING(ctx, dev->ref);
302 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
303 lysp_deviate_free(ctx, iter);
304 free(iter);
305 }
306 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
307}
308
309static void
310lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
311{
312 FREE_STRING(ctx, ref->nodeid);
313 FREE_STRING(ctx, ref->dsc);
314 FREE_STRING(ctx, ref->ref);
315 FREE_STRINGS(ctx, ref->iffeatures);
316 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
317 FREE_STRING(ctx, ref->presence);
318 FREE_STRINGS(ctx, ref->dflts);
319 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
320}
321
322static void
323lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
324{
325 struct lysp_node *child, *next;
326
327 FREE_STRING(ctx, node->name);
328 FREE_STRING(ctx, node->dsc);
329 FREE_STRING(ctx, node->ref);
330 FREE_MEMBER(ctx, node->when, lysp_when_free);
331 FREE_STRINGS(ctx, node->iffeatures);
332 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
333
334 switch(node->nodetype) {
335 case LYS_CONTAINER:
336 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, lysp_restr_free);
337 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
338 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, lysp_tpdf_free);
339 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, lysp_grp_free);
340 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
341 lysp_node_free(ctx, child);
342 }
343 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, lysp_action_free);
344 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, lysp_notif_free);
345 break;
346 case LYS_LEAF:
347 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, lysp_restr_free);
348 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
349 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
350 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
351 break;
352 case LYS_LEAFLIST:
353 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, lysp_restr_free);
354 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
355 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
356 FREE_STRINGS(ctx, ((struct lysp_node_leaflist*)node)->dflts);
357 break;
358 case LYS_LIST:
359 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, lysp_restr_free);
360 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
361 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, lysp_tpdf_free);
362 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, lysp_grp_free);
363 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
364 lysp_node_free(ctx, child);
365 }
366 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, lysp_action_free);
367 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, lysp_notif_free);
368 FREE_STRINGS(ctx, ((struct lysp_node_list*)node)->uniques);
369 break;
370 case LYS_CHOICE:
371 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
372 lysp_node_free(ctx, child);
373 }
374 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
375 break;
376 case LYS_CASE:
377 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
378 lysp_node_free(ctx, child);
379 }
380 break;
381 case LYS_ANYDATA:
382 case LYS_ANYXML:
383 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, lysp_restr_free);
384 break;
385 case LYS_USES:
386 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, lysp_refine_free);
387 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, lysp_augment_free);
388 break;
389 default:
390 LOGINT(ctx);
391 }
392
393 free(node);
394}
395
396API void
397lysp_module_free(struct lysp_module *module)
398{
399 struct ly_ctx *ctx;
400 struct lysp_node *node, *next;
401
402 LY_CHECK_ARG_RET(NULL, module,);
403 ctx = module->ctx;
404
405 FREE_STRING(ctx, module->name);
406 FREE_STRING(ctx, module->filepath);
407 FREE_STRING(ctx, module->ns); /* or belongs-to */
408 FREE_STRING(ctx, module->prefix);
409
410 FREE_ARRAY(ctx, module->imports, lysp_import_free);
411 FREE_ARRAY(ctx, module->includes, lysp_include_free);
412
413 FREE_STRING(ctx, module->org);
414 FREE_STRING(ctx, module->contact);
415 FREE_STRING(ctx, module->dsc);
416 FREE_STRING(ctx, module->ref);
417
418 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
419 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
420 FREE_ARRAY(ctx, module->features, lysp_feature_free);
421 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
422 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
423 FREE_ARRAY(ctx, module->groupings, lysp_grp_free);
424 LY_LIST_FOR_SAFE(module->data, next, node) {
425 lysp_node_free(ctx, node);
426 }
427 FREE_ARRAY(ctx, module->augments, lysp_augment_free);
428 FREE_ARRAY(ctx, module->rpcs, lysp_action_free);
429 FREE_ARRAY(ctx, module->notifs, lysp_notif_free);
430 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
431 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
432
433 free(module);
434}
435
436static void
437lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
438{
439 FREE_STRING(ctx, ext->argument);
440 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
441}
442
443static void
444lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
445{
446 LY_ARRAY_FREE(iff->features);
447 free(iff->expr);
448}
449
450static void
Radek Krejci58d171e2018-11-23 13:50:55 +0100451lysc_when_free(struct ly_ctx *ctx, struct lysc_when *w)
452{
453 lyxp_expr_free(ctx, w->cond);
Radek Krejcic8b31002019-01-08 10:24:45 +0100454 FREE_STRING(ctx, w->dsc);
455 FREE_STRING(ctx, w->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100456 FREE_ARRAY(ctx, w->exts, lysc_ext_instance_free);
457}
458
459static void
460lysc_must_free(struct ly_ctx *ctx, struct lysc_must *must)
461{
462 lyxp_expr_free(ctx, must->cond);
463 FREE_STRING(ctx, must->emsg);
464 FREE_STRING(ctx, must->eapptag);
Radek Krejcic8b31002019-01-08 10:24:45 +0100465 FREE_STRING(ctx, must->dsc);
466 FREE_STRING(ctx, must->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100467 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
468}
469
470static void
Radek Krejci19a96102018-11-15 13:38:09 +0100471lysc_import_free(struct ly_ctx *ctx, struct lysc_import *import)
472{
473 /* imported module is freed directly from the context's list */
474 FREE_STRING(ctx, import->prefix);
475 FREE_ARRAY(ctx, import->exts, lysc_ext_instance_free);
476}
477
478static void
479lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident)
480{
481 FREE_STRING(ctx, ident->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100482 FREE_STRING(ctx, ident->dsc);
483 FREE_STRING(ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100484 FREE_ARRAY(ctx, ident->iffeatures, lysc_iffeature_free);
485 LY_ARRAY_FREE(ident->derived);
486 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
487}
488
489static void
490lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat)
491{
492 FREE_STRING(ctx, feat->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100493 FREE_STRING(ctx, feat->dsc);
494 FREE_STRING(ctx, feat->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100495 FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
496 LY_ARRAY_FREE(feat->depfeatures);
497 FREE_ARRAY(ctx, feat->exts, lysc_ext_instance_free);
498}
499
500static void
501lysc_range_free(struct ly_ctx *ctx, struct lysc_range *range)
502{
503 LY_ARRAY_FREE(range->parts);
504 FREE_STRING(ctx, range->eapptag);
505 FREE_STRING(ctx, range->emsg);
Radek Krejcic8b31002019-01-08 10:24:45 +0100506 FREE_STRING(ctx, range->dsc);
507 FREE_STRING(ctx, range->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100508 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
509}
510
511static void
512lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern)
513{
514 if (--(*pattern)->refcount) {
515 return;
516 }
517 pcre_free((*pattern)->expr);
518 pcre_free_study((*pattern)->expr_extra);
519 FREE_STRING(ctx, (*pattern)->eapptag);
520 FREE_STRING(ctx, (*pattern)->emsg);
Radek Krejcic8b31002019-01-08 10:24:45 +0100521 FREE_STRING(ctx, (*pattern)->dsc);
522 FREE_STRING(ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100523 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
524 free(*pattern);
525}
526
527static void
528lysc_enum_item_free(struct ly_ctx *ctx, struct lysc_type_enum_item *item)
529{
530 FREE_STRING(ctx, item->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100531 FREE_STRING(ctx, item->dsc);
532 FREE_STRING(ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100533 FREE_ARRAY(ctx, item->iffeatures, lysc_iffeature_free);
534 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
535}
536
Radek Krejcia3045382018-11-22 14:30:31 +0100537static void
538lysc_type2_free(struct ly_ctx *ctx, struct lysc_type **type)
539{
540 lysc_type_free(ctx, *type);
541}
Radek Krejcicdfecd92018-11-26 11:27:32 +0100542void
Radek Krejci19a96102018-11-15 13:38:09 +0100543lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
544{
545 if (--type->refcount) {
546 return;
547 }
548 switch(type->basetype) {
549 case LY_TYPE_BINARY:
550 FREE_MEMBER(ctx, ((struct lysc_type_bin*)type)->length, lysc_range_free);
551 break;
552 case LY_TYPE_BITS:
553 FREE_ARRAY(ctx, (struct lysc_type_enum_item*)((struct lysc_type_bits*)type)->bits, lysc_enum_item_free);
554 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100555 case LY_TYPE_DEC64:
556 FREE_MEMBER(ctx, ((struct lysc_type_dec*)type)->range, lysc_range_free);
557 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100558 case LY_TYPE_STRING:
559 FREE_MEMBER(ctx, ((struct lysc_type_str*)type)->length, lysc_range_free);
560 FREE_ARRAY(ctx, ((struct lysc_type_str*)type)->patterns, lysc_pattern_free);
561 break;
562 case LY_TYPE_ENUM:
563 FREE_ARRAY(ctx, ((struct lysc_type_enum*)type)->enums, lysc_enum_item_free);
564 break;
565 case LY_TYPE_INT8:
566 case LY_TYPE_UINT8:
567 case LY_TYPE_INT16:
568 case LY_TYPE_UINT16:
569 case LY_TYPE_INT32:
570 case LY_TYPE_UINT32:
571 case LY_TYPE_INT64:
572 case LY_TYPE_UINT64:
573 FREE_MEMBER(ctx, ((struct lysc_type_num*)type)->range, lysc_range_free);
574 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100575 case LY_TYPE_IDENT:
576 LY_ARRAY_FREE(((struct lysc_type_identityref*)type)->bases);
577 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100578 case LY_TYPE_UNION:
579 FREE_ARRAY(ctx, ((struct lysc_type_union*)type)->types, lysc_type2_free);
580 break;
581 case LY_TYPE_LEAFREF:
582 FREE_STRING(ctx, ((struct lysc_type_leafref*)type)->path);
583 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100584 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100585 case LY_TYPE_BOOL:
586 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100587 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100588 /* nothing to do */
589 break;
590 }
591 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci01342af2019-01-03 15:18:08 +0100592 FREE_STRING(ctx, type->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100593
594 free(type);
595}
596
Radek Krejcicdfecd92018-11-26 11:27:32 +0100597static void
Radek Krejci19a96102018-11-15 13:38:09 +0100598lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
599{
600 struct lysc_node *child, *child_next;
601
602 LY_LIST_FOR_SAFE(node->child, child_next, child) {
603 lysc_node_free(ctx, child);
604 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100605 FREE_ARRAY(ctx, node->musts, lysc_must_free);
606
607 /* TODO actions, notifs */
Radek Krejci19a96102018-11-15 13:38:09 +0100608}
609
610static void
611lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
612{
Radek Krejci58d171e2018-11-23 13:50:55 +0100613 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100614 if (node->type) {
615 lysc_type_free(ctx, node->type);
616 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100617 FREE_STRING(ctx, node->units);
618 FREE_STRING(ctx, node->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100619}
620
Radek Krejci42452ac2018-11-28 17:09:52 +0100621static void
622lysc_node_leaflist_free(struct ly_ctx *ctx, struct lysc_node_leaflist *node)
623{
624 unsigned int u;
625
Radek Krejci42452ac2018-11-28 17:09:52 +0100626 FREE_ARRAY(ctx, node->musts, lysc_must_free);
627 if (node->type) {
628 lysc_type_free(ctx, node->type);
629 }
630 FREE_STRING(ctx, node->units);
631 LY_ARRAY_FOR(node->dflts, u) {
632 lydict_remove(ctx, node->dflts[u]);
633 }
634 LY_ARRAY_FREE(node->dflts);
635}
636
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100637static void
638lysc_node_list_free(struct ly_ctx *ctx, struct lysc_node_list *node)
639{
640 unsigned int u;
641 struct lysc_node *child, *child_next;
642
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100643 LY_LIST_FOR_SAFE(node->child, child_next, child) {
644 lysc_node_free(ctx, child);
645 }
646 FREE_ARRAY(ctx, node->musts, lysc_must_free);
647
648 LY_ARRAY_FREE(node->keys);
649 LY_ARRAY_FOR(node->uniques, u) {
650 LY_ARRAY_FREE(node->uniques[u]);
651 }
652 LY_ARRAY_FREE(node->uniques);
653
654 /* TODO actions, notifs */
655}
656
Radek Krejci056d0a82018-12-06 16:57:25 +0100657static void
658lysc_node_choice_free(struct ly_ctx *ctx, struct lysc_node_choice *node)
659{
660 struct lysc_node *child, *child_next;
661
Radek Krejci056d0a82018-12-06 16:57:25 +0100662 if (node->cases) {
663 LY_LIST_FOR_SAFE(node->cases->child, child_next, child) {
664 lysc_node_free(ctx, child);
665 }
666 LY_LIST_FOR_SAFE((struct lysc_node*)node->cases, child_next, child) {
667 lysc_node_free(ctx, child);
668 }
669 }
Radek Krejci9800fb82018-12-13 14:26:23 +0100670}
Radek Krejci056d0a82018-12-06 16:57:25 +0100671
Radek Krejci9800fb82018-12-13 14:26:23 +0100672static void
673lysc_node_anydata_free(struct ly_ctx *ctx, struct lysc_node_anydata *node)
674{
675 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +0100676}
677
Radek Krejci19a96102018-11-15 13:38:09 +0100678void
679lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node)
680{
681 /* common part */
682 FREE_STRING(ctx, node->name);
Radek Krejci12fb9142019-01-08 09:45:30 +0100683 FREE_STRING(ctx, node->dsc);
684 FREE_STRING(ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100685
686 /* nodetype-specific part */
687 switch(node->nodetype) {
688 case LYS_CONTAINER:
689 lysc_node_container_free(ctx, (struct lysc_node_container*)node);
690 break;
691 case LYS_LEAF:
692 lysc_node_leaf_free(ctx, (struct lysc_node_leaf*)node);
693 break;
Radek Krejci42452ac2018-11-28 17:09:52 +0100694 case LYS_LEAFLIST:
695 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist*)node);
696 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100697 case LYS_LIST:
698 lysc_node_list_free(ctx, (struct lysc_node_list*)node);
699 break;
Radek Krejci056d0a82018-12-06 16:57:25 +0100700 case LYS_CHOICE:
701 lysc_node_choice_free(ctx, (struct lysc_node_choice*)node);
702 break;
703 case LYS_CASE:
704 /* nothing specific */
705 break;
Radek Krejci9800fb82018-12-13 14:26:23 +0100706 case LYS_ANYDATA:
707 case LYS_ANYXML:
708 lysc_node_anydata_free(ctx, (struct lysc_node_anydata*)node);
709 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100710 default:
711 LOGINT(ctx);
712 }
713
Radek Krejci056d0a82018-12-06 16:57:25 +0100714 FREE_MEMBER(ctx, node->when, lysc_when_free);
715 FREE_ARRAY(ctx, node->iffeatures, lysc_iffeature_free);
716 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100717 free(node);
718}
719
720static void
721lysc_module_free_(struct lysc_module *module)
722{
723 struct ly_ctx *ctx;
724 struct lysc_node *node, *node_next;
725
726 LY_CHECK_ARG_RET(NULL, module,);
727 ctx = module->ctx;
728
729 FREE_STRING(ctx, module->name);
730 FREE_STRING(ctx, module->ns);
731 FREE_STRING(ctx, module->prefix);
732 FREE_STRING(ctx, module->revision);
Radek Krejcic8b31002019-01-08 10:24:45 +0100733 FREE_STRING(ctx, module->org);
734 FREE_STRING(ctx, module->contact);
735 FREE_STRING(ctx, module->dsc);
736 FREE_STRING(ctx, module->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100737
738 FREE_ARRAY(ctx, module->imports, lysc_import_free);
739 FREE_ARRAY(ctx, module->features, lysc_feature_free);
740 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
741
742 LY_LIST_FOR_SAFE(module->data, node_next, node) {
743 lysc_node_free(ctx, node);
744 }
745
746 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
747
748 free(module);
749}
750
751void
752lysc_module_free(struct lysc_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
753{
Radek Krejci19a96102018-11-15 13:38:09 +0100754 if (module) {
755 lysc_module_free_(module);
756 }
757}
758
759void
760lys_module_free(struct lys_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
761{
762 if (!module) {
763 return;
764 }
765
766 lysc_module_free(module->compiled, private_destructor);
767 lysp_module_free(module->parsed);
768 free(module);
769}