blob: 28be01d14d3831efe5b9d666b73b8aa0d8cb0172 [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);}
24#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
25#define FREE_STRINGS(CTX, ARRAY) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__]);}LY_ARRAY_FREE(ARRAY);}
26
27static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
28static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
29
30static void
31lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
32{
33 struct lysp_stmt *child, *next;
34
35 FREE_STRING(ctx, stmt->stmt);
36 FREE_STRING(ctx, stmt->arg);
37
38 LY_LIST_FOR_SAFE(stmt->child, next, child) {
39 lysp_stmt_free(ctx, child);
40 }
41
42 free(stmt);
43}
44
45static void
46lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
47{
48 struct lysp_stmt *stmt, *next;
49
50 FREE_STRING(ctx, ext->name);
51 FREE_STRING(ctx, ext->argument);
52
53 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
54 lysp_stmt_free(ctx, stmt);
55 }
56}
57
58static void
59lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
60{
61 /* imported module is freed directly from the context's list */
62 FREE_STRING(ctx, import->name);
63 FREE_STRING(ctx, import->prefix);
64 FREE_STRING(ctx, import->dsc);
65 FREE_STRING(ctx, import->ref);
66 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
67}
68
69static void
70lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
71{
72 if (include->submodule) {
73 lysp_module_free(include->submodule);
74 }
75 FREE_STRING(ctx, include->name);
76 FREE_STRING(ctx, include->dsc);
77 FREE_STRING(ctx, include->ref);
78 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
79}
80
81static void
82lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
83{
84 FREE_STRING(ctx, rev->dsc);
85 FREE_STRING(ctx, rev->ref);
86 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
87}
88
89static void
90lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
91{
92 FREE_STRING(ctx, ext->name);
93 FREE_STRING(ctx, ext->argument);
94 FREE_STRING(ctx, ext->dsc);
95 FREE_STRING(ctx, ext->ref);
96 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
97}
98
99static void
100lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
101{
102 FREE_STRING(ctx, feat->name);
103 FREE_STRINGS(ctx, feat->iffeatures);
104 FREE_STRING(ctx, feat->dsc);
105 FREE_STRING(ctx, feat->ref);
106 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
107}
108
109static void
110lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
111{
112 FREE_STRING(ctx, ident->name);
113 FREE_STRINGS(ctx, ident->iffeatures);
114 FREE_STRINGS(ctx, ident->bases);
115 FREE_STRING(ctx, ident->dsc);
116 FREE_STRING(ctx, ident->ref);
117 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
118}
119
120static void
121lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
122{
123 FREE_STRING(ctx, restr->arg);
124 FREE_STRING(ctx, restr->emsg);
125 FREE_STRING(ctx, restr->eapptag);
126 FREE_STRING(ctx, restr->dsc);
127 FREE_STRING(ctx, restr->ref);
128 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
129}
130
131static void
132lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
133{
134 FREE_STRING(ctx, item->name);
135 FREE_STRING(ctx, item->dsc);
136 FREE_STRING(ctx, item->ref);
137 FREE_STRINGS(ctx, item->iffeatures);
138 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
139}
140
Radek Krejcicdfecd92018-11-26 11:27:32 +0100141void lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type);
Radek Krejci19a96102018-11-15 13:38:09 +0100142static void
143lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
144{
145 FREE_STRING(ctx, type->name);
146 FREE_MEMBER(ctx, type->range, lysp_restr_free);
147 FREE_MEMBER(ctx, type->length, lysp_restr_free);
148 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
149 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
150 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
151 FREE_STRING(ctx, type->path);
152 FREE_STRINGS(ctx, type->bases);
153 FREE_ARRAY(ctx, type->types, lysp_type_free);
154 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
155 if (type->compiled) {
156 lysc_type_free(ctx, type->compiled);
157 }
158}
159
160static void
161lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
162{
163 FREE_STRING(ctx, tpdf->name);
164 FREE_STRING(ctx, tpdf->units);
165 FREE_STRING(ctx, tpdf->dflt);
166 FREE_STRING(ctx, tpdf->dsc);
167 FREE_STRING(ctx, tpdf->ref);
168 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
169
170 lysp_type_free(ctx, &tpdf->type);
171
172}
173
174static void
175lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
176{
177 struct lysp_node *node, *next;
178
179 FREE_ARRAY(ctx, inout->musts, lysp_restr_free);
180 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
181 FREE_ARRAY(ctx, inout->groupings, lysp_grp_free);
182 LY_LIST_FOR_SAFE(inout->data, next, node) {
183 lysp_node_free(ctx, node);
184 }
185 FREE_ARRAY(ctx, inout->exts, lysp_ext_instance_free);
186
187}
188
189static void
190lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
191{
192 FREE_STRING(ctx, action->name);
193 FREE_STRING(ctx, action->dsc);
194 FREE_STRING(ctx, action->ref);
195 FREE_STRINGS(ctx, action->iffeatures);
196 FREE_ARRAY(ctx, action->typedefs, lysp_tpdf_free);
197 FREE_ARRAY(ctx, action->groupings, lysp_grp_free);
198 FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
199 FREE_MEMBER(ctx, action->output, lysp_action_inout_free);
200 FREE_ARRAY(ctx, action->exts, lysp_ext_instance_free);
201}
202
203static void
204lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
205{
206 struct lysp_node *node, *next;
207
208 FREE_STRING(ctx, notif->name);
209 FREE_STRING(ctx, notif->dsc);
210 FREE_STRING(ctx, notif->ref);
211 FREE_STRINGS(ctx, notif->iffeatures);
212 FREE_ARRAY(ctx, notif->musts, lysp_restr_free);
213 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
214 FREE_ARRAY(ctx, notif->groupings, lysp_grp_free);
215 LY_LIST_FOR_SAFE(notif->data, next, node) {
216 lysp_node_free(ctx, node);
217 }
218 FREE_ARRAY(ctx, notif->exts, lysp_ext_instance_free);
219}
220
221static void
222lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
223{
224 struct lysp_node *node, *next;
225
226 FREE_STRING(ctx, grp->name);
227 FREE_STRING(ctx, grp->dsc);
228 FREE_STRING(ctx, grp->ref);
229 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
230 FREE_ARRAY(ctx, grp->groupings, lysp_grp_free);
231 LY_LIST_FOR_SAFE(grp->data, next, node) {
232 lysp_node_free(ctx, node);
233 }
234 FREE_ARRAY(ctx, grp->actions, lysp_action_free);
235 FREE_ARRAY(ctx, grp->notifs, lysp_notif_free);
236 FREE_ARRAY(ctx, grp->exts, lysp_ext_instance_free);
237}
238
239static void
240lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
241{
242 FREE_STRING(ctx, when->cond);
243 FREE_STRING(ctx, when->dsc);
244 FREE_STRING(ctx, when->ref);
245 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
246}
247
248static void
249lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
250{
251 struct lysp_node *node, *next;
252
253 FREE_STRING(ctx, augment->nodeid);
254 FREE_STRING(ctx, augment->dsc);
255 FREE_STRING(ctx, augment->ref);
256 FREE_MEMBER(ctx, augment->when, lysp_when_free);
257 FREE_STRINGS(ctx, augment->iffeatures);
258 LY_LIST_FOR_SAFE(augment->child, next, node) {
259 lysp_node_free(ctx, node);
260 }
261 FREE_ARRAY(ctx, augment->actions, lysp_action_free);
262 FREE_ARRAY(ctx, augment->notifs, lysp_notif_free);
263 FREE_ARRAY(ctx, augment->exts, lysp_ext_instance_free);
264}
265
266static void
267lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
268{
269 struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
270 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
271
272 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
273 switch(d->mod) {
274 case LYS_DEV_NOT_SUPPORTED:
275 /* nothing to do */
276 break;
277 case LYS_DEV_ADD:
278 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
279 FREE_STRING(ctx, add->units);
280 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
281 FREE_STRINGS(ctx, add->uniques);
282 FREE_STRINGS(ctx, add->dflts);
283 break;
284 case LYS_DEV_REPLACE:
285 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
286 FREE_STRING(ctx, rpl->units);
287 FREE_STRING(ctx, rpl->dflt);
288 break;
289 default:
290 LOGINT(ctx);
291 break;
292 }
293}
294
295static void
296lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
297{
298 struct lysp_deviate *next, *iter;
299
300 FREE_STRING(ctx, dev->nodeid);
301 FREE_STRING(ctx, dev->dsc);
302 FREE_STRING(ctx, dev->ref);
303 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
304 lysp_deviate_free(ctx, iter);
305 free(iter);
306 }
307 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
308}
309
310static void
311lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
312{
313 FREE_STRING(ctx, ref->nodeid);
314 FREE_STRING(ctx, ref->dsc);
315 FREE_STRING(ctx, ref->ref);
316 FREE_STRINGS(ctx, ref->iffeatures);
317 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
318 FREE_STRING(ctx, ref->presence);
319 FREE_STRINGS(ctx, ref->dflts);
320 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
321}
322
323static void
324lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
325{
326 struct lysp_node *child, *next;
327
328 FREE_STRING(ctx, node->name);
329 FREE_STRING(ctx, node->dsc);
330 FREE_STRING(ctx, node->ref);
331 FREE_MEMBER(ctx, node->when, lysp_when_free);
332 FREE_STRINGS(ctx, node->iffeatures);
333 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
334
335 switch(node->nodetype) {
336 case LYS_CONTAINER:
337 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, lysp_restr_free);
338 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
339 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, lysp_tpdf_free);
340 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, lysp_grp_free);
341 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
342 lysp_node_free(ctx, child);
343 }
344 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, lysp_action_free);
345 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, lysp_notif_free);
346 break;
347 case LYS_LEAF:
348 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, lysp_restr_free);
349 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
350 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
351 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
352 break;
353 case LYS_LEAFLIST:
354 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, lysp_restr_free);
355 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
356 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
357 FREE_STRINGS(ctx, ((struct lysp_node_leaflist*)node)->dflts);
358 break;
359 case LYS_LIST:
360 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, lysp_restr_free);
361 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
362 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, lysp_tpdf_free);
363 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, lysp_grp_free);
364 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
365 lysp_node_free(ctx, child);
366 }
367 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, lysp_action_free);
368 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, lysp_notif_free);
369 FREE_STRINGS(ctx, ((struct lysp_node_list*)node)->uniques);
370 break;
371 case LYS_CHOICE:
372 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
373 lysp_node_free(ctx, child);
374 }
375 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
376 break;
377 case LYS_CASE:
378 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
379 lysp_node_free(ctx, child);
380 }
381 break;
382 case LYS_ANYDATA:
383 case LYS_ANYXML:
384 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, lysp_restr_free);
385 break;
386 case LYS_USES:
387 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, lysp_refine_free);
388 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, lysp_augment_free);
389 break;
390 default:
391 LOGINT(ctx);
392 }
393
394 free(node);
395}
396
397API void
398lysp_module_free(struct lysp_module *module)
399{
400 struct ly_ctx *ctx;
401 struct lysp_node *node, *next;
402
403 LY_CHECK_ARG_RET(NULL, module,);
404 ctx = module->ctx;
405
406 FREE_STRING(ctx, module->name);
407 FREE_STRING(ctx, module->filepath);
408 FREE_STRING(ctx, module->ns); /* or belongs-to */
409 FREE_STRING(ctx, module->prefix);
410
411 FREE_ARRAY(ctx, module->imports, lysp_import_free);
412 FREE_ARRAY(ctx, module->includes, lysp_include_free);
413
414 FREE_STRING(ctx, module->org);
415 FREE_STRING(ctx, module->contact);
416 FREE_STRING(ctx, module->dsc);
417 FREE_STRING(ctx, module->ref);
418
419 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
420 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
421 FREE_ARRAY(ctx, module->features, lysp_feature_free);
422 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
423 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
424 FREE_ARRAY(ctx, module->groupings, lysp_grp_free);
425 LY_LIST_FOR_SAFE(module->data, next, node) {
426 lysp_node_free(ctx, node);
427 }
428 FREE_ARRAY(ctx, module->augments, lysp_augment_free);
429 FREE_ARRAY(ctx, module->rpcs, lysp_action_free);
430 FREE_ARRAY(ctx, module->notifs, lysp_notif_free);
431 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
432 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
433
434 free(module);
435}
436
437static void
438lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
439{
440 FREE_STRING(ctx, ext->argument);
441 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
442}
443
444static void
445lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
446{
447 LY_ARRAY_FREE(iff->features);
448 free(iff->expr);
449}
450
451static void
Radek Krejci58d171e2018-11-23 13:50:55 +0100452lysc_when_free(struct ly_ctx *ctx, struct lysc_when *w)
453{
454 lyxp_expr_free(ctx, w->cond);
455 FREE_ARRAY(ctx, w->exts, lysc_ext_instance_free);
456}
457
458static void
459lysc_must_free(struct ly_ctx *ctx, struct lysc_must *must)
460{
461 lyxp_expr_free(ctx, must->cond);
462 FREE_STRING(ctx, must->emsg);
463 FREE_STRING(ctx, must->eapptag);
464 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
465}
466
467static void
Radek Krejci19a96102018-11-15 13:38:09 +0100468lysc_import_free(struct ly_ctx *ctx, struct lysc_import *import)
469{
470 /* imported module is freed directly from the context's list */
471 FREE_STRING(ctx, import->prefix);
472 FREE_ARRAY(ctx, import->exts, lysc_ext_instance_free);
473}
474
475static void
476lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident)
477{
478 FREE_STRING(ctx, ident->name);
479 FREE_ARRAY(ctx, ident->iffeatures, lysc_iffeature_free);
480 LY_ARRAY_FREE(ident->derived);
481 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
482}
483
484static void
485lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat)
486{
487 FREE_STRING(ctx, feat->name);
488 FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
489 LY_ARRAY_FREE(feat->depfeatures);
490 FREE_ARRAY(ctx, feat->exts, lysc_ext_instance_free);
491}
492
493static void
494lysc_range_free(struct ly_ctx *ctx, struct lysc_range *range)
495{
496 LY_ARRAY_FREE(range->parts);
497 FREE_STRING(ctx, range->eapptag);
498 FREE_STRING(ctx, range->emsg);
499 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
500}
501
502static void
503lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern)
504{
505 if (--(*pattern)->refcount) {
506 return;
507 }
508 pcre_free((*pattern)->expr);
509 pcre_free_study((*pattern)->expr_extra);
510 FREE_STRING(ctx, (*pattern)->eapptag);
511 FREE_STRING(ctx, (*pattern)->emsg);
512 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
513 free(*pattern);
514}
515
516static void
517lysc_enum_item_free(struct ly_ctx *ctx, struct lysc_type_enum_item *item)
518{
519 FREE_STRING(ctx, item->name);
520 FREE_ARRAY(ctx, item->iffeatures, lysc_iffeature_free);
521 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
522}
523
Radek Krejcia3045382018-11-22 14:30:31 +0100524static void
525lysc_type2_free(struct ly_ctx *ctx, struct lysc_type **type)
526{
527 lysc_type_free(ctx, *type);
528}
Radek Krejcicdfecd92018-11-26 11:27:32 +0100529void
Radek Krejci19a96102018-11-15 13:38:09 +0100530lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
531{
532 if (--type->refcount) {
533 return;
534 }
535 switch(type->basetype) {
536 case LY_TYPE_BINARY:
537 FREE_MEMBER(ctx, ((struct lysc_type_bin*)type)->length, lysc_range_free);
538 break;
539 case LY_TYPE_BITS:
540 FREE_ARRAY(ctx, (struct lysc_type_enum_item*)((struct lysc_type_bits*)type)->bits, lysc_enum_item_free);
541 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100542 case LY_TYPE_DEC64:
543 FREE_MEMBER(ctx, ((struct lysc_type_dec*)type)->range, lysc_range_free);
544 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100545 case LY_TYPE_STRING:
546 FREE_MEMBER(ctx, ((struct lysc_type_str*)type)->length, lysc_range_free);
547 FREE_ARRAY(ctx, ((struct lysc_type_str*)type)->patterns, lysc_pattern_free);
548 break;
549 case LY_TYPE_ENUM:
550 FREE_ARRAY(ctx, ((struct lysc_type_enum*)type)->enums, lysc_enum_item_free);
551 break;
552 case LY_TYPE_INT8:
553 case LY_TYPE_UINT8:
554 case LY_TYPE_INT16:
555 case LY_TYPE_UINT16:
556 case LY_TYPE_INT32:
557 case LY_TYPE_UINT32:
558 case LY_TYPE_INT64:
559 case LY_TYPE_UINT64:
560 FREE_MEMBER(ctx, ((struct lysc_type_num*)type)->range, lysc_range_free);
561 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100562 case LY_TYPE_IDENT:
563 LY_ARRAY_FREE(((struct lysc_type_identityref*)type)->bases);
564 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100565 case LY_TYPE_UNION:
566 FREE_ARRAY(ctx, ((struct lysc_type_union*)type)->types, lysc_type2_free);
567 break;
568 case LY_TYPE_LEAFREF:
569 FREE_STRING(ctx, ((struct lysc_type_leafref*)type)->path);
570 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100571 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100572 case LY_TYPE_BOOL:
573 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100574 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100575 /* nothing to do */
576 break;
577 }
578 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
579
580 free(type);
581}
582
Radek Krejcicdfecd92018-11-26 11:27:32 +0100583static void
Radek Krejci19a96102018-11-15 13:38:09 +0100584lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
585{
586 struct lysc_node *child, *child_next;
587
588 LY_LIST_FOR_SAFE(node->child, child_next, child) {
589 lysc_node_free(ctx, child);
590 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100591 FREE_ARRAY(ctx, node->musts, lysc_must_free);
592
593 /* TODO actions, notifs */
Radek Krejci19a96102018-11-15 13:38:09 +0100594}
595
596static void
597lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
598{
Radek Krejci58d171e2018-11-23 13:50:55 +0100599 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100600 if (node->type) {
601 lysc_type_free(ctx, node->type);
602 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100603 FREE_STRING(ctx, node->units);
604 FREE_STRING(ctx, node->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100605}
606
Radek Krejci42452ac2018-11-28 17:09:52 +0100607static void
608lysc_node_leaflist_free(struct ly_ctx *ctx, struct lysc_node_leaflist *node)
609{
610 unsigned int u;
611
Radek Krejci42452ac2018-11-28 17:09:52 +0100612 FREE_ARRAY(ctx, node->musts, lysc_must_free);
613 if (node->type) {
614 lysc_type_free(ctx, node->type);
615 }
616 FREE_STRING(ctx, node->units);
617 LY_ARRAY_FOR(node->dflts, u) {
618 lydict_remove(ctx, node->dflts[u]);
619 }
620 LY_ARRAY_FREE(node->dflts);
621}
622
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100623static void
624lysc_node_list_free(struct ly_ctx *ctx, struct lysc_node_list *node)
625{
626 unsigned int u;
627 struct lysc_node *child, *child_next;
628
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100629 LY_LIST_FOR_SAFE(node->child, child_next, child) {
630 lysc_node_free(ctx, child);
631 }
632 FREE_ARRAY(ctx, node->musts, lysc_must_free);
633
634 LY_ARRAY_FREE(node->keys);
635 LY_ARRAY_FOR(node->uniques, u) {
636 LY_ARRAY_FREE(node->uniques[u]);
637 }
638 LY_ARRAY_FREE(node->uniques);
639
640 /* TODO actions, notifs */
641}
642
Radek Krejci056d0a82018-12-06 16:57:25 +0100643static void
644lysc_node_choice_free(struct ly_ctx *ctx, struct lysc_node_choice *node)
645{
646 struct lysc_node *child, *child_next;
647
648 FREE_MEMBER(ctx, node->when, lysc_when_free);
649 FREE_ARRAY(ctx, node->iffeatures, lysc_iffeature_free);
650 if (node->cases) {
651 LY_LIST_FOR_SAFE(node->cases->child, child_next, child) {
652 lysc_node_free(ctx, child);
653 }
654 LY_LIST_FOR_SAFE((struct lysc_node*)node->cases, child_next, child) {
655 lysc_node_free(ctx, child);
656 }
657 }
658
659}
660
Radek Krejci19a96102018-11-15 13:38:09 +0100661void
662lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node)
663{
664 /* common part */
665 FREE_STRING(ctx, node->name);
666
667 /* nodetype-specific part */
668 switch(node->nodetype) {
669 case LYS_CONTAINER:
670 lysc_node_container_free(ctx, (struct lysc_node_container*)node);
671 break;
672 case LYS_LEAF:
673 lysc_node_leaf_free(ctx, (struct lysc_node_leaf*)node);
674 break;
Radek Krejci42452ac2018-11-28 17:09:52 +0100675 case LYS_LEAFLIST:
676 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist*)node);
677 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100678 case LYS_LIST:
679 lysc_node_list_free(ctx, (struct lysc_node_list*)node);
680 break;
Radek Krejci056d0a82018-12-06 16:57:25 +0100681 case LYS_CHOICE:
682 lysc_node_choice_free(ctx, (struct lysc_node_choice*)node);
683 break;
684 case LYS_CASE:
685 /* nothing specific */
686 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100687 default:
688 LOGINT(ctx);
689 }
690
Radek Krejci056d0a82018-12-06 16:57:25 +0100691 FREE_MEMBER(ctx, node->when, lysc_when_free);
692 FREE_ARRAY(ctx, node->iffeatures, lysc_iffeature_free);
693 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100694 free(node);
695}
696
697static void
698lysc_module_free_(struct lysc_module *module)
699{
700 struct ly_ctx *ctx;
701 struct lysc_node *node, *node_next;
702
703 LY_CHECK_ARG_RET(NULL, module,);
704 ctx = module->ctx;
705
706 FREE_STRING(ctx, module->name);
707 FREE_STRING(ctx, module->ns);
708 FREE_STRING(ctx, module->prefix);
709 FREE_STRING(ctx, module->revision);
710
711 FREE_ARRAY(ctx, module->imports, lysc_import_free);
712 FREE_ARRAY(ctx, module->features, lysc_feature_free);
713 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
714
715 LY_LIST_FOR_SAFE(module->data, node_next, node) {
716 lysc_node_free(ctx, node);
717 }
718
719 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
720
721 free(module);
722}
723
724void
725lysc_module_free(struct lysc_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
726{
Radek Krejci19a96102018-11-15 13:38:09 +0100727 if (module) {
728 lysc_module_free_(module);
729 }
730}
731
732void
733lys_module_free(struct lys_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
734{
735 if (!module) {
736 return;
737 }
738
739 lysc_module_free(module->compiled, private_destructor);
740 lysp_module_free(module->parsed);
741 free(module);
742}