blob: 1c94ae7ff42f820d90f833e94a3c2845f11efbe9 [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
Radek Krejci19a96102018-11-15 13:38:09 +010022static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
23static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
24
25static void
26lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
27{
28 struct lysp_stmt *child, *next;
29
30 FREE_STRING(ctx, stmt->stmt);
31 FREE_STRING(ctx, stmt->arg);
32
33 LY_LIST_FOR_SAFE(stmt->child, next, child) {
34 lysp_stmt_free(ctx, child);
35 }
36
37 free(stmt);
38}
39
40static void
41lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
42{
43 struct lysp_stmt *stmt, *next;
44
45 FREE_STRING(ctx, ext->name);
46 FREE_STRING(ctx, ext->argument);
47
48 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
49 lysp_stmt_free(ctx, stmt);
50 }
51}
52
53static void
54lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
55{
56 /* imported module is freed directly from the context's list */
57 FREE_STRING(ctx, import->name);
58 FREE_STRING(ctx, import->prefix);
59 FREE_STRING(ctx, import->dsc);
60 FREE_STRING(ctx, import->ref);
61 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
62}
63
64static void
65lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
66{
67 if (include->submodule) {
Radek Krejci0bcdaed2019-01-10 10:21:34 +010068 lysp_submodule_free(ctx, include->submodule);
Radek Krejci19a96102018-11-15 13:38:09 +010069 }
70 FREE_STRING(ctx, include->name);
71 FREE_STRING(ctx, include->dsc);
72 FREE_STRING(ctx, include->ref);
73 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
74}
75
76static void
77lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
78{
79 FREE_STRING(ctx, rev->dsc);
80 FREE_STRING(ctx, rev->ref);
81 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
82}
83
84static void
85lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
86{
87 FREE_STRING(ctx, ext->name);
88 FREE_STRING(ctx, ext->argument);
89 FREE_STRING(ctx, ext->dsc);
90 FREE_STRING(ctx, ext->ref);
91 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
92}
93
94static void
95lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
96{
97 FREE_STRING(ctx, feat->name);
98 FREE_STRINGS(ctx, feat->iffeatures);
99 FREE_STRING(ctx, feat->dsc);
100 FREE_STRING(ctx, feat->ref);
101 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
102}
103
104static void
105lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
106{
107 FREE_STRING(ctx, ident->name);
108 FREE_STRINGS(ctx, ident->iffeatures);
109 FREE_STRINGS(ctx, ident->bases);
110 FREE_STRING(ctx, ident->dsc);
111 FREE_STRING(ctx, ident->ref);
112 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
113}
114
115static void
116lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
117{
118 FREE_STRING(ctx, restr->arg);
119 FREE_STRING(ctx, restr->emsg);
120 FREE_STRING(ctx, restr->eapptag);
121 FREE_STRING(ctx, restr->dsc);
122 FREE_STRING(ctx, restr->ref);
123 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
124}
125
126static void
127lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
128{
129 FREE_STRING(ctx, item->name);
130 FREE_STRING(ctx, item->dsc);
131 FREE_STRING(ctx, item->ref);
132 FREE_STRINGS(ctx, item->iffeatures);
133 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
134}
135
Radek Krejcicdfecd92018-11-26 11:27:32 +0100136void lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type);
Radek Krejci19a96102018-11-15 13:38:09 +0100137static void
138lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
139{
140 FREE_STRING(ctx, type->name);
141 FREE_MEMBER(ctx, type->range, lysp_restr_free);
142 FREE_MEMBER(ctx, type->length, lysp_restr_free);
143 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
144 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
145 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
146 FREE_STRING(ctx, type->path);
147 FREE_STRINGS(ctx, type->bases);
148 FREE_ARRAY(ctx, type->types, lysp_type_free);
149 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
150 if (type->compiled) {
151 lysc_type_free(ctx, type->compiled);
152 }
153}
154
155static void
156lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
157{
158 FREE_STRING(ctx, tpdf->name);
159 FREE_STRING(ctx, tpdf->units);
160 FREE_STRING(ctx, tpdf->dflt);
161 FREE_STRING(ctx, tpdf->dsc);
162 FREE_STRING(ctx, tpdf->ref);
163 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
164
165 lysp_type_free(ctx, &tpdf->type);
166
167}
168
Radek Krejcif538ce52019-03-05 10:46:14 +0100169void
Radek Krejci19a96102018-11-15 13:38:09 +0100170lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
171{
172 struct lysp_node *node, *next;
173
174 FREE_ARRAY(ctx, inout->musts, lysp_restr_free);
175 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
176 FREE_ARRAY(ctx, inout->groupings, lysp_grp_free);
177 LY_LIST_FOR_SAFE(inout->data, next, node) {
178 lysp_node_free(ctx, node);
179 }
180 FREE_ARRAY(ctx, inout->exts, lysp_ext_instance_free);
181
182}
183
184static void
185lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
186{
187 FREE_STRING(ctx, action->name);
188 FREE_STRING(ctx, action->dsc);
189 FREE_STRING(ctx, action->ref);
190 FREE_STRINGS(ctx, action->iffeatures);
191 FREE_ARRAY(ctx, action->typedefs, lysp_tpdf_free);
192 FREE_ARRAY(ctx, action->groupings, lysp_grp_free);
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100193 lysp_action_inout_free(ctx, &action->input);
194 lysp_action_inout_free(ctx, &action->output);
Radek Krejci19a96102018-11-15 13:38:09 +0100195 FREE_ARRAY(ctx, action->exts, lysp_ext_instance_free);
196}
197
198static void
199lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
200{
201 struct lysp_node *node, *next;
202
203 FREE_STRING(ctx, notif->name);
204 FREE_STRING(ctx, notif->dsc);
205 FREE_STRING(ctx, notif->ref);
206 FREE_STRINGS(ctx, notif->iffeatures);
207 FREE_ARRAY(ctx, notif->musts, lysp_restr_free);
208 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
209 FREE_ARRAY(ctx, notif->groupings, lysp_grp_free);
210 LY_LIST_FOR_SAFE(notif->data, next, node) {
211 lysp_node_free(ctx, node);
212 }
213 FREE_ARRAY(ctx, notif->exts, lysp_ext_instance_free);
214}
215
216static void
217lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
218{
219 struct lysp_node *node, *next;
220
221 FREE_STRING(ctx, grp->name);
222 FREE_STRING(ctx, grp->dsc);
223 FREE_STRING(ctx, grp->ref);
224 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
225 FREE_ARRAY(ctx, grp->groupings, lysp_grp_free);
226 LY_LIST_FOR_SAFE(grp->data, next, node) {
227 lysp_node_free(ctx, node);
228 }
229 FREE_ARRAY(ctx, grp->actions, lysp_action_free);
230 FREE_ARRAY(ctx, grp->notifs, lysp_notif_free);
231 FREE_ARRAY(ctx, grp->exts, lysp_ext_instance_free);
232}
233
234static void
235lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
236{
237 FREE_STRING(ctx, when->cond);
238 FREE_STRING(ctx, when->dsc);
239 FREE_STRING(ctx, when->ref);
240 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
241}
242
243static void
244lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
245{
246 struct lysp_node *node, *next;
247
248 FREE_STRING(ctx, augment->nodeid);
249 FREE_STRING(ctx, augment->dsc);
250 FREE_STRING(ctx, augment->ref);
251 FREE_MEMBER(ctx, augment->when, lysp_when_free);
252 FREE_STRINGS(ctx, augment->iffeatures);
253 LY_LIST_FOR_SAFE(augment->child, next, node) {
254 lysp_node_free(ctx, node);
255 }
256 FREE_ARRAY(ctx, augment->actions, lysp_action_free);
257 FREE_ARRAY(ctx, augment->notifs, lysp_notif_free);
258 FREE_ARRAY(ctx, augment->exts, lysp_ext_instance_free);
259}
260
261static void
262lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
263{
264 struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
265 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
266
267 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
268 switch(d->mod) {
269 case LYS_DEV_NOT_SUPPORTED:
270 /* nothing to do */
271 break;
272 case LYS_DEV_ADD:
273 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
274 FREE_STRING(ctx, add->units);
275 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
276 FREE_STRINGS(ctx, add->uniques);
277 FREE_STRINGS(ctx, add->dflts);
278 break;
279 case LYS_DEV_REPLACE:
280 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
281 FREE_STRING(ctx, rpl->units);
282 FREE_STRING(ctx, rpl->dflt);
283 break;
284 default:
285 LOGINT(ctx);
286 break;
287 }
288}
289
290static void
291lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
292{
293 struct lysp_deviate *next, *iter;
294
295 FREE_STRING(ctx, dev->nodeid);
296 FREE_STRING(ctx, dev->dsc);
297 FREE_STRING(ctx, dev->ref);
298 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
299 lysp_deviate_free(ctx, iter);
300 free(iter);
301 }
302 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
303}
304
305static void
306lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
307{
308 FREE_STRING(ctx, ref->nodeid);
309 FREE_STRING(ctx, ref->dsc);
310 FREE_STRING(ctx, ref->ref);
311 FREE_STRINGS(ctx, ref->iffeatures);
312 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
313 FREE_STRING(ctx, ref->presence);
314 FREE_STRINGS(ctx, ref->dflts);
315 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
316}
317
318static void
319lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
320{
321 struct lysp_node *child, *next;
322
323 FREE_STRING(ctx, node->name);
324 FREE_STRING(ctx, node->dsc);
325 FREE_STRING(ctx, node->ref);
326 FREE_MEMBER(ctx, node->when, lysp_when_free);
327 FREE_STRINGS(ctx, node->iffeatures);
328 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
329
330 switch(node->nodetype) {
331 case LYS_CONTAINER:
332 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, lysp_restr_free);
333 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
334 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, lysp_tpdf_free);
335 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, lysp_grp_free);
336 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
337 lysp_node_free(ctx, child);
338 }
339 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, lysp_action_free);
340 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, lysp_notif_free);
341 break;
342 case LYS_LEAF:
343 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, lysp_restr_free);
344 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
345 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
346 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
347 break;
348 case LYS_LEAFLIST:
349 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, lysp_restr_free);
350 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
351 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
352 FREE_STRINGS(ctx, ((struct lysp_node_leaflist*)node)->dflts);
353 break;
354 case LYS_LIST:
355 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, lysp_restr_free);
356 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
357 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, lysp_tpdf_free);
358 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, lysp_grp_free);
359 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
360 lysp_node_free(ctx, child);
361 }
362 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, lysp_action_free);
363 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, lysp_notif_free);
364 FREE_STRINGS(ctx, ((struct lysp_node_list*)node)->uniques);
365 break;
366 case LYS_CHOICE:
367 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
368 lysp_node_free(ctx, child);
369 }
370 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
371 break;
372 case LYS_CASE:
373 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
374 lysp_node_free(ctx, child);
375 }
376 break;
377 case LYS_ANYDATA:
378 case LYS_ANYXML:
379 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, lysp_restr_free);
380 break;
381 case LYS_USES:
382 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, lysp_refine_free);
383 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, lysp_augment_free);
384 break;
385 default:
386 LOGINT(ctx);
387 }
388
389 free(node);
390}
391
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100392void
393lysp_submodule_free(struct ly_ctx *ctx, struct lysp_submodule *submod)
394{
395 struct lysp_node *node, *next;
396
Radek Krejci40544fa2019-01-11 09:38:37 +0100397 if (!submod) {
398 return;
399 }
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100400
401 FREE_ARRAY(ctx, submod->imports, lysp_import_free);
402 FREE_ARRAY(ctx, submod->includes, lysp_include_free);
403
404 FREE_ARRAY(ctx, submod->revs, lysp_revision_free);
405 FREE_ARRAY(ctx, submod->extensions, lysp_ext_free);
406 FREE_ARRAY(ctx, submod->features, lysp_feature_free);
407 FREE_ARRAY(ctx, submod->identities, lysp_ident_free);
408 FREE_ARRAY(ctx, submod->typedefs, lysp_tpdf_free);
409 FREE_ARRAY(ctx, submod->groupings, lysp_grp_free);
410 LY_LIST_FOR_SAFE(submod->data, next, node) {
411 lysp_node_free(ctx, node);
412 }
413 FREE_ARRAY(ctx, submod->augments, lysp_augment_free);
414 FREE_ARRAY(ctx, submod->rpcs, lysp_action_free);
415 FREE_ARRAY(ctx, submod->notifs, lysp_notif_free);
416 FREE_ARRAY(ctx, submod->deviations, lysp_deviation_free);
417 FREE_ARRAY(ctx, submod->exts, lysp_ext_instance_free);
418
419 FREE_STRING(ctx, submod->belongsto);
420 FREE_STRING(ctx, submod->name);
421 FREE_STRING(ctx, submod->filepath);
422 FREE_STRING(ctx, submod->prefix);
423 FREE_STRING(ctx, submod->org);
424 FREE_STRING(ctx, submod->contact);
425 FREE_STRING(ctx, submod->dsc);
426 FREE_STRING(ctx, submod->ref);
427
428 free(submod);
429}
430
Radek Krejci19a96102018-11-15 13:38:09 +0100431API void
432lysp_module_free(struct lysp_module *module)
433{
434 struct ly_ctx *ctx;
435 struct lysp_node *node, *next;
436
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100437 if (!module) {
438 return;
439 }
440 ctx = module->mod->ctx;
Radek Krejci19a96102018-11-15 13:38:09 +0100441
442 FREE_ARRAY(ctx, module->imports, lysp_import_free);
443 FREE_ARRAY(ctx, module->includes, lysp_include_free);
444
Radek Krejci19a96102018-11-15 13:38:09 +0100445 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
446 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
447 FREE_ARRAY(ctx, module->features, lysp_feature_free);
448 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
449 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
450 FREE_ARRAY(ctx, module->groupings, lysp_grp_free);
451 LY_LIST_FOR_SAFE(module->data, next, node) {
452 lysp_node_free(ctx, node);
453 }
454 FREE_ARRAY(ctx, module->augments, lysp_augment_free);
455 FREE_ARRAY(ctx, module->rpcs, lysp_action_free);
456 FREE_ARRAY(ctx, module->notifs, lysp_notif_free);
457 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
458 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
459
460 free(module);
461}
462
Radek Krejci0af46292019-01-11 16:02:31 +0100463void
Radek Krejci19a96102018-11-15 13:38:09 +0100464lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
465{
466 FREE_STRING(ctx, ext->argument);
467 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
468}
469
Radek Krejci0af46292019-01-11 16:02:31 +0100470void
Radek Krejci19a96102018-11-15 13:38:09 +0100471lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
472{
473 LY_ARRAY_FREE(iff->features);
474 free(iff->expr);
475}
476
477static void
Radek Krejci00b874b2019-02-12 10:54:50 +0100478lysc_when_free(struct ly_ctx *ctx, struct lysc_when **w)
Radek Krejci58d171e2018-11-23 13:50:55 +0100479{
Radek Krejci00b874b2019-02-12 10:54:50 +0100480 if (--(*w)->refcount) {
481 return;
482 }
483 lyxp_expr_free(ctx, (*w)->cond);
484 FREE_STRING(ctx, (*w)->dsc);
485 FREE_STRING(ctx, (*w)->ref);
486 FREE_ARRAY(ctx, (*w)->exts, lysc_ext_instance_free);
487 free(*w);
Radek Krejci58d171e2018-11-23 13:50:55 +0100488}
489
Radek Krejciccd20f12019-02-15 14:12:27 +0100490void
Radek Krejci58d171e2018-11-23 13:50:55 +0100491lysc_must_free(struct ly_ctx *ctx, struct lysc_must *must)
492{
493 lyxp_expr_free(ctx, must->cond);
494 FREE_STRING(ctx, must->emsg);
495 FREE_STRING(ctx, must->eapptag);
Radek Krejcic8b31002019-01-08 10:24:45 +0100496 FREE_STRING(ctx, must->dsc);
497 FREE_STRING(ctx, must->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100498 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
499}
500
501static void
Radek Krejci19a96102018-11-15 13:38:09 +0100502lysc_import_free(struct ly_ctx *ctx, struct lysc_import *import)
503{
504 /* imported module is freed directly from the context's list */
505 FREE_STRING(ctx, import->prefix);
506 FREE_ARRAY(ctx, import->exts, lysc_ext_instance_free);
507}
508
509static void
510lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident)
511{
512 FREE_STRING(ctx, ident->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100513 FREE_STRING(ctx, ident->dsc);
514 FREE_STRING(ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100515 FREE_ARRAY(ctx, ident->iffeatures, lysc_iffeature_free);
516 LY_ARRAY_FREE(ident->derived);
517 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
518}
519
520static void
521lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat)
522{
523 FREE_STRING(ctx, feat->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100524 FREE_STRING(ctx, feat->dsc);
525 FREE_STRING(ctx, feat->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100526 FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
527 LY_ARRAY_FREE(feat->depfeatures);
528 FREE_ARRAY(ctx, feat->exts, lysc_ext_instance_free);
529}
530
531static void
532lysc_range_free(struct ly_ctx *ctx, struct lysc_range *range)
533{
534 LY_ARRAY_FREE(range->parts);
535 FREE_STRING(ctx, range->eapptag);
536 FREE_STRING(ctx, range->emsg);
Radek Krejcic8b31002019-01-08 10:24:45 +0100537 FREE_STRING(ctx, range->dsc);
538 FREE_STRING(ctx, range->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100539 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
540}
541
542static void
543lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern)
544{
545 if (--(*pattern)->refcount) {
546 return;
547 }
548 pcre_free((*pattern)->expr);
549 pcre_free_study((*pattern)->expr_extra);
550 FREE_STRING(ctx, (*pattern)->eapptag);
551 FREE_STRING(ctx, (*pattern)->emsg);
Radek Krejcic8b31002019-01-08 10:24:45 +0100552 FREE_STRING(ctx, (*pattern)->dsc);
553 FREE_STRING(ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100554 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
555 free(*pattern);
556}
557
558static void
559lysc_enum_item_free(struct ly_ctx *ctx, struct lysc_type_enum_item *item)
560{
561 FREE_STRING(ctx, item->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100562 FREE_STRING(ctx, item->dsc);
563 FREE_STRING(ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100564 FREE_ARRAY(ctx, item->iffeatures, lysc_iffeature_free);
565 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
566}
567
Radek Krejcia3045382018-11-22 14:30:31 +0100568static void
569lysc_type2_free(struct ly_ctx *ctx, struct lysc_type **type)
570{
571 lysc_type_free(ctx, *type);
572}
Radek Krejcicdfecd92018-11-26 11:27:32 +0100573void
Radek Krejci19a96102018-11-15 13:38:09 +0100574lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
575{
576 if (--type->refcount) {
577 return;
578 }
579 switch(type->basetype) {
580 case LY_TYPE_BINARY:
581 FREE_MEMBER(ctx, ((struct lysc_type_bin*)type)->length, lysc_range_free);
582 break;
583 case LY_TYPE_BITS:
584 FREE_ARRAY(ctx, (struct lysc_type_enum_item*)((struct lysc_type_bits*)type)->bits, lysc_enum_item_free);
585 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100586 case LY_TYPE_DEC64:
587 FREE_MEMBER(ctx, ((struct lysc_type_dec*)type)->range, lysc_range_free);
588 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100589 case LY_TYPE_STRING:
590 FREE_MEMBER(ctx, ((struct lysc_type_str*)type)->length, lysc_range_free);
591 FREE_ARRAY(ctx, ((struct lysc_type_str*)type)->patterns, lysc_pattern_free);
592 break;
593 case LY_TYPE_ENUM:
594 FREE_ARRAY(ctx, ((struct lysc_type_enum*)type)->enums, lysc_enum_item_free);
595 break;
596 case LY_TYPE_INT8:
597 case LY_TYPE_UINT8:
598 case LY_TYPE_INT16:
599 case LY_TYPE_UINT16:
600 case LY_TYPE_INT32:
601 case LY_TYPE_UINT32:
602 case LY_TYPE_INT64:
603 case LY_TYPE_UINT64:
604 FREE_MEMBER(ctx, ((struct lysc_type_num*)type)->range, lysc_range_free);
605 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100606 case LY_TYPE_IDENT:
607 LY_ARRAY_FREE(((struct lysc_type_identityref*)type)->bases);
608 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100609 case LY_TYPE_UNION:
610 FREE_ARRAY(ctx, ((struct lysc_type_union*)type)->types, lysc_type2_free);
611 break;
612 case LY_TYPE_LEAFREF:
613 FREE_STRING(ctx, ((struct lysc_type_leafref*)type)->path);
614 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100615 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100616 case LY_TYPE_BOOL:
617 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100618 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100619 /* nothing to do */
620 break;
621 }
622 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci01342af2019-01-03 15:18:08 +0100623 FREE_STRING(ctx, type->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100624
625 free(type);
626}
627
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100628void
Radek Krejcif538ce52019-03-05 10:46:14 +0100629lysc_action_inout_free(struct ly_ctx *ctx, struct lysc_action_inout *inout)
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100630{
631 struct lysc_node *child, *child_next;
632
Radek Krejcif538ce52019-03-05 10:46:14 +0100633 FREE_ARRAY(ctx, inout->musts, lysc_must_free);
634 LY_LIST_FOR_SAFE(inout->data, child_next, child) {
635 lysc_node_free(ctx, child);
636 }
637}
638
639void
640lysc_action_free(struct ly_ctx *ctx, struct lysc_action *action)
641{
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100642 FREE_STRING(ctx, action->name);
643 FREE_STRING(ctx, action->dsc);
644 FREE_STRING(ctx, action->ref);
645 FREE_ARRAY(ctx, action->iffeatures, lysc_iffeature_free);
646 FREE_ARRAY(ctx, action->exts, lysc_ext_instance_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200647 FREE_ARRAY(ctx, action->input_exts, lysc_ext_instance_free);
Radek Krejcif538ce52019-03-05 10:46:14 +0100648 lysc_action_inout_free(ctx, &action->input);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200649 FREE_ARRAY(ctx, action->output_exts, lysc_ext_instance_free);
Radek Krejcif538ce52019-03-05 10:46:14 +0100650 lysc_action_inout_free(ctx, &action->output);
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100651}
652
Radek Krejcifc11bd72019-04-11 16:00:05 +0200653void
654lysc_notif_free(struct ly_ctx *ctx, struct lysc_notif *notif)
655{
656 struct lysc_node *child, *child_next;
657
658 FREE_STRING(ctx, notif->name);
659 FREE_STRING(ctx, notif->dsc);
660 FREE_STRING(ctx, notif->ref);
661 FREE_ARRAY(ctx, notif->iffeatures, lysc_iffeature_free);
662 FREE_ARRAY(ctx, notif->exts, lysc_ext_instance_free);
663 FREE_ARRAY(ctx, notif->musts, lysc_must_free);
664 LY_LIST_FOR_SAFE(notif->data, child_next, child) {
665 lysc_node_free(ctx, child);
666 }
667}
668
Radek Krejcicdfecd92018-11-26 11:27:32 +0100669static void
Radek Krejci19a96102018-11-15 13:38:09 +0100670lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
671{
672 struct lysc_node *child, *child_next;
673
674 LY_LIST_FOR_SAFE(node->child, child_next, child) {
675 lysc_node_free(ctx, child);
676 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100677 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100678 FREE_ARRAY(ctx, node->actions, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200679 FREE_ARRAY(ctx, node->notifs, lysc_notif_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100680}
681
682static void
683lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
684{
Radek Krejci58d171e2018-11-23 13:50:55 +0100685 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100686 if (node->type) {
687 lysc_type_free(ctx, node->type);
688 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100689 FREE_STRING(ctx, node->units);
690 FREE_STRING(ctx, node->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100691}
692
Radek Krejci42452ac2018-11-28 17:09:52 +0100693static void
694lysc_node_leaflist_free(struct ly_ctx *ctx, struct lysc_node_leaflist *node)
695{
696 unsigned int u;
697
Radek Krejci42452ac2018-11-28 17:09:52 +0100698 FREE_ARRAY(ctx, node->musts, lysc_must_free);
699 if (node->type) {
700 lysc_type_free(ctx, node->type);
701 }
702 FREE_STRING(ctx, node->units);
703 LY_ARRAY_FOR(node->dflts, u) {
704 lydict_remove(ctx, node->dflts[u]);
705 }
706 LY_ARRAY_FREE(node->dflts);
707}
708
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100709static void
710lysc_node_list_free(struct ly_ctx *ctx, struct lysc_node_list *node)
711{
712 unsigned int u;
713 struct lysc_node *child, *child_next;
714
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100715 LY_LIST_FOR_SAFE(node->child, child_next, child) {
716 lysc_node_free(ctx, child);
717 }
718 FREE_ARRAY(ctx, node->musts, lysc_must_free);
719
720 LY_ARRAY_FREE(node->keys);
721 LY_ARRAY_FOR(node->uniques, u) {
722 LY_ARRAY_FREE(node->uniques[u]);
723 }
724 LY_ARRAY_FREE(node->uniques);
725
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100726 FREE_ARRAY(ctx, node->actions, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200727 FREE_ARRAY(ctx, node->notifs, lysc_notif_free);
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100728}
729
Radek Krejci056d0a82018-12-06 16:57:25 +0100730static void
731lysc_node_choice_free(struct ly_ctx *ctx, struct lysc_node_choice *node)
732{
733 struct lysc_node *child, *child_next;
734
Radek Krejci056d0a82018-12-06 16:57:25 +0100735 if (node->cases) {
736 LY_LIST_FOR_SAFE(node->cases->child, child_next, child) {
737 lysc_node_free(ctx, child);
738 }
739 LY_LIST_FOR_SAFE((struct lysc_node*)node->cases, child_next, child) {
740 lysc_node_free(ctx, child);
741 }
742 }
Radek Krejci9800fb82018-12-13 14:26:23 +0100743}
Radek Krejci056d0a82018-12-06 16:57:25 +0100744
Radek Krejci9800fb82018-12-13 14:26:23 +0100745static void
746lysc_node_anydata_free(struct ly_ctx *ctx, struct lysc_node_anydata *node)
747{
748 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +0100749}
750
Radek Krejci19a96102018-11-15 13:38:09 +0100751void
752lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node)
753{
754 /* common part */
755 FREE_STRING(ctx, node->name);
Radek Krejci12fb9142019-01-08 09:45:30 +0100756 FREE_STRING(ctx, node->dsc);
757 FREE_STRING(ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100758
759 /* nodetype-specific part */
760 switch(node->nodetype) {
761 case LYS_CONTAINER:
762 lysc_node_container_free(ctx, (struct lysc_node_container*)node);
763 break;
764 case LYS_LEAF:
765 lysc_node_leaf_free(ctx, (struct lysc_node_leaf*)node);
766 break;
Radek Krejci42452ac2018-11-28 17:09:52 +0100767 case LYS_LEAFLIST:
768 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist*)node);
769 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100770 case LYS_LIST:
771 lysc_node_list_free(ctx, (struct lysc_node_list*)node);
772 break;
Radek Krejci056d0a82018-12-06 16:57:25 +0100773 case LYS_CHOICE:
774 lysc_node_choice_free(ctx, (struct lysc_node_choice*)node);
775 break;
776 case LYS_CASE:
777 /* nothing specific */
778 break;
Radek Krejci9800fb82018-12-13 14:26:23 +0100779 case LYS_ANYDATA:
780 case LYS_ANYXML:
781 lysc_node_anydata_free(ctx, (struct lysc_node_anydata*)node);
782 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100783 default:
784 LOGINT(ctx);
785 }
786
Radek Krejci00b874b2019-02-12 10:54:50 +0100787 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci056d0a82018-12-06 16:57:25 +0100788 FREE_ARRAY(ctx, node->iffeatures, lysc_iffeature_free);
789 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100790 free(node);
791}
792
793static void
794lysc_module_free_(struct lysc_module *module)
795{
796 struct ly_ctx *ctx;
797 struct lysc_node *node, *node_next;
798
799 LY_CHECK_ARG_RET(NULL, module,);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100800 ctx = module->mod->ctx;
Radek Krejci19a96102018-11-15 13:38:09 +0100801
Radek Krejci19a96102018-11-15 13:38:09 +0100802 FREE_ARRAY(ctx, module->imports, lysc_import_free);
803 FREE_ARRAY(ctx, module->features, lysc_feature_free);
804 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
805
806 LY_LIST_FOR_SAFE(module->data, node_next, node) {
807 lysc_node_free(ctx, node);
808 }
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100809 FREE_ARRAY(ctx, module->rpcs, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200810 FREE_ARRAY(ctx, module->notifs, lysc_notif_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100811
812 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
813
814 free(module);
815}
816
817void
818lysc_module_free(struct lysc_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
819{
Radek Krejci9b042892019-02-13 14:28:44 +0100820 /* TODO use the destructor, this just suppress warning about unused parameter */
821 (void) private_destructor;
822
Radek Krejci19a96102018-11-15 13:38:09 +0100823 if (module) {
824 lysc_module_free_(module);
825 }
826}
827
828void
829lys_module_free(struct lys_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
830{
831 if (!module) {
832 return;
833 }
834
835 lysc_module_free(module->compiled, private_destructor);
Radek Krejci0af46292019-01-11 16:02:31 +0100836 FREE_ARRAY(module->ctx, module->off_features, lysc_feature_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100837 lysp_module_free(module->parsed);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100838
839 FREE_STRING(module->ctx, module->name);
Radek Krejci0af46292019-01-11 16:02:31 +0100840 FREE_STRING(module->ctx, module->revision);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100841 FREE_STRING(module->ctx, module->ns);
842 FREE_STRING(module->ctx, module->prefix);
843 FREE_STRING(module->ctx, module->filepath);
844 FREE_STRING(module->ctx, module->org);
845 FREE_STRING(module->ctx, module->contact);
846 FREE_STRING(module->ctx, module->dsc);
847 FREE_STRING(module->ctx, module->ref);
848
Radek Krejci19a96102018-11-15 13:38:09 +0100849 free(module);
850}