Coverage Report

Created: 2026-01-13 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libyang/src/tree_schema_free.c
Line
Count
Source
1
/**
2
 * @file tree_schema_free.c
3
 * @author Radek Krejci <rkrejci@cesnet.cz>
4
 * @brief Freeing functions for schema tree structures.
5
 *
6
 * Copyright (c) 2019 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 <stdlib.h>
16
17
#include "common.h"
18
#include "compat.h"
19
#include "dict.h"
20
#include "log.h"
21
#include "plugins_exts.h"
22
#include "plugins_types.h"
23
#include "tree.h"
24
#include "tree_data.h"
25
#include "tree_data_internal.h"
26
#include "tree_edit.h"
27
#include "tree_schema.h"
28
#include "tree_schema_internal.h"
29
#include "xml.h"
30
#include "xpath.h"
31
32
void lysp_grp_free(struct ly_ctx *ctx, struct lysp_node_grp *grp);
33
static void lysc_node_free_(struct ly_ctx *ctx, struct lysc_node *node);
34
35
static void
36
lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
37
0
{
38
0
    struct lysp_stmt *child, *next;
39
40
0
    lydict_remove(ctx, stmt->stmt);
41
0
    lydict_remove(ctx, stmt->arg);
42
0
    ly_free_prefix_data(stmt->format, stmt->prefix_data);
43
44
0
    LY_LIST_FOR_SAFE(stmt->child, next, child) {
45
0
        lysp_stmt_free(ctx, child);
46
0
    }
47
48
0
    free(stmt);
49
0
}
50
51
void
52
lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
53
0
{
54
0
    struct lysp_stmt *stmt, *next;
55
0
    struct lysp_node *node, *next_node;
56
57
0
    lydict_remove(ctx, ext->name);
58
0
    lydict_remove(ctx, ext->argument);
59
0
    ly_free_prefix_data(ext->format, ext->prefix_data);
60
0
    LY_LIST_FOR_SAFE(ext->parsed, next_node, node) {
61
0
        lysp_node_free(ctx, node);
62
0
    }
63
64
0
    LY_LIST_FOR_SAFE(ext->child, next, stmt) {
65
0
        lysp_stmt_free(ctx, stmt);
66
0
    }
67
0
}
68
69
void
70
lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
71
0
{
72
    /* imported module is freed directly from the context's list */
73
0
    lydict_remove(ctx, import->name);
74
0
    lydict_remove(ctx, import->prefix);
75
0
    lydict_remove(ctx, import->dsc);
76
0
    lydict_remove(ctx, import->ref);
77
0
    FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
78
0
}
79
80
/**
81
 * @brief Common function to erase include record in main module and submodule.
82
 *
83
 * There is a difference since the main module is expected to have the complete list if the included submodules and
84
 * the parsed submodule is shared with any include in a submodule. Therefore, the referenced submodules in the include
85
 * record are freed only from main module's records.
86
 *
87
 * @param[in] ctx libyang context
88
 * @param[in] include The include record to be erased, the record itself is not freed.
89
 * @param[in] main_module Flag to get know if the include record is placed in main module so also the referenced submodule
90
 * is supposed to be freed.
91
 */
92
static void
93
lysp_include_free_(struct ly_ctx *ctx, struct lysp_include *include, ly_bool main_module)
94
0
{
95
0
    if (main_module && include->submodule) {
96
0
        lysp_module_free((struct lysp_module *)include->submodule);
97
0
    }
98
0
    lydict_remove(ctx, include->name);
99
0
    lydict_remove(ctx, include->dsc);
100
0
    lydict_remove(ctx, include->ref);
101
0
    FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
102
0
}
103
104
void
105
lysp_include_free_submodule(struct ly_ctx *ctx, struct lysp_include *include)
106
0
{
107
0
    return lysp_include_free_(ctx, include, 0);
108
0
}
109
110
void
111
lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
112
0
{
113
0
    return lysp_include_free_(ctx, include, 1);
114
0
}
115
116
void
117
lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
118
0
{
119
0
    lydict_remove(ctx, rev->dsc);
120
0
    lydict_remove(ctx, rev->ref);
121
0
    FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
122
0
}
123
124
void
125
lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
126
0
{
127
0
    lydict_remove(ctx, ext->name);
128
0
    lydict_remove(ctx, ext->argname);
129
0
    lydict_remove(ctx, ext->dsc);
130
0
    lydict_remove(ctx, ext->ref);
131
0
    FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
132
0
    if (ext->compiled) {
133
0
        lysc_extension_free(ctx, &ext->compiled);
134
0
    }
135
0
}
136
137
void
138
lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
139
0
{
140
0
    lydict_remove(ctx, feat->name);
141
0
    FREE_ARRAY(ctx, feat->iffeatures, lysp_qname_free);
142
0
    FREE_ARRAY(ctx, feat->iffeatures_c, lysc_iffeature_free);
143
0
    LY_ARRAY_FREE(feat->depfeatures);
144
0
    lydict_remove(ctx, feat->dsc);
145
0
    lydict_remove(ctx, feat->ref);
146
0
    FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
147
0
}
148
149
void
150
lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
151
0
{
152
0
    lydict_remove(ctx, ident->name);
153
0
    FREE_ARRAY(ctx, ident->iffeatures, lysp_qname_free);
154
0
    FREE_STRINGS(ctx, ident->bases);
155
0
    lydict_remove(ctx, ident->dsc);
156
0
    lydict_remove(ctx, ident->ref);
157
0
    FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
158
0
}
159
160
void
161
lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
162
0
{
163
0
    lydict_remove(ctx, restr->arg.str);
164
0
    lydict_remove(ctx, restr->emsg);
165
0
    lydict_remove(ctx, restr->eapptag);
166
0
    lydict_remove(ctx, restr->dsc);
167
0
    lydict_remove(ctx, restr->ref);
168
0
    FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
169
0
}
170
171
static void
172
lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
173
0
{
174
0
    lydict_remove(ctx, item->name);
175
0
    lydict_remove(ctx, item->dsc);
176
0
    lydict_remove(ctx, item->ref);
177
0
    FREE_ARRAY(ctx, item->iffeatures, lysp_qname_free);
178
0
    FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
179
0
}
180
181
void lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type);
182
183
void
184
lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
185
0
{
186
0
    lydict_remove(ctx, type->name);
187
0
    FREE_MEMBER(ctx, type->range, lysp_restr_free);
188
0
    FREE_MEMBER(ctx, type->length, lysp_restr_free);
189
0
    FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
190
0
    FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
191
0
    FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
192
0
    lyxp_expr_free(ctx, type->path);
193
0
    FREE_STRINGS(ctx, type->bases);
194
0
    FREE_ARRAY(ctx, type->types, lysp_type_free);
195
0
    FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
196
0
    if (type->compiled) {
197
0
        lysc_type_free(ctx, type->compiled);
198
0
    }
199
0
}
200
201
void
202
lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
203
0
{
204
0
    lydict_remove(ctx, tpdf->name);
205
0
    lydict_remove(ctx, tpdf->units);
206
0
    lydict_remove(ctx, tpdf->dflt.str);
207
0
    lydict_remove(ctx, tpdf->dsc);
208
0
    lydict_remove(ctx, tpdf->ref);
209
0
    FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
210
211
0
    lysp_type_free(ctx, &tpdf->type);
212
213
0
}
214
215
void
216
lysp_grp_free(struct ly_ctx *ctx, struct lysp_node_grp *grp)
217
0
{
218
0
    struct lysp_node *node, *next;
219
220
0
    FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
221
0
    LY_LIST_FOR_SAFE((struct lysp_node *)grp->groupings, next, node) {
222
0
        lysp_node_free(ctx, node);
223
0
    }
224
0
    LY_LIST_FOR_SAFE(grp->child, next, node) {
225
0
        lysp_node_free(ctx, node);
226
0
    }
227
0
    LY_LIST_FOR_SAFE((struct lysp_node *)grp->actions, next, node) {
228
0
        lysp_node_free(ctx, node);
229
0
    }
230
0
    LY_LIST_FOR_SAFE((struct lysp_node *)grp->notifs, next, node) {
231
0
        lysp_node_free(ctx, node);
232
0
    }
233
0
}
234
235
void
236
lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
237
0
{
238
0
    lydict_remove(ctx, when->cond);
239
0
    lydict_remove(ctx, when->dsc);
240
0
    lydict_remove(ctx, when->ref);
241
0
    FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
242
0
}
243
244
void
245
lysp_augment_free(struct ly_ctx *ctx, struct lysp_node_augment *augment)
246
0
{
247
0
    struct lysp_node *node, *next;
248
249
0
    LY_LIST_FOR_SAFE(augment->child, next, node) {
250
0
        lysp_node_free(ctx, node);
251
0
    }
252
0
    LY_LIST_FOR_SAFE((struct lysp_node *)augment->actions, next, node) {
253
0
        lysp_node_free(ctx, node);
254
0
    }
255
0
    LY_LIST_FOR_SAFE((struct lysp_node *)augment->notifs, next, node) {
256
0
        lysp_node_free(ctx, node);
257
0
    }
258
0
}
259
260
void
261
lysp_qname_free(struct ly_ctx *ctx, struct lysp_qname *qname)
262
0
{
263
0
    if (qname) {
264
0
        lydict_remove(ctx, qname->str);
265
0
    }
266
0
}
267
268
void
269
lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
270
0
{
271
0
    struct lysp_deviate_add *add = (struct lysp_deviate_add *)d;
272
0
    struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl *)d;
273
274
0
    FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
275
0
    switch (d->mod) {
276
0
    case LYS_DEV_NOT_SUPPORTED:
277
        /* nothing to do */
278
0
        break;
279
0
    case LYS_DEV_ADD:
280
0
    case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
281
0
        lydict_remove(ctx, add->units);
282
0
        FREE_ARRAY(ctx, add->musts, lysp_restr_free);
283
0
        FREE_ARRAY(ctx, add->uniques, lysp_qname_free);
284
0
        FREE_ARRAY(ctx, add->dflts, lysp_qname_free);
285
0
        break;
286
0
    case LYS_DEV_REPLACE:
287
0
        FREE_MEMBER(ctx, rpl->type, lysp_type_free);
288
0
        lydict_remove(ctx, rpl->units);
289
0
        lysp_qname_free(ctx, &rpl->dflt);
290
0
        break;
291
0
    default:
292
0
        LOGINT(ctx);
293
0
        break;
294
0
    }
295
0
}
296
297
void
298
lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
299
0
{
300
0
    struct lysp_deviate *next, *iter;
301
302
0
    lydict_remove(ctx, dev->nodeid);
303
0
    lydict_remove(ctx, dev->dsc);
304
0
    lydict_remove(ctx, dev->ref);
305
0
    LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
306
0
        lysp_deviate_free(ctx, iter);
307
0
        free(iter);
308
0
    }
309
0
    FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
310
0
}
311
312
void
313
lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
314
0
{
315
0
    lydict_remove(ctx, ref->nodeid);
316
0
    lydict_remove(ctx, ref->dsc);
317
0
    lydict_remove(ctx, ref->ref);
318
0
    FREE_ARRAY(ctx, ref->iffeatures, lysp_qname_free);
319
0
    FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
320
0
    lydict_remove(ctx, ref->presence);
321
0
    FREE_ARRAY(ctx, ref->dflts, lysp_qname_free);
322
0
    FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
323
0
}
324
325
void
326
lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
327
0
{
328
0
    struct lysp_node *child, *next;
329
0
    struct lysp_restr *musts = lysp_node_musts(node);
330
0
    struct lysp_when *when = lysp_node_when(node);
331
332
0
    lydict_remove(ctx, node->name);
333
0
    lydict_remove(ctx, node->dsc);
334
0
    lydict_remove(ctx, node->ref);
335
0
    FREE_ARRAY(ctx, node->iffeatures, lysp_qname_free);
336
0
    FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
337
338
0
    FREE_MEMBER(ctx, when, lysp_when_free);
339
0
    FREE_ARRAY(ctx, musts, lysp_restr_free);
340
341
0
    switch (node->nodetype) {
342
0
    case LYS_CONTAINER:
343
0
        lydict_remove(ctx, ((struct lysp_node_container *)node)->presence);
344
0
        FREE_ARRAY(ctx, ((struct lysp_node_container *)node)->typedefs, lysp_tpdf_free);
345
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->groupings->node, next, child) {
346
0
            lysp_node_free(ctx, child);
347
0
        }
348
0
        LY_LIST_FOR_SAFE(((struct lysp_node_container *)node)->child, next, child) {
349
0
            lysp_node_free(ctx, child);
350
0
        }
351
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->actions->node, next, child) {
352
0
            lysp_node_free(ctx, child);
353
0
        }
354
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_container *)node)->notifs->node, next, child) {
355
0
            lysp_node_free(ctx, child);
356
0
        }
357
0
        break;
358
0
    case LYS_LEAF:
359
0
        lysp_type_free(ctx, &((struct lysp_node_leaf *)node)->type);
360
0
        lydict_remove(ctx, ((struct lysp_node_leaf *)node)->units);
361
0
        lydict_remove(ctx, ((struct lysp_node_leaf *)node)->dflt.str);
362
0
        break;
363
0
    case LYS_LEAFLIST:
364
0
        lysp_type_free(ctx, &((struct lysp_node_leaflist *)node)->type);
365
0
        lydict_remove(ctx, ((struct lysp_node_leaflist *)node)->units);
366
0
        FREE_ARRAY(ctx, ((struct lysp_node_leaflist *)node)->dflts, lysp_qname_free);
367
0
        break;
368
0
    case LYS_LIST:
369
0
        lydict_remove(ctx, ((struct lysp_node_list *)node)->key);
370
0
        FREE_ARRAY(ctx, ((struct lysp_node_list *)node)->typedefs, lysp_tpdf_free);
371
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->groupings->node, next, child) {
372
0
            lysp_node_free(ctx, child);
373
0
        }
374
0
        LY_LIST_FOR_SAFE(((struct lysp_node_list *)node)->child, next, child) {
375
0
            lysp_node_free(ctx, child);
376
0
        }
377
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->actions->node, next, child) {
378
0
            lysp_node_free(ctx, child);
379
0
        }
380
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_list *)node)->notifs->node, next, child) {
381
0
            lysp_node_free(ctx, child);
382
0
        }
383
0
        FREE_ARRAY(ctx, ((struct lysp_node_list *)node)->uniques, lysp_qname_free);
384
0
        break;
385
0
    case LYS_CHOICE:
386
0
        LY_LIST_FOR_SAFE(((struct lysp_node_choice *)node)->child, next, child) {
387
0
            lysp_node_free(ctx, child);
388
0
        }
389
0
        lydict_remove(ctx, ((struct lysp_node_choice *)node)->dflt.str);
390
0
        break;
391
0
    case LYS_CASE:
392
0
        LY_LIST_FOR_SAFE(((struct lysp_node_case *)node)->child, next, child) {
393
0
            lysp_node_free(ctx, child);
394
0
        }
395
0
        break;
396
0
    case LYS_ANYDATA:
397
0
    case LYS_ANYXML:
398
        /* nothing special to do */
399
0
        break;
400
0
    case LYS_USES:
401
0
        FREE_ARRAY(ctx, ((struct lysp_node_uses *)node)->refines, lysp_refine_free);
402
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_uses *)node)->augments->node, next, child) {
403
0
            lysp_node_free(ctx, child);
404
0
        }
405
0
        break;
406
0
    case LYS_RPC:
407
0
    case LYS_ACTION:
408
0
        FREE_ARRAY(ctx, ((struct lysp_node_action *)node)->typedefs, lysp_tpdf_free);
409
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_action *)node)->groupings->node, next, child) {
410
0
            lysp_node_free(ctx, child);
411
0
        }
412
0
        if (((struct lysp_node_action *)node)->input.nodetype) {
413
0
            lysp_node_free(ctx, &((struct lysp_node_action *)node)->input.node);
414
0
        }
415
0
        if (((struct lysp_node_action *)node)->output.nodetype) {
416
0
            lysp_node_free(ctx, &((struct lysp_node_action *)node)->output.node);
417
0
        }
418
0
        break;
419
0
    case LYS_INPUT:
420
0
    case LYS_OUTPUT:
421
0
        FREE_ARRAY(ctx, ((struct lysp_node_action_inout *)node)->typedefs, lysp_tpdf_free);
422
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_action_inout *)node)->groupings->node, next, child) {
423
0
            lysp_node_free(ctx, child);
424
0
        }
425
0
        LY_LIST_FOR_SAFE(((struct lysp_node_action_inout *)node)->child, next, child) {
426
0
            lysp_node_free(ctx, child);
427
0
        }
428
        /* do not free the node, it is never standalone but part of the action node */
429
0
        return;
430
0
    case LYS_NOTIF:
431
0
        FREE_ARRAY(ctx, ((struct lysp_node_notif *)node)->typedefs, lysp_tpdf_free);
432
0
        LY_LIST_FOR_SAFE(&((struct lysp_node_notif *)node)->groupings->node, next, child) {
433
0
            lysp_node_free(ctx, child);
434
0
        }
435
0
        LY_LIST_FOR_SAFE(((struct lysp_node_notif *)node)->child, next, child) {
436
0
            lysp_node_free(ctx, child);
437
0
        }
438
0
        break;
439
0
    case LYS_GROUPING:
440
0
        lysp_grp_free(ctx, (struct lysp_node_grp *)node);
441
0
        break;
442
0
    case LYS_AUGMENT:
443
0
        lysp_augment_free(ctx, ((struct lysp_node_augment *)node));
444
0
        break;
445
0
    default:
446
0
        LOGINT(ctx);
447
0
    }
448
449
0
    free(node);
450
0
}
451
452
void
453
lysp_module_free(struct lysp_module *module)
454
0
{
455
0
    struct ly_ctx *ctx;
456
0
    struct lysp_node *node, *next;
457
458
0
    if (!module) {
459
0
        return;
460
0
    }
461
0
    ctx = module->mod->ctx;
462
463
0
    FREE_ARRAY(ctx, module->imports, lysp_import_free);
464
0
    FREE_ARRAY(ctx, module->includes, module->is_submod ? lysp_include_free_submodule : lysp_include_free);
465
466
0
    FREE_ARRAY(ctx, module->revs, lysp_revision_free);
467
0
    FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
468
0
    FREE_ARRAY(ctx, module->features, lysp_feature_free);
469
0
    FREE_ARRAY(ctx, module->identities, lysp_ident_free);
470
0
    FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
471
0
    LY_LIST_FOR_SAFE((struct lysp_node *)module->groupings, next, node) {
472
0
        lysp_node_free(ctx, node);
473
0
    }
474
0
    LY_LIST_FOR_SAFE(module->data, next, node) {
475
0
        lysp_node_free(ctx, node);
476
0
    }
477
0
    LY_LIST_FOR_SAFE((struct lysp_node *)module->augments, next, node) {
478
0
        lysp_node_free(ctx, node);
479
0
    }
480
0
    LY_LIST_FOR_SAFE((struct lysp_node *)module->rpcs, next, node) {
481
0
        lysp_node_free(ctx, node);
482
0
    }
483
0
    LY_LIST_FOR_SAFE((struct lysp_node *)module->notifs, next, node) {
484
0
        lysp_node_free(ctx, node);
485
0
    }
486
0
    FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
487
0
    FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
488
489
0
    if (module->is_submod) {
490
0
        struct lysp_submodule *submod = (struct lysp_submodule *)module;
491
492
0
        lydict_remove(ctx, submod->name);
493
0
        lydict_remove(ctx, submod->filepath);
494
0
        lydict_remove(ctx, submod->prefix);
495
0
        lydict_remove(ctx, submod->org);
496
0
        lydict_remove(ctx, submod->contact);
497
0
        lydict_remove(ctx, submod->dsc);
498
0
        lydict_remove(ctx, submod->ref);
499
0
    }
500
501
0
    free(module);
502
0
}
503
504
void
505
lysc_extension_free(struct ly_ctx *ctx, struct lysc_ext **ext)
506
0
{
507
0
    if (--(*ext)->refcount) {
508
0
        return;
509
0
    }
510
0
    lydict_remove(ctx, (*ext)->name);
511
0
    lydict_remove(ctx, (*ext)->argname);
512
0
    FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
513
0
    free(*ext);
514
0
    *ext = NULL;
515
0
}
516
517
void
518
lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
519
0
{
520
0
    if (ext->def && ext->def->plugin && ext->def->plugin->free) {
521
0
        ext->def->plugin->free(ctx, ext);
522
0
    }
523
0
    if (ext->def) {
524
0
        lysc_extension_free(ctx, &ext->def);
525
0
    }
526
0
    lydict_remove(ctx, ext->argument);
527
0
    FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
528
0
}
529
530
void
531
lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
532
0
{
533
0
    LY_ARRAY_FREE(iff->features);
534
0
    free(iff->expr);
535
0
}
536
537
static void
538
lysc_when_free(struct ly_ctx *ctx, struct lysc_when **w)
539
0
{
540
0
    if (--(*w)->refcount) {
541
0
        return;
542
0
    }
543
0
    lyxp_expr_free(ctx, (*w)->cond);
544
0
    ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, (*w)->prefixes);
545
0
    lydict_remove(ctx, (*w)->dsc);
546
0
    lydict_remove(ctx, (*w)->ref);
547
0
    FREE_ARRAY(ctx, (*w)->exts, lysc_ext_instance_free);
548
0
    free(*w);
549
0
}
550
551
void
552
lysc_must_free(struct ly_ctx *ctx, struct lysc_must *must)
553
0
{
554
0
    lyxp_expr_free(ctx, must->cond);
555
0
    ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, must->prefixes);
556
0
    lydict_remove(ctx, must->emsg);
557
0
    lydict_remove(ctx, must->eapptag);
558
0
    lydict_remove(ctx, must->dsc);
559
0
    lydict_remove(ctx, must->ref);
560
0
    FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
561
0
}
562
563
void
564
lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident)
565
0
{
566
0
    lydict_remove(ctx, ident->name);
567
0
    lydict_remove(ctx, ident->dsc);
568
0
    lydict_remove(ctx, ident->ref);
569
0
    LY_ARRAY_FREE(ident->derived);
570
0
    FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
571
0
}
572
573
static void
574
lysc_range_free(struct ly_ctx *ctx, struct lysc_range *range)
575
0
{
576
0
    LY_ARRAY_FREE(range->parts);
577
0
    lydict_remove(ctx, range->eapptag);
578
0
    lydict_remove(ctx, range->emsg);
579
0
    lydict_remove(ctx, range->dsc);
580
0
    lydict_remove(ctx, range->ref);
581
0
    FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
582
0
}
583
584
static void
585
lysc_pattern_free(struct ly_ctx *ctx, struct lysc_pattern **pattern)
586
0
{
587
0
    if (--(*pattern)->refcount) {
588
0
        return;
589
0
    }
590
0
    pcre2_code_free((*pattern)->code);
591
0
    lydict_remove(ctx, (*pattern)->expr);
592
0
    lydict_remove(ctx, (*pattern)->eapptag);
593
0
    lydict_remove(ctx, (*pattern)->emsg);
594
0
    lydict_remove(ctx, (*pattern)->dsc);
595
0
    lydict_remove(ctx, (*pattern)->ref);
596
0
    FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
597
0
    free(*pattern);
598
0
}
599
600
static void
601
lysc_enum_item_free(struct ly_ctx *ctx, struct lysc_type_bitenum_item *item)
602
0
{
603
0
    lydict_remove(ctx, item->name);
604
0
    lydict_remove(ctx, item->dsc);
605
0
    lydict_remove(ctx, item->ref);
606
0
    FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
607
0
}
608
609
static void
610
lysc_type2_free(struct ly_ctx *ctx, struct lysc_type **type)
611
0
{
612
0
    lysc_type_free(ctx, *type);
613
0
}
614
615
void
616
lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
617
0
{
618
0
    if (--type->refcount) {
619
0
        return;
620
0
    }
621
622
0
    switch (type->basetype) {
623
0
    case LY_TYPE_BINARY:
624
0
        FREE_MEMBER(ctx, ((struct lysc_type_bin *)type)->length, lysc_range_free);
625
0
        break;
626
0
    case LY_TYPE_BITS:
627
0
        FREE_ARRAY(ctx, (struct lysc_type_bitenum_item *)((struct lysc_type_bits *)type)->bits, lysc_enum_item_free);
628
0
        break;
629
0
    case LY_TYPE_DEC64:
630
0
        FREE_MEMBER(ctx, ((struct lysc_type_dec *)type)->range, lysc_range_free);
631
0
        break;
632
0
    case LY_TYPE_STRING:
633
0
        FREE_MEMBER(ctx, ((struct lysc_type_str *)type)->length, lysc_range_free);
634
0
        FREE_ARRAY(ctx, ((struct lysc_type_str *)type)->patterns, lysc_pattern_free);
635
0
        break;
636
0
    case LY_TYPE_ENUM:
637
0
        FREE_ARRAY(ctx, ((struct lysc_type_enum *)type)->enums, lysc_enum_item_free);
638
0
        break;
639
0
    case LY_TYPE_INT8:
640
0
    case LY_TYPE_UINT8:
641
0
    case LY_TYPE_INT16:
642
0
    case LY_TYPE_UINT16:
643
0
    case LY_TYPE_INT32:
644
0
    case LY_TYPE_UINT32:
645
0
    case LY_TYPE_INT64:
646
0
    case LY_TYPE_UINT64:
647
0
        FREE_MEMBER(ctx, ((struct lysc_type_num *)type)->range, lysc_range_free);
648
0
        break;
649
0
    case LY_TYPE_IDENT:
650
0
        LY_ARRAY_FREE(((struct lysc_type_identityref *)type)->bases);
651
0
        break;
652
0
    case LY_TYPE_UNION:
653
0
        FREE_ARRAY(ctx, ((struct lysc_type_union *)type)->types, lysc_type2_free);
654
0
        break;
655
0
    case LY_TYPE_LEAFREF:
656
0
        lyxp_expr_free(ctx, ((struct lysc_type_leafref *)type)->path);
657
0
        ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, ((struct lysc_type_leafref *)type)->prefixes);
658
0
        break;
659
0
    case LY_TYPE_INST:
660
0
    case LY_TYPE_BOOL:
661
0
    case LY_TYPE_EMPTY:
662
0
    case LY_TYPE_UNKNOWN:
663
        /* nothing to do */
664
0
        break;
665
0
    }
666
667
0
    FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
668
0
    free(type);
669
0
}
670
671
void
672
lysc_node_action_inout_free(struct ly_ctx *ctx, struct lysc_node_action_inout *inout)
673
0
{
674
0
    struct lysc_node *child, *child_next;
675
676
0
    FREE_ARRAY(ctx, inout->musts, lysc_must_free);
677
0
    LY_LIST_FOR_SAFE(inout->child, child_next, child) {
678
0
        lysc_node_free_(ctx, child);
679
0
    }
680
0
}
681
682
void
683
lysc_node_action_free(struct ly_ctx *ctx, struct lysc_node_action *action)
684
0
{
685
0
    FREE_ARRAY(ctx, action->when, lysc_when_free);
686
0
    if (action->input.nodetype) {
687
0
        lysc_node_free_(ctx, &action->input.node);
688
0
    }
689
0
    if (action->output.nodetype) {
690
0
        lysc_node_free_(ctx, &action->output.node);
691
0
    }
692
0
}
693
694
void
695
lysc_node_notif_free(struct ly_ctx *ctx, struct lysc_node_notif *notif)
696
0
{
697
0
    struct lysc_node *child, *child_next;
698
699
0
    FREE_ARRAY(ctx, notif->when, lysc_when_free);
700
0
    FREE_ARRAY(ctx, notif->musts, lysc_must_free);
701
0
    LY_LIST_FOR_SAFE(notif->child, child_next, child) {
702
0
        lysc_node_free_(ctx, child);
703
0
    }
704
0
}
705
706
void
707
lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
708
0
{
709
0
    struct lysc_node *child, *child_next;
710
711
0
    LY_LIST_FOR_SAFE(node->child, child_next, child) {
712
0
        lysc_node_free_(ctx, child);
713
0
    }
714
0
    LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
715
0
        lysc_node_free_(ctx, child);
716
0
    }
717
0
    LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
718
0
        lysc_node_free_(ctx, child);
719
0
    }
720
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
721
0
    FREE_ARRAY(ctx, node->musts, lysc_must_free);
722
0
}
723
724
static void
725
lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
726
0
{
727
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
728
0
    FREE_ARRAY(ctx, node->musts, lysc_must_free);
729
0
    if (node->type) {
730
0
        lysc_type_free(ctx, node->type);
731
0
    }
732
0
    lydict_remove(ctx, node->units);
733
0
    if (node->dflt) {
734
0
        node->dflt->realtype->plugin->free(ctx, node->dflt);
735
0
        lysc_type_free(ctx, (struct lysc_type *)node->dflt->realtype);
736
0
        free(node->dflt);
737
0
    }
738
0
}
739
740
static void
741
lysc_node_leaflist_free(struct ly_ctx *ctx, struct lysc_node_leaflist *node)
742
0
{
743
0
    LY_ARRAY_COUNT_TYPE u;
744
745
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
746
0
    FREE_ARRAY(ctx, node->musts, lysc_must_free);
747
0
    if (node->type) {
748
0
        lysc_type_free(ctx, node->type);
749
0
    }
750
0
    lydict_remove(ctx, node->units);
751
0
    LY_ARRAY_FOR(node->dflts, u) {
752
0
        node->dflts[u]->realtype->plugin->free(ctx, node->dflts[u]);
753
0
        lysc_type_free(ctx, (struct lysc_type *)node->dflts[u]->realtype);
754
0
        free(node->dflts[u]);
755
0
    }
756
0
    LY_ARRAY_FREE(node->dflts);
757
0
}
758
759
static void
760
lysc_node_list_free(struct ly_ctx *ctx, struct lysc_node_list *node)
761
0
{
762
0
    LY_ARRAY_COUNT_TYPE u;
763
0
    struct lysc_node *child, *child_next;
764
765
0
    LY_LIST_FOR_SAFE(node->child, child_next, child) {
766
0
        lysc_node_free_(ctx, child);
767
0
    }
768
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
769
0
    FREE_ARRAY(ctx, node->musts, lysc_must_free);
770
771
0
    LY_ARRAY_FOR(node->uniques, u) {
772
0
        LY_ARRAY_FREE(node->uniques[u]);
773
0
    }
774
0
    LY_ARRAY_FREE(node->uniques);
775
776
0
    LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
777
0
        lysc_node_free_(ctx, child);
778
0
    }
779
0
    LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
780
0
        lysc_node_free_(ctx, child);
781
0
    }
782
0
}
783
784
static void
785
lysc_node_choice_free(struct ly_ctx *ctx, struct lysc_node_choice *node)
786
0
{
787
0
    struct lysc_node *child, *child_next;
788
789
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
790
0
    LY_LIST_FOR_SAFE((struct lysc_node *)node->cases, child_next, child) {
791
0
        lysc_node_free_(ctx, child);
792
0
    }
793
0
}
794
795
static void
796
lysc_node_case_free(struct ly_ctx *ctx, struct lysc_node_case *node)
797
0
{
798
0
    struct lysc_node *child, *child_next;
799
800
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
801
0
    LY_LIST_FOR_SAFE(node->child, child_next, child) {
802
0
        lysc_node_free_(ctx, child);
803
0
    }
804
0
}
805
806
static void
807
lysc_node_anydata_free(struct ly_ctx *ctx, struct lysc_node_anydata *node)
808
0
{
809
0
    FREE_ARRAY(ctx, node->when, lysc_when_free);
810
0
    FREE_ARRAY(ctx, node->musts, lysc_must_free);
811
0
}
812
813
static void
814
lysc_node_free_(struct ly_ctx *ctx, struct lysc_node *node)
815
0
{
816
0
    ly_bool inout = 0;
817
818
    /* common part */
819
0
    lydict_remove(ctx, node->name);
820
0
    lydict_remove(ctx, node->dsc);
821
0
    lydict_remove(ctx, node->ref);
822
823
    /* nodetype-specific part */
824
0
    switch (node->nodetype) {
825
0
    case LYS_CONTAINER:
826
0
        lysc_node_container_free(ctx, (struct lysc_node_container *)node);
827
0
        break;
828
0
    case LYS_LEAF:
829
0
        lysc_node_leaf_free(ctx, (struct lysc_node_leaf *)node);
830
0
        break;
831
0
    case LYS_LEAFLIST:
832
0
        lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist *)node);
833
0
        break;
834
0
    case LYS_LIST:
835
0
        lysc_node_list_free(ctx, (struct lysc_node_list *)node);
836
0
        break;
837
0
    case LYS_CHOICE:
838
0
        lysc_node_choice_free(ctx, (struct lysc_node_choice *)node);
839
0
        break;
840
0
    case LYS_CASE:
841
0
        lysc_node_case_free(ctx, (struct lysc_node_case *)node);
842
0
        break;
843
0
    case LYS_ANYDATA:
844
0
    case LYS_ANYXML:
845
0
        lysc_node_anydata_free(ctx, (struct lysc_node_anydata *)node);
846
0
        break;
847
0
    case LYS_RPC:
848
0
    case LYS_ACTION:
849
0
        lysc_node_action_free(ctx, (struct lysc_node_action *)node);
850
0
        break;
851
0
    case LYS_INPUT:
852
0
    case LYS_OUTPUT:
853
0
        lysc_node_action_inout_free(ctx, (struct lysc_node_action_inout *)node);
854
0
        inout = 1;
855
0
        break;
856
0
    case LYS_NOTIF:
857
0
        lysc_node_notif_free(ctx, (struct lysc_node_notif *)node);
858
0
        break;
859
0
    default:
860
0
        LOGINT(ctx);
861
0
    }
862
863
0
    FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
864
865
0
    if (!inout) {
866
0
        free(node);
867
0
    }
868
0
}
869
870
void
871
lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node, ly_bool unlink)
872
0
{
873
0
    struct lysc_node *iter, **child_p;
874
875
0
    if (node->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
876
        /* nothing to do - inouts are part of actions and cannot be unlinked/freed separately */
877
0
        return;
878
0
    }
879
880
0
    if (unlink) {
881
        /* unlink from siblings */
882
0
        if (node->prev->next) {
883
0
            node->prev->next = node->next;
884
0
        }
885
0
        if (node->next) {
886
0
            node->next->prev = node->prev;
887
0
        } else {
888
            /* unlinking the last node */
889
0
            if (node->parent) {
890
0
                if (node->nodetype == LYS_ACTION) {
891
0
                    iter = (struct lysc_node *)lysc_node_actions(node->parent);
892
0
                } else if (node->nodetype == LYS_NOTIF) {
893
0
                    iter = (struct lysc_node *)lysc_node_notifs(node->parent);
894
0
                } else {
895
0
                    iter = (struct lysc_node *)lysc_node_child(node->parent);
896
0
                }
897
0
                LY_CHECK_ERR_RET(!iter, LOGINT(ctx), );
898
0
            } else if (node->nodetype == LYS_RPC) {
899
0
                iter = (struct lysc_node *)node->module->compiled->rpcs;
900
0
            } else if (node->nodetype == LYS_NOTIF) {
901
0
                iter = (struct lysc_node *)node->module->compiled->notifs;
902
0
            } else {
903
0
                iter = node->module->compiled->data;
904
0
            }
905
            /* update the "last" pointer from the first node */
906
0
            iter->prev = node->prev;
907
0
        }
908
909
        /* unlink from parent */
910
0
        if (node->parent) {
911
0
            if (node->nodetype == LYS_ACTION) {
912
0
                child_p = (struct lysc_node **)lysc_node_actions_p(node->parent);
913
0
            } else if (node->nodetype == LYS_NOTIF) {
914
0
                child_p = (struct lysc_node **)lysc_node_notifs_p(node->parent);
915
0
            } else {
916
0
                child_p = lysc_node_child_p(node->parent);
917
0
            }
918
0
        } else if (node->nodetype == LYS_RPC) {
919
0
            child_p = (struct lysc_node **)&node->module->compiled->rpcs;
920
0
        } else if (node->nodetype == LYS_NOTIF) {
921
0
            child_p = (struct lysc_node **)&node->module->compiled->notifs;
922
0
        } else {
923
0
            child_p = &node->module->compiled->data;
924
0
        }
925
0
        if (child_p && (*child_p == node)) {
926
            /* the node is the first child */
927
0
            *child_p = node->next;
928
0
        }
929
0
    }
930
931
0
    lysc_node_free_(ctx, node);
932
0
}
933
934
void
935
lysc_module_free(struct lysc_module *module)
936
0
{
937
0
    struct ly_ctx *ctx;
938
0
    struct lysc_node *node, *node_next;
939
940
0
    if (!module) {
941
0
        return;
942
0
    }
943
944
0
    ctx = module->mod->ctx;
945
946
0
    LY_LIST_FOR_SAFE(module->data, node_next, node) {
947
0
        lysc_node_free_(ctx, node);
948
0
    }
949
0
    LY_LIST_FOR_SAFE((struct lysc_node *)module->rpcs, node_next, node) {
950
0
        lysc_node_free_(ctx, node);
951
0
    }
952
0
    LY_LIST_FOR_SAFE((struct lysc_node *)module->notifs, node_next, node) {
953
0
        lysc_node_free_(ctx, node);
954
0
    }
955
0
    FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
956
957
0
    free(module);
958
0
}
959
960
void
961
lys_module_free(struct lys_module *module)
962
0
{
963
0
    if (!module) {
964
0
        return;
965
0
    }
966
967
0
    lysc_module_free(module->compiled);
968
0
    FREE_ARRAY(module->ctx, module->identities, lysc_ident_free);
969
0
    lysp_module_free(module->parsed);
970
971
0
    LY_ARRAY_FREE(module->augmented_by);
972
0
    LY_ARRAY_FREE(module->deviated_by);
973
974
0
    lydict_remove(module->ctx, module->name);
975
0
    lydict_remove(module->ctx, module->revision);
976
0
    lydict_remove(module->ctx, module->ns);
977
0
    lydict_remove(module->ctx, module->prefix);
978
0
    lydict_remove(module->ctx, module->filepath);
979
0
    lydict_remove(module->ctx, module->org);
980
0
    lydict_remove(module->ctx, module->contact);
981
0
    lydict_remove(module->ctx, module->dsc);
982
0
    lydict_remove(module->ctx, module->ref);
983
984
0
    free(module);
985
0
}
986
987
API void
988
lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
989
0
{
990
0
    LY_ARRAY_COUNT_TYPE u;
991
992
0
    LY_ARRAY_FOR(substmts, u) {
993
0
        if (!substmts[u].storage) {
994
0
            continue;
995
0
        }
996
997
0
        switch (substmts[u].stmt) {
998
0
        case LY_STMT_ACTION:
999
0
        case LY_STMT_ANYDATA:
1000
0
        case LY_STMT_ANYXML:
1001
0
        case LY_STMT_CONTAINER:
1002
0
        case LY_STMT_CHOICE:
1003
0
        case LY_STMT_LEAF:
1004
0
        case LY_STMT_LEAF_LIST:
1005
0
        case LY_STMT_LIST:
1006
0
        case LY_STMT_NOTIFICATION:
1007
0
        case LY_STMT_RPC:
1008
0
        case LY_STMT_USES: {
1009
0
            struct lysc_node *child, *child_next;
1010
1011
0
            LY_LIST_FOR_SAFE(*((struct lysc_node **)substmts[u].storage), child_next, child) {
1012
0
                lysc_node_free_(ctx, child);
1013
0
            }
1014
0
            break;
1015
0
        }
1016
0
        case LY_STMT_CONFIG:
1017
0
        case LY_STMT_STATUS:
1018
            /* nothing to do */
1019
0
            break;
1020
0
        case LY_STMT_DESCRIPTION:
1021
0
        case LY_STMT_REFERENCE:
1022
0
        case LY_STMT_UNITS:
1023
0
            if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1024
                /* single item */
1025
0
                const char *str = *((const char **)substmts[u].storage);
1026
0
                if (!str) {
1027
0
                    break;
1028
0
                }
1029
0
                lydict_remove(ctx, str);
1030
0
            } else {
1031
                /* multiple items */
1032
0
                const char **strs = *((const char ***)substmts[u].storage);
1033
0
                if (!strs) {
1034
0
                    break;
1035
0
                }
1036
0
                FREE_STRINGS(ctx, strs);
1037
0
            }
1038
0
            break;
1039
0
        case LY_STMT_IF_FEATURE: {
1040
0
            struct lysc_iffeature *iff = *((struct lysc_iffeature **)substmts[u].storage);
1041
0
            if (!iff) {
1042
0
                break;
1043
0
            }
1044
0
            if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1045
                /* single item */
1046
0
                lysc_iffeature_free(ctx, iff);
1047
0
                free(iff);
1048
0
            } else {
1049
                /* multiple items */
1050
0
                FREE_ARRAY(ctx, iff, lysc_iffeature_free);
1051
0
            }
1052
0
            break;
1053
0
        case LY_STMT_TYPE:
1054
0
            if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1055
                /* single item */
1056
0
                struct lysc_type *type = *((struct lysc_type **)substmts[u].storage);
1057
0
                if (!type) {
1058
0
                    break;
1059
0
                }
1060
0
                lysc_type_free(ctx, type);
1061
0
            } else {
1062
                /* multiple items */
1063
0
                struct lysc_type **types = *((struct lysc_type ***)substmts[u].storage);
1064
0
                if (!types) {
1065
0
                    break;
1066
0
                }
1067
0
                FREE_ARRAY(ctx, types, lysc_type2_free);
1068
0
            }
1069
0
            break;
1070
0
        }
1071
1072
        /* TODO other statements */
1073
0
        default:
1074
0
            LOGINT(ctx);
1075
0
        }
1076
0
    }
1077
1078
0
    LY_ARRAY_FREE(substmts);
1079
0
}
1080
1081
void
1082
yang_parser_ctx_free(struct lys_yang_parser_ctx *ctx)
1083
0
{
1084
0
    if (ctx) {
1085
0
        free(ctx);
1086
0
    }
1087
0
}
1088
1089
void
1090
yin_parser_ctx_free(struct lys_yin_parser_ctx *ctx)
1091
0
{
1092
0
    if (ctx) {
1093
0
        lyxml_ctx_free(ctx->xmlctx);
1094
0
        free(ctx);
1095
0
    }
1096
0
}