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