blob: 9e5563c62ea0b0df123ff9e97c9dc936e09afb2a [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);
Radek Krejci693262f2019-04-29 15:23:20 +0200550 FREE_STRING(ctx, (*pattern)->orig);
Radek Krejci19a96102018-11-15 13:38:09 +0100551 FREE_STRING(ctx, (*pattern)->eapptag);
552 FREE_STRING(ctx, (*pattern)->emsg);
Radek Krejcic8b31002019-01-08 10:24:45 +0100553 FREE_STRING(ctx, (*pattern)->dsc);
554 FREE_STRING(ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100555 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
556 free(*pattern);
557}
558
559static void
Radek Krejci693262f2019-04-29 15:23:20 +0200560lysc_enum_item_free(struct ly_ctx *ctx, struct lysc_type_bitenum_item *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100561{
562 FREE_STRING(ctx, item->name);
Radek Krejcic8b31002019-01-08 10:24:45 +0100563 FREE_STRING(ctx, item->dsc);
564 FREE_STRING(ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100565 FREE_ARRAY(ctx, item->iffeatures, lysc_iffeature_free);
566 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
567}
568
Radek Krejcia3045382018-11-22 14:30:31 +0100569static void
570lysc_type2_free(struct ly_ctx *ctx, struct lysc_type **type)
571{
572 lysc_type_free(ctx, *type);
573}
Radek Krejcicdfecd92018-11-26 11:27:32 +0100574void
Radek Krejci19a96102018-11-15 13:38:09 +0100575lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
576{
577 if (--type->refcount) {
578 return;
579 }
580 switch(type->basetype) {
581 case LY_TYPE_BINARY:
582 FREE_MEMBER(ctx, ((struct lysc_type_bin*)type)->length, lysc_range_free);
583 break;
584 case LY_TYPE_BITS:
Radek Krejci693262f2019-04-29 15:23:20 +0200585 FREE_ARRAY(ctx, (struct lysc_type_bitenum_item*)((struct lysc_type_bits*)type)->bits, lysc_enum_item_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100586 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100587 case LY_TYPE_DEC64:
588 FREE_MEMBER(ctx, ((struct lysc_type_dec*)type)->range, lysc_range_free);
589 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100590 case LY_TYPE_STRING:
591 FREE_MEMBER(ctx, ((struct lysc_type_str*)type)->length, lysc_range_free);
592 FREE_ARRAY(ctx, ((struct lysc_type_str*)type)->patterns, lysc_pattern_free);
593 break;
594 case LY_TYPE_ENUM:
595 FREE_ARRAY(ctx, ((struct lysc_type_enum*)type)->enums, lysc_enum_item_free);
596 break;
597 case LY_TYPE_INT8:
598 case LY_TYPE_UINT8:
599 case LY_TYPE_INT16:
600 case LY_TYPE_UINT16:
601 case LY_TYPE_INT32:
602 case LY_TYPE_UINT32:
603 case LY_TYPE_INT64:
604 case LY_TYPE_UINT64:
605 FREE_MEMBER(ctx, ((struct lysc_type_num*)type)->range, lysc_range_free);
606 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100607 case LY_TYPE_IDENT:
608 LY_ARRAY_FREE(((struct lysc_type_identityref*)type)->bases);
609 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100610 case LY_TYPE_UNION:
611 FREE_ARRAY(ctx, ((struct lysc_type_union*)type)->types, lysc_type2_free);
612 break;
613 case LY_TYPE_LEAFREF:
614 FREE_STRING(ctx, ((struct lysc_type_leafref*)type)->path);
615 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100616 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100617 case LY_TYPE_BOOL:
618 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100619 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100620 /* nothing to do */
621 break;
622 }
623 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci01342af2019-01-03 15:18:08 +0100624 FREE_STRING(ctx, type->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100625
626 free(type);
627}
628
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100629void
Radek Krejcif538ce52019-03-05 10:46:14 +0100630lysc_action_inout_free(struct ly_ctx *ctx, struct lysc_action_inout *inout)
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100631{
632 struct lysc_node *child, *child_next;
633
Radek Krejcif538ce52019-03-05 10:46:14 +0100634 FREE_ARRAY(ctx, inout->musts, lysc_must_free);
635 LY_LIST_FOR_SAFE(inout->data, child_next, child) {
636 lysc_node_free(ctx, child);
637 }
638}
639
640void
641lysc_action_free(struct ly_ctx *ctx, struct lysc_action *action)
642{
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100643 FREE_STRING(ctx, action->name);
644 FREE_STRING(ctx, action->dsc);
645 FREE_STRING(ctx, action->ref);
646 FREE_ARRAY(ctx, action->iffeatures, lysc_iffeature_free);
647 FREE_ARRAY(ctx, action->exts, lysc_ext_instance_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200648 FREE_ARRAY(ctx, action->input_exts, lysc_ext_instance_free);
Radek Krejcif538ce52019-03-05 10:46:14 +0100649 lysc_action_inout_free(ctx, &action->input);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200650 FREE_ARRAY(ctx, action->output_exts, lysc_ext_instance_free);
Radek Krejcif538ce52019-03-05 10:46:14 +0100651 lysc_action_inout_free(ctx, &action->output);
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100652}
653
Radek Krejcifc11bd72019-04-11 16:00:05 +0200654void
655lysc_notif_free(struct ly_ctx *ctx, struct lysc_notif *notif)
656{
657 struct lysc_node *child, *child_next;
658
659 FREE_STRING(ctx, notif->name);
660 FREE_STRING(ctx, notif->dsc);
661 FREE_STRING(ctx, notif->ref);
662 FREE_ARRAY(ctx, notif->iffeatures, lysc_iffeature_free);
663 FREE_ARRAY(ctx, notif->exts, lysc_ext_instance_free);
664 FREE_ARRAY(ctx, notif->musts, lysc_must_free);
665 LY_LIST_FOR_SAFE(notif->data, child_next, child) {
666 lysc_node_free(ctx, child);
667 }
668}
669
Radek Krejcicdfecd92018-11-26 11:27:32 +0100670static void
Radek Krejci19a96102018-11-15 13:38:09 +0100671lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
672{
673 struct lysc_node *child, *child_next;
674
675 LY_LIST_FOR_SAFE(node->child, child_next, child) {
676 lysc_node_free(ctx, child);
677 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100678 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100679 FREE_ARRAY(ctx, node->actions, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200680 FREE_ARRAY(ctx, node->notifs, lysc_notif_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100681}
682
683static void
684lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
685{
Radek Krejci58d171e2018-11-23 13:50:55 +0100686 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100687 if (node->type) {
688 lysc_type_free(ctx, node->type);
689 }
Radek Krejci58d171e2018-11-23 13:50:55 +0100690 FREE_STRING(ctx, node->units);
691 FREE_STRING(ctx, node->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100692}
693
Radek Krejci42452ac2018-11-28 17:09:52 +0100694static void
695lysc_node_leaflist_free(struct ly_ctx *ctx, struct lysc_node_leaflist *node)
696{
697 unsigned int u;
698
Radek Krejci42452ac2018-11-28 17:09:52 +0100699 FREE_ARRAY(ctx, node->musts, lysc_must_free);
700 if (node->type) {
701 lysc_type_free(ctx, node->type);
702 }
703 FREE_STRING(ctx, node->units);
704 LY_ARRAY_FOR(node->dflts, u) {
705 lydict_remove(ctx, node->dflts[u]);
706 }
707 LY_ARRAY_FREE(node->dflts);
708}
709
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100710static void
711lysc_node_list_free(struct ly_ctx *ctx, struct lysc_node_list *node)
712{
713 unsigned int u;
714 struct lysc_node *child, *child_next;
715
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100716 LY_LIST_FOR_SAFE(node->child, child_next, child) {
717 lysc_node_free(ctx, child);
718 }
719 FREE_ARRAY(ctx, node->musts, lysc_must_free);
720
721 LY_ARRAY_FREE(node->keys);
722 LY_ARRAY_FOR(node->uniques, u) {
723 LY_ARRAY_FREE(node->uniques[u]);
724 }
725 LY_ARRAY_FREE(node->uniques);
726
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100727 FREE_ARRAY(ctx, node->actions, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200728 FREE_ARRAY(ctx, node->notifs, lysc_notif_free);
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100729}
730
Radek Krejci056d0a82018-12-06 16:57:25 +0100731static void
732lysc_node_choice_free(struct ly_ctx *ctx, struct lysc_node_choice *node)
733{
734 struct lysc_node *child, *child_next;
735
Radek Krejci056d0a82018-12-06 16:57:25 +0100736 if (node->cases) {
737 LY_LIST_FOR_SAFE(node->cases->child, child_next, child) {
738 lysc_node_free(ctx, child);
739 }
740 LY_LIST_FOR_SAFE((struct lysc_node*)node->cases, child_next, child) {
741 lysc_node_free(ctx, child);
742 }
743 }
Radek Krejci9800fb82018-12-13 14:26:23 +0100744}
Radek Krejci056d0a82018-12-06 16:57:25 +0100745
Radek Krejci9800fb82018-12-13 14:26:23 +0100746static void
747lysc_node_anydata_free(struct ly_ctx *ctx, struct lysc_node_anydata *node)
748{
749 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +0100750}
751
Radek Krejci19a96102018-11-15 13:38:09 +0100752void
753lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node)
754{
755 /* common part */
756 FREE_STRING(ctx, node->name);
Radek Krejci12fb9142019-01-08 09:45:30 +0100757 FREE_STRING(ctx, node->dsc);
758 FREE_STRING(ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100759
760 /* nodetype-specific part */
761 switch(node->nodetype) {
762 case LYS_CONTAINER:
763 lysc_node_container_free(ctx, (struct lysc_node_container*)node);
764 break;
765 case LYS_LEAF:
766 lysc_node_leaf_free(ctx, (struct lysc_node_leaf*)node);
767 break;
Radek Krejci42452ac2018-11-28 17:09:52 +0100768 case LYS_LEAFLIST:
769 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist*)node);
770 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +0100771 case LYS_LIST:
772 lysc_node_list_free(ctx, (struct lysc_node_list*)node);
773 break;
Radek Krejci056d0a82018-12-06 16:57:25 +0100774 case LYS_CHOICE:
775 lysc_node_choice_free(ctx, (struct lysc_node_choice*)node);
776 break;
777 case LYS_CASE:
778 /* nothing specific */
779 break;
Radek Krejci9800fb82018-12-13 14:26:23 +0100780 case LYS_ANYDATA:
781 case LYS_ANYXML:
782 lysc_node_anydata_free(ctx, (struct lysc_node_anydata*)node);
783 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100784 default:
785 LOGINT(ctx);
786 }
787
Radek Krejci00b874b2019-02-12 10:54:50 +0100788 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci056d0a82018-12-06 16:57:25 +0100789 FREE_ARRAY(ctx, node->iffeatures, lysc_iffeature_free);
790 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100791 free(node);
792}
793
794static void
795lysc_module_free_(struct lysc_module *module)
796{
797 struct ly_ctx *ctx;
798 struct lysc_node *node, *node_next;
799
800 LY_CHECK_ARG_RET(NULL, module,);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100801 ctx = module->mod->ctx;
Radek Krejci19a96102018-11-15 13:38:09 +0100802
Radek Krejci19a96102018-11-15 13:38:09 +0100803 FREE_ARRAY(ctx, module->imports, lysc_import_free);
804 FREE_ARRAY(ctx, module->features, lysc_feature_free);
805 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
806
807 LY_LIST_FOR_SAFE(module->data, node_next, node) {
808 lysc_node_free(ctx, node);
809 }
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100810 FREE_ARRAY(ctx, module->rpcs, lysc_action_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200811 FREE_ARRAY(ctx, module->notifs, lysc_notif_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100812
813 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
814
815 free(module);
816}
817
818void
819lysc_module_free(struct lysc_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
820{
Radek Krejci9b042892019-02-13 14:28:44 +0100821 /* TODO use the destructor, this just suppress warning about unused parameter */
822 (void) private_destructor;
823
Radek Krejci19a96102018-11-15 13:38:09 +0100824 if (module) {
825 lysc_module_free_(module);
826 }
827}
828
829void
830lys_module_free(struct lys_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
831{
832 if (!module) {
833 return;
834 }
835
836 lysc_module_free(module->compiled, private_destructor);
Radek Krejci0af46292019-01-11 16:02:31 +0100837 FREE_ARRAY(module->ctx, module->off_features, lysc_feature_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100838 lysp_module_free(module->parsed);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100839
840 FREE_STRING(module->ctx, module->name);
Radek Krejci0af46292019-01-11 16:02:31 +0100841 FREE_STRING(module->ctx, module->revision);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100842 FREE_STRING(module->ctx, module->ns);
843 FREE_STRING(module->ctx, module->prefix);
844 FREE_STRING(module->ctx, module->filepath);
845 FREE_STRING(module->ctx, module->org);
846 FREE_STRING(module->ctx, module->contact);
847 FREE_STRING(module->ctx, module->dsc);
848 FREE_STRING(module->ctx, module->ref);
849
Radek Krejci19a96102018-11-15 13:38:09 +0100850 free(module);
851}