blob: 171686905127e02a1e457acc64c5e224994b2058 [file] [log] [blame]
Radek Krejci19a96102018-11-15 13:38:09 +01001/**
Radek Krejcie7b95092019-05-15 11:03:07 +02002 * @file tree_schema_free.c
Radek Krejci19a96102018-11-15 13:38:09 +01003 * @author Radek Krejci <rkrejci@cesnet.cz>
Michal Vaskoc636ea42022-09-16 10:20:31 +02004 * @author Michal Vasko <mvasko@cesnet.cz>
Radek Krejcie7b95092019-05-15 11:03:07 +02005 * @brief Freeing functions for schema tree structures.
Radek Krejci19a96102018-11-15 13:38:09 +01006 *
Michal Vaskoc636ea42022-09-16 10:20:31 +02007 * Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
Radek Krejci19a96102018-11-15 13:38:09 +01008 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
15
Michal Vaskoc636ea42022-09-16 10:20:31 +020016#include "tree_schema_free.h"
17
Michal Vaskoee757602021-06-10 14:38:19 +020018#include <assert.h>
Radek Krejcie7b95092019-05-15 11:03:07 +020019#include <stdlib.h>
20
Radek Krejci535ea9f2020-05-29 16:01:05 +020021#include "common.h"
Michal Vasko69730152020-10-09 16:30:07 +020022#include "compat.h"
Radek Krejci77114102021-03-10 15:21:57 +010023#include "dict.h"
Radek Krejci47fab892020-11-05 17:02:41 +010024#include "log.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020025#include "plugins_exts.h"
26#include "plugins_types.h"
Radek Krejcie7b95092019-05-15 11:03:07 +020027#include "tree.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020028#include "tree_data.h"
Michal Vaskofc2cd072021-02-24 13:17:17 +010029#include "tree_data_internal.h"
Radek Krejci859a15a2021-03-05 20:56:59 +010030#include "tree_edit.h"
Radek Krejcie7b95092019-05-15 11:03:07 +020031#include "tree_schema.h"
Radek Krejci19a96102018-11-15 13:38:09 +010032#include "tree_schema_internal.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020033#include "xml.h"
Radek Krejci19a96102018-11-15 13:38:09 +010034#include "xpath.h"
35
Michal Vaskoc636ea42022-09-16 10:20:31 +020036static void lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext);
37static void lysc_node_free_(struct lysf_ctx *ctx, struct lysc_node *node);
Radek Krejci19a96102018-11-15 13:38:09 +010038
Michal Vaskoc636ea42022-09-16 10:20:31 +020039void
40lysp_qname_free(struct ly_ctx *ctx, struct lysp_qname *qname)
41{
42 if (qname) {
43 lydict_remove(ctx, qname->str);
44 }
45}
46
47/**
48 * @brief Free the parsed generic statement structure.
49 *
50 * @param[in] ctx libyang context.
51 * @param[in] grp Parsed schema statement structure to free. Note that the structure itself is not freed.
52 */
Radek Krejci19a96102018-11-15 13:38:09 +010053static void
54lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
55{
56 struct lysp_stmt *child, *next;
57
Michal Vaskoe180ed02021-02-05 16:31:20 +010058 lydict_remove(ctx, stmt->stmt);
59 lydict_remove(ctx, stmt->arg);
Michal Vaskofc2cd072021-02-24 13:17:17 +010060 ly_free_prefix_data(stmt->format, stmt->prefix_data);
Radek Krejci19a96102018-11-15 13:38:09 +010061
62 LY_LIST_FOR_SAFE(stmt->child, next, child) {
63 lysp_stmt_free(ctx, child);
64 }
65
66 free(stmt);
67}
68
Michal Vaskoc636ea42022-09-16 10:20:31 +020069void
70lysp_ext_instance_free(struct lysf_ctx *ctx, struct lysp_ext_instance *ext)
Radek Krejci19a96102018-11-15 13:38:09 +010071{
72 struct lysp_stmt *stmt, *next;
aPiecek60d9d672021-04-27 15:49:57 +020073 struct lysp_node *node, *next_node;
Radek Krejci19a96102018-11-15 13:38:09 +010074
Michal Vaskoc636ea42022-09-16 10:20:31 +020075 lydict_remove(ctx->ctx, ext->name);
76 lydict_remove(ctx->ctx, ext->argument);
Michal Vaskofc2cd072021-02-24 13:17:17 +010077 ly_free_prefix_data(ext->format, ext->prefix_data);
aPiecek60d9d672021-04-27 15:49:57 +020078 LY_LIST_FOR_SAFE(ext->parsed, next_node, node) {
79 lysp_node_free(ctx, node);
80 }
Radek Krejci19a96102018-11-15 13:38:09 +010081
82 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
Michal Vaskoc636ea42022-09-16 10:20:31 +020083 lysp_stmt_free(ctx->ctx, stmt);
Radek Krejci19a96102018-11-15 13:38:09 +010084 }
85}
86
Michal Vaskoc636ea42022-09-16 10:20:31 +020087/**
88 * @brief Free the parsed import structure.
89 *
90 * @param[in] ctx Free context.
91 * @param[in] import Parsed schema import structure to free. Note that the structure itself is not freed.
92 */
Michal Vasko12ef5362022-09-16 15:13:58 +020093static void
Michal Vaskoc636ea42022-09-16 10:20:31 +020094lysp_import_free(struct lysf_ctx *ctx, struct lysp_import *import)
Radek Krejci19a96102018-11-15 13:38:09 +010095{
96 /* imported module is freed directly from the context's list */
Michal Vaskoc636ea42022-09-16 10:20:31 +020097 lydict_remove(ctx->ctx, import->name);
98 lydict_remove(ctx->ctx, import->prefix);
99 lydict_remove(ctx->ctx, import->dsc);
100 lydict_remove(ctx->ctx, import->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100101 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
102}
103
Radek Krejci771928a2021-01-19 13:42:36 +0100104/**
105 * @brief Common function to erase include record in main module and submodule.
106 *
107 * There is a difference since the main module is expected to have the complete list if the included submodules and
108 * the parsed submodule is shared with any include in a submodule. Therefore, the referenced submodules in the include
109 * record are freed only from main module's records.
110 *
111 * @param[in] ctx libyang context
112 * @param[in] include The include record to be erased, the record itself is not freed.
113 * @param[in] main_module Flag to get know if the include record is placed in main module so also the referenced submodule
114 * is supposed to be freed.
115 */
116static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200117lysp_include_free_(struct lysf_ctx *ctx, struct lysp_include *include, ly_bool main_module)
Radek Krejci19a96102018-11-15 13:38:09 +0100118{
Radek Krejci771928a2021-01-19 13:42:36 +0100119 if (main_module && include->submodule) {
Michal Vaskoc636ea42022-09-16 10:20:31 +0200120 lysp_module_free(ctx, (struct lysp_module *)include->submodule);
Radek Krejci19a96102018-11-15 13:38:09 +0100121 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200122 lydict_remove(ctx->ctx, include->name);
123 lydict_remove(ctx->ctx, include->dsc);
124 lydict_remove(ctx->ctx, include->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100125 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
126}
127
Michal Vaskoc636ea42022-09-16 10:20:31 +0200128/**
129 * @brief Free the parsed include structure of a submodule.
130 *
131 * @param[in] ctx Free context.
132 * @param[in] include Parsed schema include structure to free. Note that the structure itself is not freed.
133 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200134static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200135lysp_include_free_submodule(struct lysf_ctx *ctx, struct lysp_include *include)
Radek Krejci771928a2021-01-19 13:42:36 +0100136{
Michal Vaskoa0a498b2021-09-22 12:17:48 +0200137 lysp_include_free_(ctx, include, 0);
Radek Krejci771928a2021-01-19 13:42:36 +0100138}
139
Michal Vaskoc636ea42022-09-16 10:20:31 +0200140/**
141 * @brief Free the parsed include structure of a module.
142 *
143 * @param[in] ctx Free context.
144 * @param[in] include Parsed schema include structure to free. Note that the structure itself is not freed.
145 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200146static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200147lysp_include_free(struct lysf_ctx *ctx, struct lysp_include *include)
Radek Krejci771928a2021-01-19 13:42:36 +0100148{
Michal Vaskoa0a498b2021-09-22 12:17:48 +0200149 lysp_include_free_(ctx, include, 1);
Radek Krejci771928a2021-01-19 13:42:36 +0100150}
151
Michal Vaskoc636ea42022-09-16 10:20:31 +0200152/**
153 * @brief Free the parsed revision structure.
154 *
155 * @param[in] ctx Free context.
156 * @param[in] rev Parsed schema revision structure to free. Note that the structure itself is not freed.
157 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200158static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200159lysp_revision_free(struct lysf_ctx *ctx, struct lysp_revision *rev)
Radek Krejci19a96102018-11-15 13:38:09 +0100160{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200161 lydict_remove(ctx->ctx, rev->dsc);
162 lydict_remove(ctx->ctx, rev->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100163 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
164}
165
Michal Vaskoc636ea42022-09-16 10:20:31 +0200166/**
167 * @brief Free the parsed ext structure.
168 *
169 * @param[in] ctx Free context.
170 * @param[in] ext Parsed schema ext structure to free. Note that the structure itself is not freed.
171 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200172static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200173lysp_ext_free(struct lysf_ctx *ctx, struct lysp_ext *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100174{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200175 lydict_remove(ctx->ctx, ext->name);
176 lydict_remove(ctx->ctx, ext->argname);
177 lydict_remove(ctx->ctx, ext->dsc);
178 lydict_remove(ctx->ctx, ext->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100179 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
Michal Vasko5fe75f12020-03-02 13:52:37 +0100180 if (ext->compiled) {
181 lysc_extension_free(ctx, &ext->compiled);
182 }
Radek Krejci19a96102018-11-15 13:38:09 +0100183}
184
Michal Vaskoc636ea42022-09-16 10:20:31 +0200185/**
186 * @brief Free the parsed feature structure.
187 *
188 * @param[in] ctx Free context.
189 * @param[in] feat Parsed schema feature structure to free. Note that the structure itself is not freed.
190 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200191static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200192lysp_feature_free(struct lysf_ctx *ctx, struct lysp_feature *feat)
Radek Krejci19a96102018-11-15 13:38:09 +0100193{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200194 lydict_remove(ctx->ctx, feat->name);
195 FREE_ARRAY(ctx->ctx, feat->iffeatures, lysp_qname_free);
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100196 FREE_ARRAY(ctx, feat->iffeatures_c, lysc_iffeature_free);
197 LY_ARRAY_FREE(feat->depfeatures);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200198 lydict_remove(ctx->ctx, feat->dsc);
199 lydict_remove(ctx->ctx, feat->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100200 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
201}
202
Michal Vaskoc636ea42022-09-16 10:20:31 +0200203/**
204 * @brief Free the parsed identity structure.
205 *
206 * @param[in] ctx Free context.
207 * @param[in] ident Parsed schema identity structure to free. Note that the structure itself is not freed.
208 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200209static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200210lysp_ident_free(struct lysf_ctx *ctx, struct lysp_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100211{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200212 lydict_remove(ctx->ctx, ident->name);
213 FREE_ARRAY(ctx->ctx, ident->iffeatures, lysp_qname_free);
214 FREE_STRINGS(ctx->ctx, ident->bases);
215 lydict_remove(ctx->ctx, ident->dsc);
216 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100217 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
218}
219
Michal Vasko7f45cf22020-10-01 12:49:44 +0200220void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200221lysp_restr_free(struct lysf_ctx *ctx, struct lysp_restr *restr)
Radek Krejci19a96102018-11-15 13:38:09 +0100222{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200223 lydict_remove(ctx->ctx, restr->arg.str);
224 lydict_remove(ctx->ctx, restr->emsg);
225 lydict_remove(ctx->ctx, restr->eapptag);
226 lydict_remove(ctx->ctx, restr->dsc);
227 lydict_remove(ctx->ctx, restr->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100228 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
229}
230
Michal Vaskoc636ea42022-09-16 10:20:31 +0200231/**
232 * @brief Free the parsed type enum item.
233 *
234 * @param[in] ctx Free context.
235 * @param[in] item Parsed schema type enum item to free. Note that the structure itself is not freed.
236 */
Radek Krejci19a96102018-11-15 13:38:09 +0100237static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200238lysp_type_enum_free(struct lysf_ctx *ctx, struct lysp_type_enum *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100239{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200240 lydict_remove(ctx->ctx, item->name);
241 lydict_remove(ctx->ctx, item->dsc);
242 lydict_remove(ctx->ctx, item->ref);
243 FREE_ARRAY(ctx->ctx, item->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100244 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
245}
246
David Sedlák32488102019-07-15 17:44:10 +0200247void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200248lysp_type_free(struct lysf_ctx *ctx, struct lysp_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100249{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200250 lydict_remove(ctx->ctx, type->name);
Radek Krejci19a96102018-11-15 13:38:09 +0100251 FREE_MEMBER(ctx, type->range, lysp_restr_free);
252 FREE_MEMBER(ctx, type->length, lysp_restr_free);
253 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
254 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
255 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200256 lyxp_expr_free(ctx->ctx, type->path);
257 FREE_STRINGS(ctx->ctx, type->bases);
Radek Krejci19a96102018-11-15 13:38:09 +0100258 FREE_ARRAY(ctx, type->types, lysp_type_free);
259 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
260 if (type->compiled) {
261 lysc_type_free(ctx, type->compiled);
262 }
263}
264
Michal Vaskoc636ea42022-09-16 10:20:31 +0200265/**
266 * @brief Free the parsed typedef structure.
267 *
268 * @param[in] ctx Free context.
269 * @param[in] tpdf Parsed schema typedef structure to free. Note that the structure itself is not freed.
270 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200271static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200272lysp_tpdf_free(struct lysf_ctx *ctx, struct lysp_tpdf *tpdf)
Radek Krejci19a96102018-11-15 13:38:09 +0100273{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200274 lydict_remove(ctx->ctx, tpdf->name);
275 lydict_remove(ctx->ctx, tpdf->units);
276 lydict_remove(ctx->ctx, tpdf->dflt.str);
277 lydict_remove(ctx->ctx, tpdf->dsc);
278 lydict_remove(ctx->ctx, tpdf->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100279 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
280
281 lysp_type_free(ctx, &tpdf->type);
282
283}
284
Michal Vaskoc636ea42022-09-16 10:20:31 +0200285/**
286 * @brief Free the parsed grouping structure.
287 *
288 * @param[in] ctx Free context.
289 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
290 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200291static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200292lysp_grp_free(struct lysf_ctx *ctx, struct lysp_node_grp *grp)
Radek Krejci19a96102018-11-15 13:38:09 +0100293{
294 struct lysp_node *node, *next;
295
Radek Krejci19a96102018-11-15 13:38:09 +0100296 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100297 LY_LIST_FOR_SAFE((struct lysp_node *)grp->groupings, next, node) {
298 lysp_node_free(ctx, node);
299 }
Radek Krejci01180ac2021-01-27 08:48:22 +0100300 LY_LIST_FOR_SAFE(grp->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100301 lysp_node_free(ctx, node);
302 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100303 LY_LIST_FOR_SAFE((struct lysp_node *)grp->actions, next, node) {
304 lysp_node_free(ctx, node);
305 }
306 LY_LIST_FOR_SAFE((struct lysp_node *)grp->notifs, next, node) {
307 lysp_node_free(ctx, node);
308 }
Radek Krejci19a96102018-11-15 13:38:09 +0100309}
310
Radek Krejcif09e4e82019-06-14 15:08:11 +0200311void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200312lysp_when_free(struct lysf_ctx *ctx, struct lysp_when *when)
Radek Krejci19a96102018-11-15 13:38:09 +0100313{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200314 lydict_remove(ctx->ctx, when->cond);
315 lydict_remove(ctx->ctx, when->dsc);
316 lydict_remove(ctx->ctx, when->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100317 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
318}
319
Michal Vaskoc636ea42022-09-16 10:20:31 +0200320/**
321 * @brief Free the parsed augment structure.
322 *
323 * @param[in] ctx Free context.
324 * @param[in] aug Parsed schema augment structure to free. Note that the structure itself is not freed.
325 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200326static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200327lysp_augment_free(struct lysf_ctx *ctx, struct lysp_node_augment *aug)
Radek Krejci19a96102018-11-15 13:38:09 +0100328{
329 struct lysp_node *node, *next;
330
Michal Vaskoc636ea42022-09-16 10:20:31 +0200331 LY_LIST_FOR_SAFE(aug->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100332 lysp_node_free(ctx, node);
333 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200334 LY_LIST_FOR_SAFE((struct lysp_node *)aug->actions, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100335 lysp_node_free(ctx, node);
336 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200337 LY_LIST_FOR_SAFE((struct lysp_node *)aug->notifs, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100338 lysp_node_free(ctx, node);
339 }
Radek Krejci19a96102018-11-15 13:38:09 +0100340}
341
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200342void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200343lysp_deviate_free(struct lysf_ctx *ctx, struct lysp_deviate *d)
Radek Krejci19a96102018-11-15 13:38:09 +0100344{
Michal Vasko22df3f02020-08-24 13:29:22 +0200345 struct lysp_deviate_add *add = (struct lysp_deviate_add *)d;
346 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl *)d;
Radek Krejci19a96102018-11-15 13:38:09 +0100347
Michal Vasko12ef5362022-09-16 15:13:58 +0200348 if (!d) {
349 return;
350 }
351
Radek Krejci19a96102018-11-15 13:38:09 +0100352 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
Michal Vaskod989ba02020-08-24 10:59:24 +0200353 switch (d->mod) {
Radek Krejci19a96102018-11-15 13:38:09 +0100354 case LYS_DEV_NOT_SUPPORTED:
355 /* nothing to do */
356 break;
357 case LYS_DEV_ADD:
358 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
Michal Vaskoc636ea42022-09-16 10:20:31 +0200359 lydict_remove(ctx->ctx, add->units);
Radek Krejci19a96102018-11-15 13:38:09 +0100360 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200361 FREE_ARRAY(ctx->ctx, add->uniques, lysp_qname_free);
362 FREE_ARRAY(ctx->ctx, add->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100363 break;
364 case LYS_DEV_REPLACE:
365 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200366 lydict_remove(ctx->ctx, rpl->units);
367 lysp_qname_free(ctx->ctx, &rpl->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100368 break;
369 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200370 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100371 break;
372 }
373}
374
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200375void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200376lysp_deviation_free(struct lysf_ctx *ctx, struct lysp_deviation *dev)
Radek Krejci19a96102018-11-15 13:38:09 +0100377{
378 struct lysp_deviate *next, *iter;
379
Michal Vaskoc636ea42022-09-16 10:20:31 +0200380 lydict_remove(ctx->ctx, dev->nodeid);
381 lydict_remove(ctx->ctx, dev->dsc);
382 lydict_remove(ctx->ctx, dev->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100383 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
384 lysp_deviate_free(ctx, iter);
385 free(iter);
386 }
387 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
388}
389
Michal Vaskoc636ea42022-09-16 10:20:31 +0200390/**
391 * @brief Free the parsed refine structure.
392 *
393 * @param[in] ctx Free context.
394 * @param[in] ref Parsed schema refine structure to free. Note that the structure itself is not freed.
395 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200396static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200397lysp_refine_free(struct lysf_ctx *ctx, struct lysp_refine *ref)
Radek Krejci19a96102018-11-15 13:38:09 +0100398{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200399 lydict_remove(ctx->ctx, ref->nodeid);
400 lydict_remove(ctx->ctx, ref->dsc);
401 lydict_remove(ctx->ctx, ref->ref);
402 FREE_ARRAY(ctx->ctx, ref->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100403 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200404 lydict_remove(ctx->ctx, ref->presence);
405 FREE_ARRAY(ctx->ctx, ref->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100406 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
407}
408
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200409void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200410lysp_node_free(struct lysf_ctx *ctx, struct lysp_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +0100411{
412 struct lysp_node *child, *next;
Michal Vasko856ea972021-06-09 09:44:30 +0200413 struct lysp_node_container *cont;
414 struct lysp_node_leaf *leaf;
415 struct lysp_node_leaflist *llist;
416 struct lysp_node_list *list;
417 struct lysp_node_choice *choice;
418 struct lysp_node_case *cas;
419 struct lysp_node_uses *uses;
420 struct lysp_node_action *act;
421 struct lysp_node_action_inout *inout;
422 struct lysp_node_notif *notif;
Radek Krejci9a3823e2021-01-27 20:26:46 +0100423 struct lysp_restr *musts = lysp_node_musts(node);
424 struct lysp_when *when = lysp_node_when(node);
Radek Krejci19a96102018-11-15 13:38:09 +0100425
Michal Vaskoc636ea42022-09-16 10:20:31 +0200426 lydict_remove(ctx->ctx, node->name);
427 lydict_remove(ctx->ctx, node->dsc);
428 lydict_remove(ctx->ctx, node->ref);
429 FREE_ARRAY(ctx->ctx, node->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100430 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
431
Radek Krejci9a3823e2021-01-27 20:26:46 +0100432 FREE_MEMBER(ctx, when, lysp_when_free);
433 FREE_ARRAY(ctx, musts, lysp_restr_free);
434
Michal Vaskod989ba02020-08-24 10:59:24 +0200435 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100436 case LYS_CONTAINER:
Michal Vasko856ea972021-06-09 09:44:30 +0200437 cont = (struct lysp_node_container *)node;
438
Michal Vaskoc636ea42022-09-16 10:20:31 +0200439 lydict_remove(ctx->ctx, cont->presence);
Michal Vasko856ea972021-06-09 09:44:30 +0200440 FREE_ARRAY(ctx, cont->typedefs, lysp_tpdf_free);
441 if (cont->groupings) {
442 LY_LIST_FOR_SAFE(&cont->groupings->node, next, child) {
443 lysp_node_free(ctx, child);
444 }
445 }
446 LY_LIST_FOR_SAFE(cont->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100447 lysp_node_free(ctx, child);
448 }
Michal Vasko856ea972021-06-09 09:44:30 +0200449 if (cont->actions) {
450 LY_LIST_FOR_SAFE(&cont->actions->node, next, child) {
451 lysp_node_free(ctx, child);
452 }
Radek Krejci19a96102018-11-15 13:38:09 +0100453 }
Michal Vasko856ea972021-06-09 09:44:30 +0200454 if (cont->notifs) {
455 LY_LIST_FOR_SAFE(&cont->notifs->node, next, child) {
456 lysp_node_free(ctx, child);
457 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100458 }
Radek Krejci19a96102018-11-15 13:38:09 +0100459 break;
460 case LYS_LEAF:
Michal Vasko856ea972021-06-09 09:44:30 +0200461 leaf = (struct lysp_node_leaf *)node;
462
463 lysp_type_free(ctx, &leaf->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200464 lydict_remove(ctx->ctx, leaf->units);
465 lydict_remove(ctx->ctx, leaf->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100466 break;
467 case LYS_LEAFLIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200468 llist = (struct lysp_node_leaflist *)node;
469
470 lysp_type_free(ctx, &llist->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200471 lydict_remove(ctx->ctx, llist->units);
472 FREE_ARRAY(ctx->ctx, llist->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100473 break;
474 case LYS_LIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200475 list = (struct lysp_node_list *)node;
476
Michal Vaskoc636ea42022-09-16 10:20:31 +0200477 lydict_remove(ctx->ctx, list->key);
Michal Vasko856ea972021-06-09 09:44:30 +0200478 FREE_ARRAY(ctx, list->typedefs, lysp_tpdf_free);
479 if (list->groupings) {
480 LY_LIST_FOR_SAFE(&list->groupings->node, next, child) {
481 lysp_node_free(ctx, child);
482 }
483 }
484 LY_LIST_FOR_SAFE(list->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100485 lysp_node_free(ctx, child);
486 }
Michal Vasko856ea972021-06-09 09:44:30 +0200487 if (list->actions) {
488 LY_LIST_FOR_SAFE(&list->actions->node, next, child) {
489 lysp_node_free(ctx, child);
490 }
Radek Krejci19a96102018-11-15 13:38:09 +0100491 }
Michal Vasko856ea972021-06-09 09:44:30 +0200492 if (list->notifs) {
493 LY_LIST_FOR_SAFE(&list->notifs->node, next, child) {
494 lysp_node_free(ctx, child);
495 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100496 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200497 FREE_ARRAY(ctx->ctx, list->uniques, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100498 break;
499 case LYS_CHOICE:
Michal Vasko856ea972021-06-09 09:44:30 +0200500 choice = (struct lysp_node_choice *)node;
501
502 LY_LIST_FOR_SAFE(choice->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100503 lysp_node_free(ctx, child);
504 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200505 lydict_remove(ctx->ctx, choice->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100506 break;
507 case LYS_CASE:
Michal Vasko856ea972021-06-09 09:44:30 +0200508 cas = (struct lysp_node_case *)node;
509
510 LY_LIST_FOR_SAFE(cas->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100511 lysp_node_free(ctx, child);
512 }
513 break;
514 case LYS_ANYDATA:
515 case LYS_ANYXML:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100516 /* nothing special to do */
Radek Krejci19a96102018-11-15 13:38:09 +0100517 break;
518 case LYS_USES:
Michal Vasko856ea972021-06-09 09:44:30 +0200519 uses = (struct lysp_node_uses *)node;
520
521 FREE_ARRAY(ctx, uses->refines, lysp_refine_free);
522 if (uses->augments) {
523 LY_LIST_FOR_SAFE(&uses->augments->node, next, child) {
524 lysp_node_free(ctx, child);
525 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100526 }
527 break;
528 case LYS_RPC:
529 case LYS_ACTION:
Michal Vasko856ea972021-06-09 09:44:30 +0200530 act = (struct lysp_node_action *)node;
531
532 FREE_ARRAY(ctx, act->typedefs, lysp_tpdf_free);
533 if (act->groupings) {
534 LY_LIST_FOR_SAFE(&act->groupings->node, next, child) {
535 lysp_node_free(ctx, child);
536 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100537 }
Michal Vasko856ea972021-06-09 09:44:30 +0200538 if (act->input.nodetype) {
539 lysp_node_free(ctx, &act->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100540 }
Michal Vasko856ea972021-06-09 09:44:30 +0200541 if (act->output.nodetype) {
542 lysp_node_free(ctx, &act->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100543 }
544 break;
545 case LYS_INPUT:
546 case LYS_OUTPUT:
Michal Vasko856ea972021-06-09 09:44:30 +0200547 inout = (struct lysp_node_action_inout *)node;
548
549 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
550 if (inout->groupings) {
551 LY_LIST_FOR_SAFE(&inout->groupings->node, next, child) {
552 lysp_node_free(ctx, child);
553 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100554 }
Michal Vasko856ea972021-06-09 09:44:30 +0200555 LY_LIST_FOR_SAFE(inout->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100556 lysp_node_free(ctx, child);
557 }
558 /* do not free the node, it is never standalone but part of the action node */
559 return;
560 case LYS_NOTIF:
Michal Vasko856ea972021-06-09 09:44:30 +0200561 notif = (struct lysp_node_notif *)node;
562
563 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
564 if (notif->groupings) {
565 LY_LIST_FOR_SAFE(&notif->groupings->node, next, child) {
566 lysp_node_free(ctx, child);
567 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100568 }
Michal Vasko856ea972021-06-09 09:44:30 +0200569 LY_LIST_FOR_SAFE(notif->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100570 lysp_node_free(ctx, child);
571 }
572 break;
573 case LYS_GROUPING:
574 lysp_grp_free(ctx, (struct lysp_node_grp *)node);
575 break;
576 case LYS_AUGMENT:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100577 lysp_augment_free(ctx, ((struct lysp_node_augment *)node));
Radek Krejci19a96102018-11-15 13:38:09 +0100578 break;
579 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200580 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100581 }
582
583 free(node);
584}
585
Radek Krejci15f10ab2020-11-03 14:14:14 +0100586void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200587lysp_module_free(struct lysf_ctx *ctx, struct lysp_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +0100588{
Radek Krejci19a96102018-11-15 13:38:09 +0100589 struct lysp_node *node, *next;
590
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100591 if (!module) {
592 return;
593 }
Radek Krejci19a96102018-11-15 13:38:09 +0100594
595 FREE_ARRAY(ctx, module->imports, lysp_import_free);
Radek Krejci771928a2021-01-19 13:42:36 +0100596 FREE_ARRAY(ctx, module->includes, module->is_submod ? lysp_include_free_submodule : lysp_include_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100597
Radek Krejci19a96102018-11-15 13:38:09 +0100598 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
599 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
600 FREE_ARRAY(ctx, module->features, lysp_feature_free);
601 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
602 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100603 LY_LIST_FOR_SAFE((struct lysp_node *)module->groupings, next, node) {
604 lysp_node_free(ctx, node);
605 }
Radek Krejci19a96102018-11-15 13:38:09 +0100606 LY_LIST_FOR_SAFE(module->data, next, node) {
607 lysp_node_free(ctx, node);
608 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100609 LY_LIST_FOR_SAFE((struct lysp_node *)module->augments, next, node) {
610 lysp_node_free(ctx, node);
611 }
612 LY_LIST_FOR_SAFE((struct lysp_node *)module->rpcs, next, node) {
613 lysp_node_free(ctx, node);
614 }
615 LY_LIST_FOR_SAFE((struct lysp_node *)module->notifs, next, node) {
616 lysp_node_free(ctx, node);
617 }
Radek Krejci19a96102018-11-15 13:38:09 +0100618 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
619 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
620
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200621 if (module->is_submod) {
622 struct lysp_submodule *submod = (struct lysp_submodule *)module;
623
Michal Vaskoc636ea42022-09-16 10:20:31 +0200624 lydict_remove(ctx->ctx, submod->name);
625 lydict_remove(ctx->ctx, submod->filepath);
626 lydict_remove(ctx->ctx, submod->prefix);
627 lydict_remove(ctx->ctx, submod->org);
628 lydict_remove(ctx->ctx, submod->contact);
629 lydict_remove(ctx->ctx, submod->dsc);
630 lydict_remove(ctx->ctx, submod->ref);
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200631 }
632
Radek Krejci19a96102018-11-15 13:38:09 +0100633 free(module);
634}
635
Michal Vaskoc636ea42022-09-16 10:20:31 +0200636/**
637 * @brief Free the compiled extension definition and NULL the provided pointer.
638 *
639 * @param[in] ctx Free context.
640 * @param[in,out] ext Compiled extension definition to be freed.
641 */
642static void
643lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext)
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100644{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200645 if (ly_set_contains(&ctx->ext_set, *ext, NULL)) {
646 /* already freed and only referenced again in this module */
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100647 return;
648 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200649
Michal Vasko6224d942022-09-19 12:32:47 +0200650 /* remember this extension to be freed, nothing to do on error */
651 (void)ly_set_add(&ctx->ext_set, *ext, 0, NULL);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200652
653 /* recursive exts free */
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100654 FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200655
Radek Krejci720d2612021-03-03 19:44:22 +0100656 *ext = NULL;
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100657}
658
659void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200660lysc_ext_instance_free(struct lysf_ctx *ctx, struct lysc_ext_instance *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100661{
fredganebc50572019-10-31 15:39:23 +0800662 if (ext->def && ext->def->plugin && ext->def->plugin->free) {
Michal Vaskoc636ea42022-09-16 10:20:31 +0200663 ext->def->plugin->free(ctx->ctx, ext);
Radek Krejci38d85362019-09-05 16:26:38 +0200664 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200665 lydict_remove(ctx->ctx, ext->argument);
Radek Krejci0935f412019-08-20 16:15:18 +0200666 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
667}
668
669void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200670lysc_iffeature_free(struct lysf_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
Radek Krejci19a96102018-11-15 13:38:09 +0100671{
672 LY_ARRAY_FREE(iff->features);
673 free(iff->expr);
674}
675
Michal Vaskoc636ea42022-09-16 10:20:31 +0200676/**
677 * @brief Free the compiled when structure (decrease refcount) and NULL the provided pointer.
678 *
679 * @param[in] ctx Free context.
680 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
681 */
Radek Krejci19a96102018-11-15 13:38:09 +0100682static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200683lysc_when_free(struct lysf_ctx *ctx, struct lysc_when **w)
Radek Krejci58d171e2018-11-23 13:50:55 +0100684{
Radek Krejci00b874b2019-02-12 10:54:50 +0100685 if (--(*w)->refcount) {
686 return;
687 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200688 lyxp_expr_free(ctx->ctx, (*w)->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200689 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, (*w)->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200690 lydict_remove(ctx->ctx, (*w)->dsc);
691 lydict_remove(ctx->ctx, (*w)->ref);
Radek Krejci00b874b2019-02-12 10:54:50 +0100692 FREE_ARRAY(ctx, (*w)->exts, lysc_ext_instance_free);
693 free(*w);
Radek Krejci58d171e2018-11-23 13:50:55 +0100694}
695
Michal Vaskoc636ea42022-09-16 10:20:31 +0200696/**
697 * @brief Free the compiled must structure.
698 *
699 * @param[in] ctx Free context.
700 * @param[in,out] must Compiled must structure to be freed.
701 * Since the structure is typically part of the sized array, the structure itself is not freed.
702 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200703static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200704lysc_must_free(struct lysf_ctx *ctx, struct lysc_must *must)
Radek Krejci58d171e2018-11-23 13:50:55 +0100705{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200706 lyxp_expr_free(ctx->ctx, must->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200707 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, must->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200708 lydict_remove(ctx->ctx, must->emsg);
709 lydict_remove(ctx->ctx, must->eapptag);
710 lydict_remove(ctx->ctx, must->dsc);
711 lydict_remove(ctx->ctx, must->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100712 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
713}
714
Michal Vaskoc636ea42022-09-16 10:20:31 +0200715/**
716 * @brief Unlink the identity from all derived identity arrays.
717 *
718 * @param[in] ident Identity to unlink.
719 */
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100720static void
721lysc_ident_derived_unlink(const struct lysc_ident *ident)
722{
723 LY_ARRAY_COUNT_TYPE u, v, w;
724 const struct lysp_submodule *submod;
Michal Vaskod84b8132022-03-15 10:45:44 +0100725 const struct lysp_module *base_pmod = NULL;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100726 const struct lysp_ident *identp = NULL;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100727 const struct lys_module *mod, *iter;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100728 const char *base_name;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100729 uint32_t i;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100730
731 /* find the parsed identity */
732 LY_ARRAY_FOR(ident->module->parsed->identities, u) {
733 if (ident->module->parsed->identities[u].name == ident->name) {
734 identp = &ident->module->parsed->identities[u];
735 base_pmod = ident->module->parsed;
736 break;
737 }
738 }
739 if (!identp) {
740 LY_ARRAY_FOR(ident->module->parsed->includes, v) {
741 submod = ident->module->parsed->includes[v].submodule;
742 LY_ARRAY_FOR(submod->identities, u) {
743 if (submod->identities[u].name == ident->name) {
744 identp = &submod->identities[u];
745 base_pmod = (struct lysp_module *)submod;
746 break;
747 }
748 }
749 }
750 }
751 assert(identp);
752
753 /* remove link from all the foreign bases, it may not be there if identity compilation failed */
754 LY_ARRAY_FOR(identp->bases, u) {
755 base_name = strchr(identp->bases[u], ':');
756 if (!base_name) {
757 continue;
758 }
759
760 /* prefixed identity */
761 mod = ly_resolve_prefix(ident->module->ctx, identp->bases[u], base_name - identp->bases[u], LY_VALUE_SCHEMA,
762 (void *)base_pmod);
763 if (!mod) {
764 continue;
765 }
766 ++base_name;
767
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100768 i = 0;
769 while ((iter = ly_ctx_get_module_iter(ident->module->ctx, &i))) {
770 if (iter == mod) {
771 break;
772 }
773 }
774 if (!iter) {
775 /* target module was freed already */
776 continue;
777 }
778
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100779 /* find the compiled base */
780 LY_ARRAY_FOR(mod->identities, v) {
781 if (!strcmp(mod->identities[v].name, base_name)) {
782 /* find the derived link */
783 LY_ARRAY_FOR(mod->identities[v].derived, w) {
784 if (mod->identities[v].derived[w] == ident) {
785 /* remove the link */
786 LY_ARRAY_DECREMENT(mod->identities[v].derived);
Michal Vasko3fedda12022-03-16 09:23:45 +0100787 if (!LY_ARRAY_COUNT(mod->identities[v].derived)) {
788 LY_ARRAY_FREE(mod->identities[v].derived);
789 mod->identities[v].derived = NULL;
790 } else if (w < LY_ARRAY_COUNT(mod->identities[v].derived)) {
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100791 memmove(mod->identities[v].derived + w, mod->identities[v].derived + w + 1,
792 (LY_ARRAY_COUNT(mod->identities[v].derived) - w) * sizeof ident);
793 }
794 break;
795 }
796 }
797 break;
798 }
799 }
800 }
801}
802
Michal Vaskoc636ea42022-09-16 10:20:31 +0200803/**
804 * @brief Free the compiled identity structure.
805 *
806 * @param[in] ctx Free context.
807 * @param[in,out] ident Compiled identity structure to be freed.
808 * Since the structure is typically part of the sized array, the structure itself is not freed.
809 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200810static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200811lysc_ident_free(struct lysf_ctx *ctx, struct lysc_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100812{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200813 lydict_remove(ctx->ctx, ident->name);
814 lydict_remove(ctx->ctx, ident->dsc);
815 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100816 LY_ARRAY_FREE(ident->derived);
817 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
818}
819
Michal Vaskoc636ea42022-09-16 10:20:31 +0200820/**
821 * @brief Free the compiled range structure.
822 *
823 * @param[in] ctx Free context.
824 * @param[in,out] range Compiled range structure to be freed.
825 * Since the structure is typically part of the sized array, the structure itself is not freed.
826 */
Radek Krejci19a96102018-11-15 13:38:09 +0100827static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200828lysc_range_free(struct lysf_ctx *ctx, struct lysc_range *range)
Radek Krejci19a96102018-11-15 13:38:09 +0100829{
830 LY_ARRAY_FREE(range->parts);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200831 lydict_remove(ctx->ctx, range->eapptag);
832 lydict_remove(ctx->ctx, range->emsg);
833 lydict_remove(ctx->ctx, range->dsc);
834 lydict_remove(ctx->ctx, range->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100835 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
836}
837
Michal Vasko51de7b72022-04-29 09:50:22 +0200838void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200839lysc_pattern_free(struct lysf_ctx *ctx, struct lysc_pattern **pattern)
Radek Krejci19a96102018-11-15 13:38:09 +0100840{
841 if (--(*pattern)->refcount) {
842 return;
843 }
Radek Krejci54579462019-04-30 12:47:06 +0200844 pcre2_code_free((*pattern)->code);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200845 lydict_remove(ctx->ctx, (*pattern)->expr);
846 lydict_remove(ctx->ctx, (*pattern)->eapptag);
847 lydict_remove(ctx->ctx, (*pattern)->emsg);
848 lydict_remove(ctx->ctx, (*pattern)->dsc);
849 lydict_remove(ctx->ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100850 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
851 free(*pattern);
852}
853
Michal Vaskof4fa90d2021-11-11 15:05:19 +0100854void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200855lysc_enum_item_free(struct lysf_ctx *ctx, struct lysc_type_bitenum_item *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100856{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200857 lydict_remove(ctx->ctx, item->name);
858 lydict_remove(ctx->ctx, item->dsc);
859 lydict_remove(ctx->ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100860 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
861}
862
Michal Vaskoc636ea42022-09-16 10:20:31 +0200863/**
864 * @brief Free the compiled type structure.
865 *
866 * @param[in] ctx Free context.
867 * @param[in,out] type Pointer to compiled type structure to be freed.
868 * Since the structure is typically part of the sized array, the structure itself is not freed.
869 */
Radek Krejcia3045382018-11-22 14:30:31 +0100870static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200871lysc_type2_free(struct lysf_ctx *ctx, struct lysc_type **type)
Radek Krejcia3045382018-11-22 14:30:31 +0100872{
873 lysc_type_free(ctx, *type);
874}
Radek Krejci0f969882020-08-21 16:56:47 +0200875
Radek Krejcicdfecd92018-11-26 11:27:32 +0100876void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200877lysc_type_free(struct lysf_ctx *ctx, struct lysc_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100878{
Michal Vaskod15c7de2022-05-09 15:34:09 +0200879 if (!type || (LY_ATOMIC_DEC_BARRIER(type->refcount) > 1)) {
Radek Krejci19a96102018-11-15 13:38:09 +0100880 return;
881 }
Radek Krejcib915ac92020-08-14 23:31:04 +0200882
Michal Vaskod989ba02020-08-24 10:59:24 +0200883 switch (type->basetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100884 case LY_TYPE_BINARY:
Michal Vasko22df3f02020-08-24 13:29:22 +0200885 FREE_MEMBER(ctx, ((struct lysc_type_bin *)type)->length, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100886 break;
887 case LY_TYPE_BITS:
Michal Vasko22df3f02020-08-24 13:29:22 +0200888 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 +0100889 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100890 case LY_TYPE_DEC64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200891 FREE_MEMBER(ctx, ((struct lysc_type_dec *)type)->range, lysc_range_free);
Radek Krejci6cba4292018-11-15 17:33:29 +0100892 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100893 case LY_TYPE_STRING:
Michal Vasko22df3f02020-08-24 13:29:22 +0200894 FREE_MEMBER(ctx, ((struct lysc_type_str *)type)->length, lysc_range_free);
895 FREE_ARRAY(ctx, ((struct lysc_type_str *)type)->patterns, lysc_pattern_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100896 break;
897 case LY_TYPE_ENUM:
Michal Vasko22df3f02020-08-24 13:29:22 +0200898 FREE_ARRAY(ctx, ((struct lysc_type_enum *)type)->enums, lysc_enum_item_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100899 break;
900 case LY_TYPE_INT8:
901 case LY_TYPE_UINT8:
902 case LY_TYPE_INT16:
903 case LY_TYPE_UINT16:
904 case LY_TYPE_INT32:
905 case LY_TYPE_UINT32:
906 case LY_TYPE_INT64:
907 case LY_TYPE_UINT64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200908 FREE_MEMBER(ctx, ((struct lysc_type_num *)type)->range, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100909 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100910 case LY_TYPE_IDENT:
Michal Vasko22df3f02020-08-24 13:29:22 +0200911 LY_ARRAY_FREE(((struct lysc_type_identityref *)type)->bases);
Radek Krejci555cb5b2018-11-16 14:54:33 +0100912 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100913 case LY_TYPE_UNION:
Michal Vasko22df3f02020-08-24 13:29:22 +0200914 FREE_ARRAY(ctx, ((struct lysc_type_union *)type)->types, lysc_type2_free);
Radek Krejcia3045382018-11-22 14:30:31 +0100915 break;
916 case LY_TYPE_LEAFREF:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200917 lyxp_expr_free(ctx->ctx, ((struct lysc_type_leafref *)type)->path);
Radek Krejci8df109d2021-04-23 12:19:08 +0200918 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, ((struct lysc_type_leafref *)type)->prefixes);
Michal Vaskod15c7de2022-05-09 15:34:09 +0200919 lysc_type_free(ctx, ((struct lysc_type_leafref *)type)->realtype);
Radek Krejcia3045382018-11-22 14:30:31 +0100920 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100921 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100922 case LY_TYPE_BOOL:
923 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100924 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100925 /* nothing to do */
926 break;
927 }
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200928
929 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100930 free(type);
931}
932
Michal Vaskoc636ea42022-09-16 10:20:31 +0200933/**
934 * @brief Free the compiled input/output structure.
935 *
936 * @param[in] ctx Free context.
937 * @param[in,out] inout Compiled inout structure to be freed.
938 * Since the structure is part of the RPC/action structure, it is not freed itself.
939 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200940static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200941lysc_node_action_inout_free(struct lysf_ctx *ctx, struct lysc_node_action_inout *inout)
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100942{
943 struct lysc_node *child, *child_next;
944
Radek Krejcif538ce52019-03-05 10:46:14 +0100945 FREE_ARRAY(ctx, inout->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100946 LY_LIST_FOR_SAFE(inout->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100947 lysc_node_free_(ctx, child);
Radek Krejcif538ce52019-03-05 10:46:14 +0100948 }
949}
950
Michal Vaskoc636ea42022-09-16 10:20:31 +0200951/**
952 * @brief Free the compiled RPC/action structure.
953 *
954 * @param[in] ctx Free context.
955 * @param[in,out] action Compiled RPC/action structure to be freed.
956 * Since the structure is typically part of the sized array, the structure itself is not freed.
957 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200958static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200959lysc_node_action_free(struct lysf_ctx *ctx, struct lysc_node_action *action)
Radek Krejcif538ce52019-03-05 10:46:14 +0100960{
Michal Vasko37a0fe62021-02-03 09:53:04 +0100961 FREE_ARRAY(ctx, action->when, lysc_when_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100962 if (action->input.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100963 lysc_node_free_(ctx, &action->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100964 }
965 if (action->output.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100966 lysc_node_free_(ctx, &action->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100967 }
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100968}
969
Michal Vaskoc636ea42022-09-16 10:20:31 +0200970/**
971 * @brief Free the compiled notification structure.
972 *
973 * @param[in] ctx Free context.
974 * @param[in,out] notif Compiled notification structure to be freed.
975 * Since the structure is typically part of the sized array, the structure itself is not freed.
976 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200977static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200978lysc_node_notif_free(struct lysf_ctx *ctx, struct lysc_node_notif *notif)
Radek Krejcifc11bd72019-04-11 16:00:05 +0200979{
980 struct lysc_node *child, *child_next;
981
Michal Vasko37a0fe62021-02-03 09:53:04 +0100982 FREE_ARRAY(ctx, notif->when, lysc_when_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200983 FREE_ARRAY(ctx, notif->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100984 LY_LIST_FOR_SAFE(notif->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100985 lysc_node_free_(ctx, child);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200986 }
987}
988
Radek Krejcif2de0ed2019-05-02 14:13:18 +0200989void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200990lysc_node_container_free(struct lysf_ctx *ctx, struct lysc_node_container *node)
Radek Krejci19a96102018-11-15 13:38:09 +0100991{
992 struct lysc_node *child, *child_next;
993
994 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100995 lysc_node_free_(ctx, child);
Radek Krejci19a96102018-11-15 13:38:09 +0100996 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100997 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
998 lysc_node_free_(ctx, child);
999 }
1000 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1001 lysc_node_free_(ctx, child);
1002 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001003 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001004 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001005}
1006
Michal Vaskoc636ea42022-09-16 10:20:31 +02001007/**
1008 * @brief Free the compiled leaf structure.
1009 *
1010 * @param[in] ctx Free context.
1011 * @param[in,out] node Compiled leaf structure to be freed.
1012 * Since the structure is typically part of the sized array, the structure itself is not freed.
1013 */
Radek Krejci19a96102018-11-15 13:38:09 +01001014static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001015lysc_node_leaf_free(struct lysf_ctx *ctx, struct lysc_node_leaf *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001016{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001017 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001018 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001019 if (node->type) {
1020 lysc_type_free(ctx, node->type);
1021 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001022 lydict_remove(ctx->ctx, node->units);
Radek Krejcia1911222019-07-22 17:24:50 +02001023 if (node->dflt) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001024 node->dflt->realtype->plugin->free(ctx->ctx, node->dflt);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001025 lysc_type_free(ctx, (struct lysc_type *)node->dflt->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001026 free(node->dflt);
1027 }
Radek Krejci19a96102018-11-15 13:38:09 +01001028}
1029
Michal Vaskoc636ea42022-09-16 10:20:31 +02001030/**
1031 * @brief Free the compiled leaflist structure.
1032 *
1033 * @param[in] ctx Free context.
1034 * @param[in,out] node Compiled leaflist structure to be freed.
1035 * Since the structure is typically part of the sized array, the structure itself is not freed.
1036 */
Radek Krejci42452ac2018-11-28 17:09:52 +01001037static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001038lysc_node_leaflist_free(struct lysf_ctx *ctx, struct lysc_node_leaflist *node)
Radek Krejci42452ac2018-11-28 17:09:52 +01001039{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001040 LY_ARRAY_COUNT_TYPE u;
Radek Krejci42452ac2018-11-28 17:09:52 +01001041
Radek Krejci9a3823e2021-01-27 20:26:46 +01001042 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci42452ac2018-11-28 17:09:52 +01001043 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1044 if (node->type) {
1045 lysc_type_free(ctx, node->type);
1046 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001047 lydict_remove(ctx->ctx, node->units);
Radek Krejci42452ac2018-11-28 17:09:52 +01001048 LY_ARRAY_FOR(node->dflts, u) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001049 node->dflts[u]->realtype->plugin->free(ctx->ctx, node->dflts[u]);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001050 lysc_type_free(ctx, (struct lysc_type *)node->dflts[u]->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001051 free(node->dflts[u]);
Radek Krejci42452ac2018-11-28 17:09:52 +01001052 }
1053 LY_ARRAY_FREE(node->dflts);
1054}
1055
Michal Vaskoc636ea42022-09-16 10:20:31 +02001056/**
1057 * @brief Free the compiled list structure.
1058 *
1059 * @param[in] ctx Free context.
1060 * @param[in,out] node Compiled list structure to be freed.
1061 * Since the structure is typically part of the sized array, the structure itself is not freed.
1062 */
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001063static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001064lysc_node_list_free(struct lysf_ctx *ctx, struct lysc_node_list *node)
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001065{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001066 LY_ARRAY_COUNT_TYPE u;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001067 struct lysc_node *child, *child_next;
1068
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001069 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001070 lysc_node_free_(ctx, child);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001071 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001072 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001073 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1074
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001075 LY_ARRAY_FOR(node->uniques, u) {
1076 LY_ARRAY_FREE(node->uniques[u]);
1077 }
1078 LY_ARRAY_FREE(node->uniques);
1079
Radek Krejci2a9fc652021-01-22 17:44:34 +01001080 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
1081 lysc_node_free_(ctx, child);
1082 }
1083 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1084 lysc_node_free_(ctx, child);
1085 }
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001086}
1087
Michal Vaskoc636ea42022-09-16 10:20:31 +02001088/**
1089 * @brief Free the compiled choice structure.
1090 *
1091 * @param[in] ctx Free context.
1092 * @param[in,out] node Compiled choice structure to be freed.
1093 * Since the structure is typically part of the sized array, the structure itself is not freed.
1094 */
Radek Krejci056d0a82018-12-06 16:57:25 +01001095static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001096lysc_node_choice_free(struct lysf_ctx *ctx, struct lysc_node_choice *node)
Radek Krejci056d0a82018-12-06 16:57:25 +01001097{
1098 struct lysc_node *child, *child_next;
1099
Radek Krejci9a3823e2021-01-27 20:26:46 +01001100 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001101 LY_LIST_FOR_SAFE((struct lysc_node *)node->cases, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001102 lysc_node_free_(ctx, child);
Michal Vasko20424b42020-08-31 12:29:38 +02001103 }
1104}
1105
Michal Vaskoc636ea42022-09-16 10:20:31 +02001106/**
1107 * @brief Free the compiled case structure.
1108 *
1109 * @param[in] ctx Free context.
1110 * @param[in,out] node Compiled case structure to be freed.
1111 * Since the structure is typically part of the sized array, the structure itself is not freed.
1112 */
Michal Vasko20424b42020-08-31 12:29:38 +02001113static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001114lysc_node_case_free(struct lysf_ctx *ctx, struct lysc_node_case *node)
Michal Vasko20424b42020-08-31 12:29:38 +02001115{
1116 struct lysc_node *child, *child_next;
1117
Radek Krejci9a3823e2021-01-27 20:26:46 +01001118 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001119 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001120 lysc_node_free_(ctx, child);
Radek Krejci056d0a82018-12-06 16:57:25 +01001121 }
Radek Krejci9800fb82018-12-13 14:26:23 +01001122}
Radek Krejci056d0a82018-12-06 16:57:25 +01001123
Michal Vaskoc636ea42022-09-16 10:20:31 +02001124/**
1125 * @brief Free the compiled anyxml/anydata structure.
1126 *
1127 * @param[in] ctx Free context.
1128 * @param[in,out] node Compiled anyxml/anydata structure to be freed.
1129 * Since the structure is typically part of the sized array, the structure itself is not freed.
1130 */
Radek Krejci9800fb82018-12-13 14:26:23 +01001131static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001132lysc_node_anydata_free(struct lysf_ctx *ctx, struct lysc_node_anydata *node)
Radek Krejci9800fb82018-12-13 14:26:23 +01001133{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001134 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9800fb82018-12-13 14:26:23 +01001135 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +01001136}
1137
Michal Vaskoc636ea42022-09-16 10:20:31 +02001138/**
1139 * @brief Free the compiled node structure.
1140 *
1141 * @param[in] ctx Free context.
1142 * @param[in,out] node Compiled node structure to be freed.
1143 * Since the structure is typically part of the sized array, the structure itself is not freed.
1144 */
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001145static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001146lysc_node_free_(struct lysf_ctx *ctx, struct lysc_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001147{
Radek Krejci2a9fc652021-01-22 17:44:34 +01001148 ly_bool inout = 0;
1149
Radek Krejci19a96102018-11-15 13:38:09 +01001150 /* common part */
Michal Vaskoc636ea42022-09-16 10:20:31 +02001151 lydict_remove(ctx->ctx, node->name);
1152 lydict_remove(ctx->ctx, node->dsc);
1153 lydict_remove(ctx->ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +01001154
1155 /* nodetype-specific part */
Michal Vaskod989ba02020-08-24 10:59:24 +02001156 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +01001157 case LYS_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02001158 lysc_node_container_free(ctx, (struct lysc_node_container *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001159 break;
1160 case LYS_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02001161 lysc_node_leaf_free(ctx, (struct lysc_node_leaf *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001162 break;
Radek Krejci42452ac2018-11-28 17:09:52 +01001163 case LYS_LEAFLIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001164 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist *)node);
Radek Krejci42452ac2018-11-28 17:09:52 +01001165 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001166 case LYS_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001167 lysc_node_list_free(ctx, (struct lysc_node_list *)node);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001168 break;
Radek Krejci056d0a82018-12-06 16:57:25 +01001169 case LYS_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02001170 lysc_node_choice_free(ctx, (struct lysc_node_choice *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001171 break;
1172 case LYS_CASE:
Michal Vasko20424b42020-08-31 12:29:38 +02001173 lysc_node_case_free(ctx, (struct lysc_node_case *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001174 break;
Radek Krejci9800fb82018-12-13 14:26:23 +01001175 case LYS_ANYDATA:
1176 case LYS_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02001177 lysc_node_anydata_free(ctx, (struct lysc_node_anydata *)node);
Radek Krejci9800fb82018-12-13 14:26:23 +01001178 break;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001179 case LYS_RPC:
1180 case LYS_ACTION:
1181 lysc_node_action_free(ctx, (struct lysc_node_action *)node);
1182 break;
1183 case LYS_INPUT:
1184 case LYS_OUTPUT:
1185 lysc_node_action_inout_free(ctx, (struct lysc_node_action_inout *)node);
1186 inout = 1;
1187 break;
1188 case LYS_NOTIF:
1189 lysc_node_notif_free(ctx, (struct lysc_node_notif *)node);
1190 break;
Radek Krejci19a96102018-11-15 13:38:09 +01001191 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +02001192 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +01001193 }
1194
Radek Krejci056d0a82018-12-06 16:57:25 +01001195 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001196
1197 if (!inout) {
1198 free(node);
1199 }
Radek Krejci19a96102018-11-15 13:38:09 +01001200}
1201
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001202void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001203lysc_node_free(struct lysf_ctx *ctx, struct lysc_node *node, ly_bool unlink)
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001204{
Michal Vaskoe02e7402021-07-23 08:29:28 +02001205 struct lysc_node *next, *iter, **child_p;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001206
Radek Krejci2a9fc652021-01-22 17:44:34 +01001207 if (node->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
Michal Vaskoe02e7402021-07-23 08:29:28 +02001208 /* inouts are part of actions and cannot be unlinked/freed separately, we can only free all the children */
1209 struct lysc_node_action_inout *inout = (struct lysc_node_action_inout *)node;
Michal Vasko26bbb272022-08-02 14:54:33 +02001210
Michal Vaskoe02e7402021-07-23 08:29:28 +02001211 LY_LIST_FOR_SAFE(inout->child, next, iter) {
1212 lysc_node_free_(ctx, iter);
1213 }
1214 inout->child = NULL;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001215 return;
1216 }
1217
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001218 if (unlink) {
1219 /* unlink from siblings */
1220 if (node->prev->next) {
1221 node->prev->next = node->next;
1222 }
1223 if (node->next) {
1224 node->next->prev = node->prev;
1225 } else {
1226 /* unlinking the last node */
1227 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001228 if (node->nodetype == LYS_ACTION) {
1229 iter = (struct lysc_node *)lysc_node_actions(node->parent);
1230 } else if (node->nodetype == LYS_NOTIF) {
1231 iter = (struct lysc_node *)lysc_node_notifs(node->parent);
1232 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001233 iter = (struct lysc_node *)lysc_node_child(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001234 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001235 LY_CHECK_ERR_RET(!iter, LOGINT(ctx->ctx), );
Radek Krejci2a9fc652021-01-22 17:44:34 +01001236 } else if (node->nodetype == LYS_RPC) {
1237 iter = (struct lysc_node *)node->module->compiled->rpcs;
1238 } else if (node->nodetype == LYS_NOTIF) {
1239 iter = (struct lysc_node *)node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001240 } else {
1241 iter = node->module->compiled->data;
1242 }
1243 /* update the "last" pointer from the first node */
1244 iter->prev = node->prev;
1245 }
1246
1247 /* unlink from parent */
1248 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001249 if (node->nodetype == LYS_ACTION) {
1250 child_p = (struct lysc_node **)lysc_node_actions_p(node->parent);
1251 } else if (node->nodetype == LYS_NOTIF) {
1252 child_p = (struct lysc_node **)lysc_node_notifs_p(node->parent);
1253 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001254 child_p = lysc_node_child_p(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001255 }
1256 } else if (node->nodetype == LYS_RPC) {
1257 child_p = (struct lysc_node **)&node->module->compiled->rpcs;
1258 } else if (node->nodetype == LYS_NOTIF) {
1259 child_p = (struct lysc_node **)&node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001260 } else {
1261 child_p = &node->module->compiled->data;
1262 }
1263 if (child_p && (*child_p == node)) {
1264 /* the node is the first child */
1265 *child_p = node->next;
1266 }
1267 }
1268
1269 lysc_node_free_(ctx, node);
1270}
1271
Radek Krejci90ed21e2021-04-12 14:47:46 +02001272void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001273lysc_module_free(struct lysf_ctx *ctx, struct lysc_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +01001274{
Radek Krejci19a96102018-11-15 13:38:09 +01001275 struct lysc_node *node, *node_next;
1276
Radek Krejci90ed21e2021-04-12 14:47:46 +02001277 if (!module) {
1278 return;
1279 }
1280
Radek Krejci19a96102018-11-15 13:38:09 +01001281 LY_LIST_FOR_SAFE(module->data, node_next, node) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001282 lysc_node_free_(ctx, node);
Radek Krejci19a96102018-11-15 13:38:09 +01001283 }
Radek Krejci2a9fc652021-01-22 17:44:34 +01001284 LY_LIST_FOR_SAFE((struct lysc_node *)module->rpcs, node_next, node) {
1285 lysc_node_free_(ctx, node);
1286 }
1287 LY_LIST_FOR_SAFE((struct lysc_node *)module->notifs, node_next, node) {
1288 lysc_node_free_(ctx, node);
1289 }
Radek Krejci19a96102018-11-15 13:38:09 +01001290 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
1291
1292 free(module);
1293}
1294
1295void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001296lys_module_free(struct lysf_ctx *ctx, struct lys_module *module, ly_bool remove_links)
Radek Krejci19a96102018-11-15 13:38:09 +01001297{
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001298 LY_ARRAY_COUNT_TYPE u;
1299
Radek Krejci19a96102018-11-15 13:38:09 +01001300 if (!module) {
1301 return;
1302 }
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001303
Michal Vaskoee757602021-06-10 14:38:19 +02001304 assert(!module->implemented);
1305 assert(!module->compiled);
Radek Krejci19a96102018-11-15 13:38:09 +01001306
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001307 if (remove_links) {
1308 /* remove derived identity links */
1309 LY_ARRAY_FOR(module->identities, u) {
1310 lysc_ident_derived_unlink(&module->identities[u]);
1311 }
1312 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001313 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
1314 lysp_module_free(ctx, module->parsed);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001315
Michal Vasko7f45cf22020-10-01 12:49:44 +02001316 LY_ARRAY_FREE(module->augmented_by);
1317 LY_ARRAY_FREE(module->deviated_by);
1318
Michal Vaskoc636ea42022-09-16 10:20:31 +02001319 lydict_remove(ctx->ctx, module->name);
1320 lydict_remove(ctx->ctx, module->revision);
1321 lydict_remove(ctx->ctx, module->ns);
1322 lydict_remove(ctx->ctx, module->prefix);
1323 lydict_remove(ctx->ctx, module->filepath);
1324 lydict_remove(ctx->ctx, module->org);
1325 lydict_remove(ctx->ctx, module->contact);
1326 lydict_remove(ctx->ctx, module->dsc);
1327 lydict_remove(ctx->ctx, module->ref);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001328
Radek Krejci19a96102018-11-15 13:38:09 +01001329 free(module);
1330}
Michal Vasko33ff9422020-07-03 09:50:39 +02001331
Michal Vaskoc636ea42022-09-16 10:20:31 +02001332void
1333lysf_ctx_erase(struct lysf_ctx *ctx)
1334{
1335 struct lysc_ext *ext;
1336 uint32_t i;
1337
1338 for (i = 0; i < ctx->ext_set.count; ++i) {
1339 ext = ctx->ext_set.objs[i];
1340
1341 lydict_remove(ctx->ctx, ext->name);
1342 lydict_remove(ctx->ctx, ext->argname);
1343 free(ext);
1344 }
1345 ly_set_erase(&ctx->ext_set, NULL);
1346}
1347
Jan Kundrátc53a7ec2021-12-09 16:01:19 +01001348LIBYANG_API_DEF void
Radek Krejci0b013302021-03-29 15:22:32 +02001349lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
Radek Krejci38d85362019-09-05 16:26:38 +02001350{
Radek Krejci1b2eef82021-02-17 11:17:27 +01001351 LY_ARRAY_COUNT_TYPE u;
Michal Vaskoc636ea42022-09-16 10:20:31 +02001352 struct lysf_ctx fctx = {.ctx = ctx};
Radek Krejci1b2eef82021-02-17 11:17:27 +01001353
1354 LY_ARRAY_FOR(substmts, u) {
Radek Krejci38d85362019-09-05 16:26:38 +02001355 if (!substmts[u].storage) {
1356 continue;
1357 }
1358
Michal Vaskod989ba02020-08-24 10:59:24 +02001359 switch (substmts[u].stmt) {
Radek Krejci6b88a462021-02-17 12:39:34 +01001360 case LY_STMT_ACTION:
1361 case LY_STMT_ANYDATA:
1362 case LY_STMT_ANYXML:
1363 case LY_STMT_CONTAINER:
1364 case LY_STMT_CHOICE:
1365 case LY_STMT_LEAF:
1366 case LY_STMT_LEAF_LIST:
1367 case LY_STMT_LIST:
1368 case LY_STMT_NOTIFICATION:
1369 case LY_STMT_RPC:
1370 case LY_STMT_USES: {
1371 struct lysc_node *child, *child_next;
1372
1373 LY_LIST_FOR_SAFE(*((struct lysc_node **)substmts[u].storage), child_next, child) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001374 lysc_node_free_(&fctx, child);
Radek Krejci38d85362019-09-05 16:26:38 +02001375 }
1376 break;
Radek Krejci6b88a462021-02-17 12:39:34 +01001377 }
1378 case LY_STMT_CONFIG:
1379 case LY_STMT_STATUS:
1380 /* nothing to do */
1381 break;
Michal Vasko3ac60e52022-09-05 11:08:31 +02001382 case LY_STMT_CONTACT:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001383 case LY_STMT_DESCRIPTION:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001384 case LY_STMT_ERROR_APP_TAG:
1385 case LY_STMT_ERROR_MESSAGE:
1386 case LY_STMT_KEY:
1387 case LY_STMT_NAMESPACE:
1388 case LY_STMT_ORGANIZATION:
1389 case LY_STMT_PRESENCE:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001390 case LY_STMT_REFERENCE:
Radek Krejci38d85362019-09-05 16:26:38 +02001391 case LY_STMT_UNITS:
1392 if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1393 /* single item */
Michal Vasko22df3f02020-08-24 13:29:22 +02001394 const char *str = *((const char **)substmts[u].storage);
Michal Vasko26bbb272022-08-02 14:54:33 +02001395
Radek Krejci38d85362019-09-05 16:26:38 +02001396 if (!str) {
1397 break;
1398 }
Michal Vaskoe180ed02021-02-05 16:31:20 +01001399 lydict_remove(ctx, str);
Radek Krejci38d85362019-09-05 16:26:38 +02001400 } else {
1401 /* multiple items */
Michal Vasko22df3f02020-08-24 13:29:22 +02001402 const char **strs = *((const char ***)substmts[u].storage);
Michal Vasko26bbb272022-08-02 14:54:33 +02001403
Radek Krejci38d85362019-09-05 16:26:38 +02001404 if (!strs) {
1405 break;
1406 }
1407 FREE_STRINGS(ctx, strs);
1408 }
1409 break;
Radek Krejci38d85362019-09-05 16:26:38 +02001410 case LY_STMT_IF_FEATURE: {
Michal Vasko22df3f02020-08-24 13:29:22 +02001411 struct lysc_iffeature *iff = *((struct lysc_iffeature **)substmts[u].storage);
Michal Vasko26bbb272022-08-02 14:54:33 +02001412
Radek Krejci38d85362019-09-05 16:26:38 +02001413 if (!iff) {
1414 break;
1415 }
1416 if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1417 /* single item */
Michal Vaskoc636ea42022-09-16 10:20:31 +02001418 lysc_iffeature_free(&fctx, iff);
Radek Krejci38d85362019-09-05 16:26:38 +02001419 free(iff);
1420 } else {
1421 /* multiple items */
Michal Vaskoc636ea42022-09-16 10:20:31 +02001422 FREE_ARRAY(&fctx, iff, lysc_iffeature_free);
Radek Krejci38d85362019-09-05 16:26:38 +02001423 }
1424 break;
1425 }
Michal Vaskof8647fa2022-09-05 11:07:54 +02001426 case LY_STMT_TYPE:
1427 if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
1428 /* single item */
1429 struct lysc_type *type = *((struct lysc_type **)substmts[u].storage);
1430
1431 if (!type) {
1432 break;
1433 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001434 lysc_type_free(&fctx, type);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001435 } else {
1436 /* multiple items */
1437 struct lysc_type **types = *((struct lysc_type ***)substmts[u].storage);
1438
1439 if (!types) {
1440 break;
1441 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001442 FREE_ARRAY(&fctx, types, lysc_type2_free);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001443 }
1444 break;
Radek Krejci38d85362019-09-05 16:26:38 +02001445
Radek Krejci0f969882020-08-21 16:56:47 +02001446 /* TODO other statements */
Radek Krejci38d85362019-09-05 16:26:38 +02001447 default:
1448 LOGINT(ctx);
1449 }
1450 }
Radek Krejci1b2eef82021-02-17 11:17:27 +01001451
1452 LY_ARRAY_FREE(substmts);
Radek Krejci38d85362019-09-05 16:26:38 +02001453}
David Sedlákebd3acf2019-07-26 15:04:32 +02001454
1455void
Michal Vaskob36053d2020-03-26 15:49:30 +01001456yang_parser_ctx_free(struct lys_yang_parser_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001457{
1458 if (ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001459 if (ctx->main_ctx == (struct lys_parser_ctx *)ctx) {
1460 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1461 ly_set_erase(&ctx->grps_nodes, NULL);
1462 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001463 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001464 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1465 if (!ctx->parsed_mods->count) {
1466 ly_set_free(ctx->parsed_mods, NULL);
1467 }
David Sedlákebd3acf2019-07-26 15:04:32 +02001468 free(ctx);
1469 }
1470}
1471
1472void
Michal Vaskob36053d2020-03-26 15:49:30 +01001473yin_parser_ctx_free(struct lys_yin_parser_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001474{
1475 if (ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001476 if (ctx->main_ctx == (struct lys_parser_ctx *)ctx) {
1477 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1478 ly_set_erase(&ctx->grps_nodes, NULL);
1479 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001480 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001481 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1482 if (!ctx->parsed_mods->count) {
1483 ly_set_free(ctx->parsed_mods, NULL);
1484 }
Michal Vaskob36053d2020-03-26 15:49:30 +01001485 lyxml_ctx_free(ctx->xmlctx);
David Sedlákebd3acf2019-07-26 15:04:32 +02001486 free(ctx);
1487 }
1488}