blob: 91ba72b0751dc276d210ea3908766643e3f0b896 [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
Michal Vasko69730152020-10-09 16:30:07 +020021#include "compat.h"
Radek Krejci77114102021-03-10 15:21:57 +010022#include "dict.h"
Radek Krejci47fab892020-11-05 17:02:41 +010023#include "log.h"
Michal Vasko8f702ee2024-02-20 15:44:24 +010024#include "ly_common.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_node_free_(struct lysf_ctx *ctx, struct lysc_node *node);
Radek Krejci19a96102018-11-15 13:38:09 +010037
Michal Vaskoc636ea42022-09-16 10:20:31 +020038void
Michal Vasko193dacd2022-10-13 08:43:05 +020039lysp_qname_free(const struct ly_ctx *ctx, struct lysp_qname *qname)
Michal Vaskoc636ea42022-09-16 10:20:31 +020040{
41 if (qname) {
42 lydict_remove(ctx, qname->str);
43 }
44}
45
46/**
47 * @brief Free the parsed generic statement structure.
48 *
49 * @param[in] ctx libyang context.
50 * @param[in] grp Parsed schema statement structure to free. Note that the structure itself is not freed.
51 */
Radek Krejci19a96102018-11-15 13:38:09 +010052static void
53lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
54{
55 struct lysp_stmt *child, *next;
56
Michal Vaskoe180ed02021-02-05 16:31:20 +010057 lydict_remove(ctx, stmt->stmt);
58 lydict_remove(ctx, stmt->arg);
Michal Vaskofc2cd072021-02-24 13:17:17 +010059 ly_free_prefix_data(stmt->format, stmt->prefix_data);
Radek Krejci19a96102018-11-15 13:38:09 +010060
61 LY_LIST_FOR_SAFE(stmt->child, next, child) {
62 lysp_stmt_free(ctx, child);
63 }
64
65 free(stmt);
66}
67
Michal Vaskoc636ea42022-09-16 10:20:31 +020068void
69lysp_ext_instance_free(struct lysf_ctx *ctx, struct lysp_ext_instance *ext)
Radek Krejci19a96102018-11-15 13:38:09 +010070{
71 struct lysp_stmt *stmt, *next;
72
Michal Vaskoc636ea42022-09-16 10:20:31 +020073 lydict_remove(ctx->ctx, ext->name);
74 lydict_remove(ctx->ctx, ext->argument);
Michal Vaskofc2cd072021-02-24 13:17:17 +010075 ly_free_prefix_data(ext->format, ext->prefix_data);
Michal Vasko193dacd2022-10-13 08:43:05 +020076 if (ext->record && ext->record->plugin.pfree) {
77 ext->record->plugin.pfree(ctx->ctx, ext);
aPiecek60d9d672021-04-27 15:49:57 +020078 }
Radek Krejci19a96102018-11-15 13:38:09 +010079
80 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
Michal Vaskoc636ea42022-09-16 10:20:31 +020081 lysp_stmt_free(ctx->ctx, stmt);
Radek Krejci19a96102018-11-15 13:38:09 +010082 }
83}
84
Michal Vaskoc636ea42022-09-16 10:20:31 +020085/**
86 * @brief Free the parsed import structure.
87 *
88 * @param[in] ctx Free context.
89 * @param[in] import Parsed schema import structure to free. Note that the structure itself is not freed.
90 */
Michal Vasko12ef5362022-09-16 15:13:58 +020091static void
Michal Vaskoc636ea42022-09-16 10:20:31 +020092lysp_import_free(struct lysf_ctx *ctx, struct lysp_import *import)
Radek Krejci19a96102018-11-15 13:38:09 +010093{
94 /* imported module is freed directly from the context's list */
Michal Vaskoc636ea42022-09-16 10:20:31 +020095 lydict_remove(ctx->ctx, import->name);
96 lydict_remove(ctx->ctx, import->prefix);
97 lydict_remove(ctx->ctx, import->dsc);
98 lydict_remove(ctx->ctx, import->ref);
Radek Krejci19a96102018-11-15 13:38:09 +010099 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
100}
101
Radek Krejci771928a2021-01-19 13:42:36 +0100102/**
103 * @brief Common function to erase include record in main module and submodule.
104 *
105 * There is a difference since the main module is expected to have the complete list if the included submodules and
106 * the parsed submodule is shared with any include in a submodule. Therefore, the referenced submodules in the include
107 * record are freed only from main module's records.
108 *
109 * @param[in] ctx libyang context
110 * @param[in] include The include record to be erased, the record itself is not freed.
111 * @param[in] main_module Flag to get know if the include record is placed in main module so also the referenced submodule
112 * is supposed to be freed.
113 */
114static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200115lysp_include_free_(struct lysf_ctx *ctx, struct lysp_include *include, ly_bool main_module)
Radek Krejci19a96102018-11-15 13:38:09 +0100116{
Radek Krejci771928a2021-01-19 13:42:36 +0100117 if (main_module && include->submodule) {
Michal Vaskoc636ea42022-09-16 10:20:31 +0200118 lysp_module_free(ctx, (struct lysp_module *)include->submodule);
Radek Krejci19a96102018-11-15 13:38:09 +0100119 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200120 lydict_remove(ctx->ctx, include->name);
121 lydict_remove(ctx->ctx, include->dsc);
122 lydict_remove(ctx->ctx, include->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100123 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
124}
125
Michal Vaskoc636ea42022-09-16 10:20:31 +0200126/**
127 * @brief Free the parsed include structure of a submodule.
128 *
129 * @param[in] ctx Free context.
130 * @param[in] include Parsed schema include structure to free. Note that the structure itself is not freed.
131 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200132static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200133lysp_include_free_submodule(struct lysf_ctx *ctx, struct lysp_include *include)
Radek Krejci771928a2021-01-19 13:42:36 +0100134{
Michal Vaskoa0a498b2021-09-22 12:17:48 +0200135 lysp_include_free_(ctx, include, 0);
Radek Krejci771928a2021-01-19 13:42:36 +0100136}
137
Michal Vaskoc636ea42022-09-16 10:20:31 +0200138/**
139 * @brief Free the parsed include structure of a module.
140 *
141 * @param[in] ctx Free context.
142 * @param[in] include Parsed schema include structure to free. Note that the structure itself is not freed.
143 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200144static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200145lysp_include_free(struct lysf_ctx *ctx, struct lysp_include *include)
Radek Krejci771928a2021-01-19 13:42:36 +0100146{
Michal Vaskoa0a498b2021-09-22 12:17:48 +0200147 lysp_include_free_(ctx, include, 1);
Radek Krejci771928a2021-01-19 13:42:36 +0100148}
149
Michal Vaskoc636ea42022-09-16 10:20:31 +0200150/**
151 * @brief Free the parsed revision structure.
152 *
153 * @param[in] ctx Free context.
154 * @param[in] rev Parsed schema revision structure to free. Note that the structure itself is not freed.
155 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200156static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200157lysp_revision_free(struct lysf_ctx *ctx, struct lysp_revision *rev)
Radek Krejci19a96102018-11-15 13:38:09 +0100158{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200159 lydict_remove(ctx->ctx, rev->dsc);
160 lydict_remove(ctx->ctx, rev->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100161 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
162}
163
Michal Vaskoc636ea42022-09-16 10:20:31 +0200164/**
Michal Vasko193dacd2022-10-13 08:43:05 +0200165 * @brief Free the compiled extension definition and NULL the provided pointer.
166 *
167 * @param[in] ctx Free context.
168 * @param[in,out] ext Compiled extension definition to be freed.
169 */
170static void
171lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext)
172{
173 if (ly_set_contains(&ctx->ext_set, *ext, NULL)) {
174 /* already freed and only referenced again in this module */
175 return;
176 }
177
178 /* remember this extension to be freed, nothing to do on error */
179 (void)ly_set_add(&ctx->ext_set, *ext, 0, NULL);
180
181 /* recursive exts free */
182 FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
183
184 *ext = NULL;
185}
186
187/**
Michal Vaskoc636ea42022-09-16 10:20:31 +0200188 * @brief Free the parsed ext structure.
189 *
190 * @param[in] ctx Free context.
191 * @param[in] ext Parsed schema ext structure to free. Note that the structure itself is not freed.
192 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200193static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200194lysp_ext_free(struct lysf_ctx *ctx, struct lysp_ext *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100195{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200196 lydict_remove(ctx->ctx, ext->name);
197 lydict_remove(ctx->ctx, ext->argname);
198 lydict_remove(ctx->ctx, ext->dsc);
199 lydict_remove(ctx->ctx, ext->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100200 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
Michal Vasko5fe75f12020-03-02 13:52:37 +0100201 if (ext->compiled) {
202 lysc_extension_free(ctx, &ext->compiled);
203 }
Radek Krejci19a96102018-11-15 13:38:09 +0100204}
205
Michal Vaskoc636ea42022-09-16 10:20:31 +0200206/**
207 * @brief Free the parsed feature structure.
208 *
209 * @param[in] ctx Free context.
210 * @param[in] feat Parsed schema feature structure to free. Note that the structure itself is not freed.
211 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200212static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200213lysp_feature_free(struct lysf_ctx *ctx, struct lysp_feature *feat)
Radek Krejci19a96102018-11-15 13:38:09 +0100214{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200215 lydict_remove(ctx->ctx, feat->name);
216 FREE_ARRAY(ctx->ctx, feat->iffeatures, lysp_qname_free);
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100217 FREE_ARRAY(ctx, feat->iffeatures_c, lysc_iffeature_free);
218 LY_ARRAY_FREE(feat->depfeatures);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200219 lydict_remove(ctx->ctx, feat->dsc);
220 lydict_remove(ctx->ctx, feat->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100221 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
222}
223
Michal Vaskoc636ea42022-09-16 10:20:31 +0200224/**
225 * @brief Free the parsed identity structure.
226 *
227 * @param[in] ctx Free context.
228 * @param[in] ident Parsed schema identity structure to free. Note that the structure itself is not freed.
229 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200230static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200231lysp_ident_free(struct lysf_ctx *ctx, struct lysp_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100232{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200233 lydict_remove(ctx->ctx, ident->name);
234 FREE_ARRAY(ctx->ctx, ident->iffeatures, lysp_qname_free);
235 FREE_STRINGS(ctx->ctx, ident->bases);
236 lydict_remove(ctx->ctx, ident->dsc);
237 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100238 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
239}
240
Michal Vasko7f45cf22020-10-01 12:49:44 +0200241void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200242lysp_restr_free(struct lysf_ctx *ctx, struct lysp_restr *restr)
Radek Krejci19a96102018-11-15 13:38:09 +0100243{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200244 lydict_remove(ctx->ctx, restr->arg.str);
245 lydict_remove(ctx->ctx, restr->emsg);
246 lydict_remove(ctx->ctx, restr->eapptag);
247 lydict_remove(ctx->ctx, restr->dsc);
248 lydict_remove(ctx->ctx, restr->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100249 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
250}
251
Michal Vaskoc636ea42022-09-16 10:20:31 +0200252/**
253 * @brief Free the parsed type enum item.
254 *
255 * @param[in] ctx Free context.
256 * @param[in] item Parsed schema type enum item to free. Note that the structure itself is not freed.
257 */
Radek Krejci19a96102018-11-15 13:38:09 +0100258static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200259lysp_type_enum_free(struct lysf_ctx *ctx, struct lysp_type_enum *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100260{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200261 lydict_remove(ctx->ctx, item->name);
262 lydict_remove(ctx->ctx, item->dsc);
263 lydict_remove(ctx->ctx, item->ref);
264 FREE_ARRAY(ctx->ctx, item->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100265 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
266}
267
David Sedlák32488102019-07-15 17:44:10 +0200268void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200269lysp_type_free(struct lysf_ctx *ctx, struct lysp_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100270{
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200271 if (!type) {
272 return;
273 }
274
Michal Vaskoc636ea42022-09-16 10:20:31 +0200275 lydict_remove(ctx->ctx, type->name);
Radek Krejci19a96102018-11-15 13:38:09 +0100276 FREE_MEMBER(ctx, type->range, lysp_restr_free);
277 FREE_MEMBER(ctx, type->length, lysp_restr_free);
278 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
279 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
280 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200281 lyxp_expr_free(ctx->ctx, type->path);
282 FREE_STRINGS(ctx->ctx, type->bases);
Radek Krejci19a96102018-11-15 13:38:09 +0100283 FREE_ARRAY(ctx, type->types, lysp_type_free);
284 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
285 if (type->compiled) {
286 lysc_type_free(ctx, type->compiled);
287 }
288}
289
Michal Vaskoc636ea42022-09-16 10:20:31 +0200290/**
291 * @brief Free the parsed typedef structure.
292 *
293 * @param[in] ctx Free context.
294 * @param[in] tpdf Parsed schema typedef structure to free. Note that the structure itself is not freed.
295 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200296static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200297lysp_tpdf_free(struct lysf_ctx *ctx, struct lysp_tpdf *tpdf)
Radek Krejci19a96102018-11-15 13:38:09 +0100298{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200299 lydict_remove(ctx->ctx, tpdf->name);
300 lydict_remove(ctx->ctx, tpdf->units);
301 lydict_remove(ctx->ctx, tpdf->dflt.str);
302 lydict_remove(ctx->ctx, tpdf->dsc);
303 lydict_remove(ctx->ctx, tpdf->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100304 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
305
306 lysp_type_free(ctx, &tpdf->type);
307
308}
309
Michal Vaskoc636ea42022-09-16 10:20:31 +0200310/**
311 * @brief Free the parsed grouping structure.
312 *
313 * @param[in] ctx Free context.
314 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
315 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200316static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200317lysp_grp_free(struct lysf_ctx *ctx, struct lysp_node_grp *grp)
Radek Krejci19a96102018-11-15 13:38:09 +0100318{
319 struct lysp_node *node, *next;
320
Radek Krejci19a96102018-11-15 13:38:09 +0100321 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100322 LY_LIST_FOR_SAFE((struct lysp_node *)grp->groupings, next, node) {
323 lysp_node_free(ctx, node);
324 }
Radek Krejci01180ac2021-01-27 08:48:22 +0100325 LY_LIST_FOR_SAFE(grp->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100326 lysp_node_free(ctx, node);
327 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100328 LY_LIST_FOR_SAFE((struct lysp_node *)grp->actions, next, node) {
329 lysp_node_free(ctx, node);
330 }
331 LY_LIST_FOR_SAFE((struct lysp_node *)grp->notifs, next, node) {
332 lysp_node_free(ctx, node);
333 }
Radek Krejci19a96102018-11-15 13:38:09 +0100334}
335
Radek Krejcif09e4e82019-06-14 15:08:11 +0200336void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200337lysp_when_free(struct lysf_ctx *ctx, struct lysp_when *when)
Radek Krejci19a96102018-11-15 13:38:09 +0100338{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200339 lydict_remove(ctx->ctx, when->cond);
340 lydict_remove(ctx->ctx, when->dsc);
341 lydict_remove(ctx->ctx, when->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100342 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
343}
344
Michal Vaskoc636ea42022-09-16 10:20:31 +0200345/**
346 * @brief Free the parsed augment structure.
347 *
348 * @param[in] ctx Free context.
349 * @param[in] aug Parsed schema augment structure to free. Note that the structure itself is not freed.
350 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200351static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200352lysp_augment_free(struct lysf_ctx *ctx, struct lysp_node_augment *aug)
Radek Krejci19a96102018-11-15 13:38:09 +0100353{
354 struct lysp_node *node, *next;
355
Michal Vaskoc636ea42022-09-16 10:20:31 +0200356 LY_LIST_FOR_SAFE(aug->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100357 lysp_node_free(ctx, node);
358 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200359 LY_LIST_FOR_SAFE((struct lysp_node *)aug->actions, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100360 lysp_node_free(ctx, node);
361 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200362 LY_LIST_FOR_SAFE((struct lysp_node *)aug->notifs, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100363 lysp_node_free(ctx, node);
364 }
Radek Krejci19a96102018-11-15 13:38:09 +0100365}
366
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200367void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200368lysp_deviate_free(struct lysf_ctx *ctx, struct lysp_deviate *d)
Radek Krejci19a96102018-11-15 13:38:09 +0100369{
Michal Vasko22df3f02020-08-24 13:29:22 +0200370 struct lysp_deviate_add *add = (struct lysp_deviate_add *)d;
371 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl *)d;
Radek Krejci19a96102018-11-15 13:38:09 +0100372
Michal Vasko12ef5362022-09-16 15:13:58 +0200373 if (!d) {
374 return;
375 }
376
Radek Krejci19a96102018-11-15 13:38:09 +0100377 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
Michal Vaskod989ba02020-08-24 10:59:24 +0200378 switch (d->mod) {
Radek Krejci19a96102018-11-15 13:38:09 +0100379 case LYS_DEV_NOT_SUPPORTED:
380 /* nothing to do */
381 break;
382 case LYS_DEV_ADD:
383 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
Michal Vaskoc636ea42022-09-16 10:20:31 +0200384 lydict_remove(ctx->ctx, add->units);
Radek Krejci19a96102018-11-15 13:38:09 +0100385 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200386 FREE_ARRAY(ctx->ctx, add->uniques, lysp_qname_free);
387 FREE_ARRAY(ctx->ctx, add->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100388 break;
389 case LYS_DEV_REPLACE:
390 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200391 lydict_remove(ctx->ctx, rpl->units);
392 lysp_qname_free(ctx->ctx, &rpl->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100393 break;
394 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200395 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100396 break;
397 }
398}
399
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200400void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200401lysp_deviation_free(struct lysf_ctx *ctx, struct lysp_deviation *dev)
Radek Krejci19a96102018-11-15 13:38:09 +0100402{
403 struct lysp_deviate *next, *iter;
404
Michal Vaskoc636ea42022-09-16 10:20:31 +0200405 lydict_remove(ctx->ctx, dev->nodeid);
406 lydict_remove(ctx->ctx, dev->dsc);
407 lydict_remove(ctx->ctx, dev->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100408 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
409 lysp_deviate_free(ctx, iter);
410 free(iter);
411 }
412 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
413}
414
Michal Vaskoc636ea42022-09-16 10:20:31 +0200415/**
416 * @brief Free the parsed refine structure.
417 *
418 * @param[in] ctx Free context.
419 * @param[in] ref Parsed schema refine structure to free. Note that the structure itself is not freed.
420 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200421static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200422lysp_refine_free(struct lysf_ctx *ctx, struct lysp_refine *ref)
Radek Krejci19a96102018-11-15 13:38:09 +0100423{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200424 lydict_remove(ctx->ctx, ref->nodeid);
425 lydict_remove(ctx->ctx, ref->dsc);
426 lydict_remove(ctx->ctx, ref->ref);
427 FREE_ARRAY(ctx->ctx, ref->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100428 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200429 lydict_remove(ctx->ctx, ref->presence);
430 FREE_ARRAY(ctx->ctx, ref->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100431 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
432}
433
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200434void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200435lysp_node_free(struct lysf_ctx *ctx, struct lysp_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +0100436{
437 struct lysp_node *child, *next;
Michal Vasko856ea972021-06-09 09:44:30 +0200438 struct lysp_node_container *cont;
439 struct lysp_node_leaf *leaf;
440 struct lysp_node_leaflist *llist;
441 struct lysp_node_list *list;
442 struct lysp_node_choice *choice;
443 struct lysp_node_case *cas;
444 struct lysp_node_uses *uses;
445 struct lysp_node_action *act;
446 struct lysp_node_action_inout *inout;
447 struct lysp_node_notif *notif;
Radek Krejci9a3823e2021-01-27 20:26:46 +0100448 struct lysp_restr *musts = lysp_node_musts(node);
449 struct lysp_when *when = lysp_node_when(node);
Radek Krejci19a96102018-11-15 13:38:09 +0100450
Michal Vaskoc636ea42022-09-16 10:20:31 +0200451 lydict_remove(ctx->ctx, node->name);
452 lydict_remove(ctx->ctx, node->dsc);
453 lydict_remove(ctx->ctx, node->ref);
454 FREE_ARRAY(ctx->ctx, node->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100455 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
456
Radek Krejci9a3823e2021-01-27 20:26:46 +0100457 FREE_MEMBER(ctx, when, lysp_when_free);
458 FREE_ARRAY(ctx, musts, lysp_restr_free);
459
Michal Vaskod989ba02020-08-24 10:59:24 +0200460 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100461 case LYS_CONTAINER:
Michal Vasko856ea972021-06-09 09:44:30 +0200462 cont = (struct lysp_node_container *)node;
463
Michal Vaskoc636ea42022-09-16 10:20:31 +0200464 lydict_remove(ctx->ctx, cont->presence);
Michal Vasko856ea972021-06-09 09:44:30 +0200465 FREE_ARRAY(ctx, cont->typedefs, lysp_tpdf_free);
466 if (cont->groupings) {
467 LY_LIST_FOR_SAFE(&cont->groupings->node, next, child) {
468 lysp_node_free(ctx, child);
469 }
470 }
471 LY_LIST_FOR_SAFE(cont->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100472 lysp_node_free(ctx, child);
473 }
Michal Vasko856ea972021-06-09 09:44:30 +0200474 if (cont->actions) {
475 LY_LIST_FOR_SAFE(&cont->actions->node, next, child) {
476 lysp_node_free(ctx, child);
477 }
Radek Krejci19a96102018-11-15 13:38:09 +0100478 }
Michal Vasko856ea972021-06-09 09:44:30 +0200479 if (cont->notifs) {
480 LY_LIST_FOR_SAFE(&cont->notifs->node, next, child) {
481 lysp_node_free(ctx, child);
482 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100483 }
Radek Krejci19a96102018-11-15 13:38:09 +0100484 break;
485 case LYS_LEAF:
Michal Vasko856ea972021-06-09 09:44:30 +0200486 leaf = (struct lysp_node_leaf *)node;
487
488 lysp_type_free(ctx, &leaf->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200489 lydict_remove(ctx->ctx, leaf->units);
490 lydict_remove(ctx->ctx, leaf->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100491 break;
492 case LYS_LEAFLIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200493 llist = (struct lysp_node_leaflist *)node;
494
495 lysp_type_free(ctx, &llist->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200496 lydict_remove(ctx->ctx, llist->units);
497 FREE_ARRAY(ctx->ctx, llist->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100498 break;
499 case LYS_LIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200500 list = (struct lysp_node_list *)node;
501
Michal Vaskoc636ea42022-09-16 10:20:31 +0200502 lydict_remove(ctx->ctx, list->key);
Michal Vasko856ea972021-06-09 09:44:30 +0200503 FREE_ARRAY(ctx, list->typedefs, lysp_tpdf_free);
504 if (list->groupings) {
505 LY_LIST_FOR_SAFE(&list->groupings->node, next, child) {
506 lysp_node_free(ctx, child);
507 }
508 }
509 LY_LIST_FOR_SAFE(list->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100510 lysp_node_free(ctx, child);
511 }
Michal Vasko856ea972021-06-09 09:44:30 +0200512 if (list->actions) {
513 LY_LIST_FOR_SAFE(&list->actions->node, next, child) {
514 lysp_node_free(ctx, child);
515 }
Radek Krejci19a96102018-11-15 13:38:09 +0100516 }
Michal Vasko856ea972021-06-09 09:44:30 +0200517 if (list->notifs) {
518 LY_LIST_FOR_SAFE(&list->notifs->node, next, child) {
519 lysp_node_free(ctx, child);
520 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100521 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200522 FREE_ARRAY(ctx->ctx, list->uniques, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100523 break;
524 case LYS_CHOICE:
Michal Vasko856ea972021-06-09 09:44:30 +0200525 choice = (struct lysp_node_choice *)node;
526
527 LY_LIST_FOR_SAFE(choice->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100528 lysp_node_free(ctx, child);
529 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200530 lydict_remove(ctx->ctx, choice->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100531 break;
532 case LYS_CASE:
Michal Vasko856ea972021-06-09 09:44:30 +0200533 cas = (struct lysp_node_case *)node;
534
535 LY_LIST_FOR_SAFE(cas->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100536 lysp_node_free(ctx, child);
537 }
538 break;
539 case LYS_ANYDATA:
540 case LYS_ANYXML:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100541 /* nothing special to do */
Radek Krejci19a96102018-11-15 13:38:09 +0100542 break;
543 case LYS_USES:
Michal Vasko856ea972021-06-09 09:44:30 +0200544 uses = (struct lysp_node_uses *)node;
545
546 FREE_ARRAY(ctx, uses->refines, lysp_refine_free);
547 if (uses->augments) {
548 LY_LIST_FOR_SAFE(&uses->augments->node, next, child) {
549 lysp_node_free(ctx, child);
550 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100551 }
552 break;
553 case LYS_RPC:
554 case LYS_ACTION:
Michal Vasko856ea972021-06-09 09:44:30 +0200555 act = (struct lysp_node_action *)node;
556
557 FREE_ARRAY(ctx, act->typedefs, lysp_tpdf_free);
558 if (act->groupings) {
559 LY_LIST_FOR_SAFE(&act->groupings->node, next, child) {
560 lysp_node_free(ctx, child);
561 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100562 }
Michal Vasko856ea972021-06-09 09:44:30 +0200563 if (act->input.nodetype) {
564 lysp_node_free(ctx, &act->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100565 }
Michal Vasko856ea972021-06-09 09:44:30 +0200566 if (act->output.nodetype) {
567 lysp_node_free(ctx, &act->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100568 }
569 break;
570 case LYS_INPUT:
571 case LYS_OUTPUT:
Michal Vasko856ea972021-06-09 09:44:30 +0200572 inout = (struct lysp_node_action_inout *)node;
573
574 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
575 if (inout->groupings) {
576 LY_LIST_FOR_SAFE(&inout->groupings->node, next, child) {
577 lysp_node_free(ctx, child);
578 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100579 }
Michal Vasko856ea972021-06-09 09:44:30 +0200580 LY_LIST_FOR_SAFE(inout->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100581 lysp_node_free(ctx, child);
582 }
583 /* do not free the node, it is never standalone but part of the action node */
584 return;
585 case LYS_NOTIF:
Michal Vasko856ea972021-06-09 09:44:30 +0200586 notif = (struct lysp_node_notif *)node;
587
588 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
589 if (notif->groupings) {
590 LY_LIST_FOR_SAFE(&notif->groupings->node, next, child) {
591 lysp_node_free(ctx, child);
592 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100593 }
Michal Vasko856ea972021-06-09 09:44:30 +0200594 LY_LIST_FOR_SAFE(notif->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100595 lysp_node_free(ctx, child);
596 }
597 break;
598 case LYS_GROUPING:
599 lysp_grp_free(ctx, (struct lysp_node_grp *)node);
600 break;
601 case LYS_AUGMENT:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100602 lysp_augment_free(ctx, ((struct lysp_node_augment *)node));
Radek Krejci19a96102018-11-15 13:38:09 +0100603 break;
604 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200605 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100606 }
607
608 free(node);
609}
610
Radek Krejci15f10ab2020-11-03 14:14:14 +0100611void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200612lysp_module_free(struct lysf_ctx *ctx, struct lysp_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +0100613{
Radek Krejci19a96102018-11-15 13:38:09 +0100614 struct lysp_node *node, *next;
615
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100616 if (!module) {
617 return;
618 }
Radek Krejci19a96102018-11-15 13:38:09 +0100619
620 FREE_ARRAY(ctx, module->imports, lysp_import_free);
Radek Krejci771928a2021-01-19 13:42:36 +0100621 FREE_ARRAY(ctx, module->includes, module->is_submod ? lysp_include_free_submodule : lysp_include_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100622
Radek Krejci19a96102018-11-15 13:38:09 +0100623 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
624 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
625 FREE_ARRAY(ctx, module->features, lysp_feature_free);
626 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
627 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100628 LY_LIST_FOR_SAFE((struct lysp_node *)module->groupings, next, node) {
629 lysp_node_free(ctx, node);
630 }
Radek Krejci19a96102018-11-15 13:38:09 +0100631 LY_LIST_FOR_SAFE(module->data, next, node) {
632 lysp_node_free(ctx, node);
633 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100634 LY_LIST_FOR_SAFE((struct lysp_node *)module->augments, next, node) {
635 lysp_node_free(ctx, node);
636 }
637 LY_LIST_FOR_SAFE((struct lysp_node *)module->rpcs, next, node) {
638 lysp_node_free(ctx, node);
639 }
640 LY_LIST_FOR_SAFE((struct lysp_node *)module->notifs, next, node) {
641 lysp_node_free(ctx, node);
642 }
Radek Krejci19a96102018-11-15 13:38:09 +0100643 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
644 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
645
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200646 if (module->is_submod) {
647 struct lysp_submodule *submod = (struct lysp_submodule *)module;
648
Michal Vaskoc636ea42022-09-16 10:20:31 +0200649 lydict_remove(ctx->ctx, submod->name);
650 lydict_remove(ctx->ctx, submod->filepath);
651 lydict_remove(ctx->ctx, submod->prefix);
652 lydict_remove(ctx->ctx, submod->org);
653 lydict_remove(ctx->ctx, submod->contact);
654 lydict_remove(ctx->ctx, submod->dsc);
655 lydict_remove(ctx->ctx, submod->ref);
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200656 }
657
Radek Krejci19a96102018-11-15 13:38:09 +0100658 free(module);
659}
660
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100661void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200662lysc_ext_instance_free(struct lysf_ctx *ctx, struct lysc_ext_instance *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100663{
Michal Vasko193dacd2022-10-13 08:43:05 +0200664 if (ext->def && ext->def->plugin && ext->def->plugin->cfree) {
665 ext->def->plugin->cfree(ctx->ctx, ext);
Radek Krejci38d85362019-09-05 16:26:38 +0200666 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200667 lydict_remove(ctx->ctx, ext->argument);
Radek Krejci0935f412019-08-20 16:15:18 +0200668 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
669}
670
671void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200672lysc_iffeature_free(struct lysf_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
Radek Krejci19a96102018-11-15 13:38:09 +0100673{
674 LY_ARRAY_FREE(iff->features);
675 free(iff->expr);
676}
677
Michal Vaskoc636ea42022-09-16 10:20:31 +0200678/**
679 * @brief Free the compiled when structure (decrease refcount) and NULL the provided pointer.
680 *
681 * @param[in] ctx Free context.
682 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
683 */
Radek Krejci19a96102018-11-15 13:38:09 +0100684static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200685lysc_when_free(struct lysf_ctx *ctx, struct lysc_when **w)
Radek Krejci58d171e2018-11-23 13:50:55 +0100686{
Radek Krejci00b874b2019-02-12 10:54:50 +0100687 if (--(*w)->refcount) {
688 return;
689 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200690 lyxp_expr_free(ctx->ctx, (*w)->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200691 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, (*w)->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200692 lydict_remove(ctx->ctx, (*w)->dsc);
693 lydict_remove(ctx->ctx, (*w)->ref);
Radek Krejci00b874b2019-02-12 10:54:50 +0100694 FREE_ARRAY(ctx, (*w)->exts, lysc_ext_instance_free);
695 free(*w);
Radek Krejci58d171e2018-11-23 13:50:55 +0100696}
697
Michal Vaskoc636ea42022-09-16 10:20:31 +0200698/**
699 * @brief Free the compiled must structure.
700 *
701 * @param[in] ctx Free context.
702 * @param[in,out] must Compiled must structure to be freed.
703 * Since the structure is typically part of the sized array, the structure itself is not freed.
704 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200705static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200706lysc_must_free(struct lysf_ctx *ctx, struct lysc_must *must)
Radek Krejci58d171e2018-11-23 13:50:55 +0100707{
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200708 if (!must) {
709 return;
710 }
711
Michal Vaskoc636ea42022-09-16 10:20:31 +0200712 lyxp_expr_free(ctx->ctx, must->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200713 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, must->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200714 lydict_remove(ctx->ctx, must->emsg);
715 lydict_remove(ctx->ctx, must->eapptag);
716 lydict_remove(ctx->ctx, must->dsc);
717 lydict_remove(ctx->ctx, must->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100718 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
719}
720
Michal Vaskoc636ea42022-09-16 10:20:31 +0200721/**
722 * @brief Unlink the identity from all derived identity arrays.
723 *
724 * @param[in] ident Identity to unlink.
725 */
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100726static void
727lysc_ident_derived_unlink(const struct lysc_ident *ident)
728{
729 LY_ARRAY_COUNT_TYPE u, v, w;
730 const struct lysp_submodule *submod;
Michal Vaskod84b8132022-03-15 10:45:44 +0100731 const struct lysp_module *base_pmod = NULL;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100732 const struct lysp_ident *identp = NULL;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100733 const struct lys_module *mod, *iter;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100734 const char *base_name;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100735 uint32_t i;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100736
737 /* find the parsed identity */
738 LY_ARRAY_FOR(ident->module->parsed->identities, u) {
739 if (ident->module->parsed->identities[u].name == ident->name) {
740 identp = &ident->module->parsed->identities[u];
741 base_pmod = ident->module->parsed;
742 break;
743 }
744 }
745 if (!identp) {
746 LY_ARRAY_FOR(ident->module->parsed->includes, v) {
747 submod = ident->module->parsed->includes[v].submodule;
748 LY_ARRAY_FOR(submod->identities, u) {
749 if (submod->identities[u].name == ident->name) {
750 identp = &submod->identities[u];
751 base_pmod = (struct lysp_module *)submod;
752 break;
753 }
754 }
755 }
756 }
757 assert(identp);
758
759 /* remove link from all the foreign bases, it may not be there if identity compilation failed */
760 LY_ARRAY_FOR(identp->bases, u) {
761 base_name = strchr(identp->bases[u], ':');
762 if (!base_name) {
763 continue;
764 }
765
766 /* prefixed identity */
767 mod = ly_resolve_prefix(ident->module->ctx, identp->bases[u], base_name - identp->bases[u], LY_VALUE_SCHEMA,
768 (void *)base_pmod);
769 if (!mod) {
770 continue;
771 }
772 ++base_name;
773
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100774 i = 0;
775 while ((iter = ly_ctx_get_module_iter(ident->module->ctx, &i))) {
776 if (iter == mod) {
777 break;
778 }
779 }
780 if (!iter) {
781 /* target module was freed already */
782 continue;
783 }
784
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100785 /* find the compiled base */
786 LY_ARRAY_FOR(mod->identities, v) {
787 if (!strcmp(mod->identities[v].name, base_name)) {
788 /* find the derived link */
789 LY_ARRAY_FOR(mod->identities[v].derived, w) {
790 if (mod->identities[v].derived[w] == ident) {
791 /* remove the link */
792 LY_ARRAY_DECREMENT(mod->identities[v].derived);
Michal Vasko3fedda12022-03-16 09:23:45 +0100793 if (!LY_ARRAY_COUNT(mod->identities[v].derived)) {
794 LY_ARRAY_FREE(mod->identities[v].derived);
795 mod->identities[v].derived = NULL;
796 } else if (w < LY_ARRAY_COUNT(mod->identities[v].derived)) {
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100797 memmove(mod->identities[v].derived + w, mod->identities[v].derived + w + 1,
798 (LY_ARRAY_COUNT(mod->identities[v].derived) - w) * sizeof ident);
799 }
800 break;
801 }
802 }
803 break;
804 }
805 }
806 }
807}
808
Michal Vaskoc636ea42022-09-16 10:20:31 +0200809/**
810 * @brief Free the compiled identity structure.
811 *
812 * @param[in] ctx Free context.
813 * @param[in,out] ident Compiled identity structure to be freed.
814 * Since the structure is typically part of the sized array, the structure itself is not freed.
815 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200816static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200817lysc_ident_free(struct lysf_ctx *ctx, struct lysc_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100818{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200819 lydict_remove(ctx->ctx, ident->name);
820 lydict_remove(ctx->ctx, ident->dsc);
821 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100822 LY_ARRAY_FREE(ident->derived);
823 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
824}
825
Michal Vaskoc636ea42022-09-16 10:20:31 +0200826/**
827 * @brief Free the compiled range structure.
828 *
829 * @param[in] ctx Free context.
830 * @param[in,out] range Compiled range structure to be freed.
831 * Since the structure is typically part of the sized array, the structure itself is not freed.
832 */
Radek Krejci19a96102018-11-15 13:38:09 +0100833static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200834lysc_range_free(struct lysf_ctx *ctx, struct lysc_range *range)
Radek Krejci19a96102018-11-15 13:38:09 +0100835{
836 LY_ARRAY_FREE(range->parts);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200837 lydict_remove(ctx->ctx, range->eapptag);
838 lydict_remove(ctx->ctx, range->emsg);
839 lydict_remove(ctx->ctx, range->dsc);
840 lydict_remove(ctx->ctx, range->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100841 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
842}
843
Michal Vasko51de7b72022-04-29 09:50:22 +0200844void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200845lysc_pattern_free(struct lysf_ctx *ctx, struct lysc_pattern **pattern)
Radek Krejci19a96102018-11-15 13:38:09 +0100846{
847 if (--(*pattern)->refcount) {
848 return;
849 }
Radek Krejci54579462019-04-30 12:47:06 +0200850 pcre2_code_free((*pattern)->code);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200851 lydict_remove(ctx->ctx, (*pattern)->expr);
852 lydict_remove(ctx->ctx, (*pattern)->eapptag);
853 lydict_remove(ctx->ctx, (*pattern)->emsg);
854 lydict_remove(ctx->ctx, (*pattern)->dsc);
855 lydict_remove(ctx->ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100856 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
857 free(*pattern);
858}
859
Michal Vaskof4fa90d2021-11-11 15:05:19 +0100860void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200861lysc_enum_item_free(struct lysf_ctx *ctx, struct lysc_type_bitenum_item *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100862{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200863 lydict_remove(ctx->ctx, item->name);
864 lydict_remove(ctx->ctx, item->dsc);
865 lydict_remove(ctx->ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100866 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
867}
868
Michal Vaskoc636ea42022-09-16 10:20:31 +0200869/**
870 * @brief Free the compiled type structure.
871 *
872 * @param[in] ctx Free context.
873 * @param[in,out] type Pointer to compiled type structure to be freed.
874 * Since the structure is typically part of the sized array, the structure itself is not freed.
875 */
Radek Krejcia3045382018-11-22 14:30:31 +0100876static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200877lysc_type2_free(struct lysf_ctx *ctx, struct lysc_type **type)
Radek Krejcia3045382018-11-22 14:30:31 +0100878{
879 lysc_type_free(ctx, *type);
880}
Radek Krejci0f969882020-08-21 16:56:47 +0200881
Radek Krejcicdfecd92018-11-26 11:27:32 +0100882void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200883lysc_type_free(struct lysf_ctx *ctx, struct lysc_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100884{
Michal Vaskod15c7de2022-05-09 15:34:09 +0200885 if (!type || (LY_ATOMIC_DEC_BARRIER(type->refcount) > 1)) {
Radek Krejci19a96102018-11-15 13:38:09 +0100886 return;
887 }
Radek Krejcib915ac92020-08-14 23:31:04 +0200888
Michal Vaskod989ba02020-08-24 10:59:24 +0200889 switch (type->basetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100890 case LY_TYPE_BINARY:
Michal Vasko22df3f02020-08-24 13:29:22 +0200891 FREE_MEMBER(ctx, ((struct lysc_type_bin *)type)->length, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100892 break;
893 case LY_TYPE_BITS:
Michal Vasko22df3f02020-08-24 13:29:22 +0200894 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 +0100895 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100896 case LY_TYPE_DEC64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200897 FREE_MEMBER(ctx, ((struct lysc_type_dec *)type)->range, lysc_range_free);
Radek Krejci6cba4292018-11-15 17:33:29 +0100898 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100899 case LY_TYPE_STRING:
Michal Vasko22df3f02020-08-24 13:29:22 +0200900 FREE_MEMBER(ctx, ((struct lysc_type_str *)type)->length, lysc_range_free);
901 FREE_ARRAY(ctx, ((struct lysc_type_str *)type)->patterns, lysc_pattern_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100902 break;
903 case LY_TYPE_ENUM:
Michal Vasko22df3f02020-08-24 13:29:22 +0200904 FREE_ARRAY(ctx, ((struct lysc_type_enum *)type)->enums, lysc_enum_item_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100905 break;
906 case LY_TYPE_INT8:
907 case LY_TYPE_UINT8:
908 case LY_TYPE_INT16:
909 case LY_TYPE_UINT16:
910 case LY_TYPE_INT32:
911 case LY_TYPE_UINT32:
912 case LY_TYPE_INT64:
913 case LY_TYPE_UINT64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200914 FREE_MEMBER(ctx, ((struct lysc_type_num *)type)->range, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100915 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100916 case LY_TYPE_IDENT:
Michal Vasko22df3f02020-08-24 13:29:22 +0200917 LY_ARRAY_FREE(((struct lysc_type_identityref *)type)->bases);
Radek Krejci555cb5b2018-11-16 14:54:33 +0100918 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100919 case LY_TYPE_UNION:
Michal Vasko22df3f02020-08-24 13:29:22 +0200920 FREE_ARRAY(ctx, ((struct lysc_type_union *)type)->types, lysc_type2_free);
Radek Krejcia3045382018-11-22 14:30:31 +0100921 break;
922 case LY_TYPE_LEAFREF:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200923 lyxp_expr_free(ctx->ctx, ((struct lysc_type_leafref *)type)->path);
Radek Krejci8df109d2021-04-23 12:19:08 +0200924 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, ((struct lysc_type_leafref *)type)->prefixes);
Michal Vaskod15c7de2022-05-09 15:34:09 +0200925 lysc_type_free(ctx, ((struct lysc_type_leafref *)type)->realtype);
Radek Krejcia3045382018-11-22 14:30:31 +0100926 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100927 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100928 case LY_TYPE_BOOL:
929 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100930 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100931 /* nothing to do */
932 break;
933 }
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200934
Michal Vaskof309c482024-01-22 12:07:00 +0100935 lydict_remove(ctx->ctx, type->name);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200936 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100937 free(type);
938}
939
Michal Vaskoc636ea42022-09-16 10:20:31 +0200940/**
941 * @brief Free the compiled input/output structure.
942 *
943 * @param[in] ctx Free context.
944 * @param[in,out] inout Compiled inout structure to be freed.
945 * Since the structure is part of the RPC/action structure, it is not freed itself.
946 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200947static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200948lysc_node_action_inout_free(struct lysf_ctx *ctx, struct lysc_node_action_inout *inout)
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100949{
950 struct lysc_node *child, *child_next;
951
Radek Krejcif538ce52019-03-05 10:46:14 +0100952 FREE_ARRAY(ctx, inout->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100953 LY_LIST_FOR_SAFE(inout->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100954 lysc_node_free_(ctx, child);
Radek Krejcif538ce52019-03-05 10:46:14 +0100955 }
956}
957
Michal Vaskoc636ea42022-09-16 10:20:31 +0200958/**
959 * @brief Free the compiled RPC/action structure.
960 *
961 * @param[in] ctx Free context.
962 * @param[in,out] action Compiled RPC/action structure to be freed.
963 * Since the structure is typically part of the sized array, the structure itself is not freed.
964 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200965static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200966lysc_node_action_free(struct lysf_ctx *ctx, struct lysc_node_action *action)
Radek Krejcif538ce52019-03-05 10:46:14 +0100967{
Michal Vasko37a0fe62021-02-03 09:53:04 +0100968 FREE_ARRAY(ctx, action->when, lysc_when_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100969 if (action->input.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100970 lysc_node_free_(ctx, &action->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100971 }
972 if (action->output.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100973 lysc_node_free_(ctx, &action->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100974 }
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100975}
976
Michal Vaskoc636ea42022-09-16 10:20:31 +0200977/**
978 * @brief Free the compiled notification structure.
979 *
980 * @param[in] ctx Free context.
981 * @param[in,out] notif Compiled notification structure to be freed.
982 * Since the structure is typically part of the sized array, the structure itself is not freed.
983 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200984static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200985lysc_node_notif_free(struct lysf_ctx *ctx, struct lysc_node_notif *notif)
Radek Krejcifc11bd72019-04-11 16:00:05 +0200986{
987 struct lysc_node *child, *child_next;
988
Michal Vasko37a0fe62021-02-03 09:53:04 +0100989 FREE_ARRAY(ctx, notif->when, lysc_when_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200990 FREE_ARRAY(ctx, notif->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100991 LY_LIST_FOR_SAFE(notif->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100992 lysc_node_free_(ctx, child);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200993 }
994}
995
Radek Krejcif2de0ed2019-05-02 14:13:18 +0200996void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200997lysc_node_container_free(struct lysf_ctx *ctx, struct lysc_node_container *node)
Radek Krejci19a96102018-11-15 13:38:09 +0100998{
999 struct lysc_node *child, *child_next;
1000
1001 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001002 lysc_node_free_(ctx, child);
Radek Krejci19a96102018-11-15 13:38:09 +01001003 }
Radek Krejci2a9fc652021-01-22 17:44:34 +01001004 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
1005 lysc_node_free_(ctx, child);
1006 }
1007 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1008 lysc_node_free_(ctx, child);
1009 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001010 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001011 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001012}
1013
Michal Vaskoc636ea42022-09-16 10:20:31 +02001014/**
1015 * @brief Free the compiled leaf structure.
1016 *
1017 * @param[in] ctx Free context.
1018 * @param[in,out] node Compiled leaf structure to be freed.
1019 * Since the structure is typically part of the sized array, the structure itself is not freed.
1020 */
Radek Krejci19a96102018-11-15 13:38:09 +01001021static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001022lysc_node_leaf_free(struct lysf_ctx *ctx, struct lysc_node_leaf *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001023{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001024 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001025 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001026 if (node->type) {
1027 lysc_type_free(ctx, node->type);
1028 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001029 lydict_remove(ctx->ctx, node->units);
Radek Krejcia1911222019-07-22 17:24:50 +02001030 if (node->dflt) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001031 node->dflt->realtype->plugin->free(ctx->ctx, node->dflt);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001032 lysc_type_free(ctx, (struct lysc_type *)node->dflt->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001033 free(node->dflt);
1034 }
Radek Krejci19a96102018-11-15 13:38:09 +01001035}
1036
Michal Vaskoc636ea42022-09-16 10:20:31 +02001037/**
1038 * @brief Free the compiled leaflist structure.
1039 *
1040 * @param[in] ctx Free context.
1041 * @param[in,out] node Compiled leaflist structure to be freed.
1042 * Since the structure is typically part of the sized array, the structure itself is not freed.
1043 */
Radek Krejci42452ac2018-11-28 17:09:52 +01001044static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001045lysc_node_leaflist_free(struct lysf_ctx *ctx, struct lysc_node_leaflist *node)
Radek Krejci42452ac2018-11-28 17:09:52 +01001046{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001047 LY_ARRAY_COUNT_TYPE u;
Radek Krejci42452ac2018-11-28 17:09:52 +01001048
Radek Krejci9a3823e2021-01-27 20:26:46 +01001049 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci42452ac2018-11-28 17:09:52 +01001050 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1051 if (node->type) {
1052 lysc_type_free(ctx, node->type);
1053 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001054 lydict_remove(ctx->ctx, node->units);
Radek Krejci42452ac2018-11-28 17:09:52 +01001055 LY_ARRAY_FOR(node->dflts, u) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001056 node->dflts[u]->realtype->plugin->free(ctx->ctx, node->dflts[u]);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001057 lysc_type_free(ctx, (struct lysc_type *)node->dflts[u]->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001058 free(node->dflts[u]);
Radek Krejci42452ac2018-11-28 17:09:52 +01001059 }
1060 LY_ARRAY_FREE(node->dflts);
1061}
1062
Michal Vaskoc636ea42022-09-16 10:20:31 +02001063/**
1064 * @brief Free the compiled list structure.
1065 *
1066 * @param[in] ctx Free context.
1067 * @param[in,out] node Compiled list structure to be freed.
1068 * Since the structure is typically part of the sized array, the structure itself is not freed.
1069 */
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001070static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001071lysc_node_list_free(struct lysf_ctx *ctx, struct lysc_node_list *node)
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001072{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001073 LY_ARRAY_COUNT_TYPE u;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001074 struct lysc_node *child, *child_next;
1075
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001076 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001077 lysc_node_free_(ctx, child);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001078 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001079 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001080 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1081
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001082 LY_ARRAY_FOR(node->uniques, u) {
1083 LY_ARRAY_FREE(node->uniques[u]);
1084 }
1085 LY_ARRAY_FREE(node->uniques);
1086
Radek Krejci2a9fc652021-01-22 17:44:34 +01001087 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
1088 lysc_node_free_(ctx, child);
1089 }
1090 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1091 lysc_node_free_(ctx, child);
1092 }
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001093}
1094
Michal Vaskoc636ea42022-09-16 10:20:31 +02001095/**
1096 * @brief Free the compiled choice structure.
1097 *
1098 * @param[in] ctx Free context.
1099 * @param[in,out] node Compiled choice structure to be freed.
1100 * Since the structure is typically part of the sized array, the structure itself is not freed.
1101 */
Radek Krejci056d0a82018-12-06 16:57:25 +01001102static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001103lysc_node_choice_free(struct lysf_ctx *ctx, struct lysc_node_choice *node)
Radek Krejci056d0a82018-12-06 16:57:25 +01001104{
1105 struct lysc_node *child, *child_next;
1106
Radek Krejci9a3823e2021-01-27 20:26:46 +01001107 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001108 LY_LIST_FOR_SAFE((struct lysc_node *)node->cases, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001109 lysc_node_free_(ctx, child);
Michal Vasko20424b42020-08-31 12:29:38 +02001110 }
1111}
1112
Michal Vaskoc636ea42022-09-16 10:20:31 +02001113/**
1114 * @brief Free the compiled case structure.
1115 *
1116 * @param[in] ctx Free context.
1117 * @param[in,out] node Compiled case structure to be freed.
1118 * Since the structure is typically part of the sized array, the structure itself is not freed.
1119 */
Michal Vasko20424b42020-08-31 12:29:38 +02001120static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001121lysc_node_case_free(struct lysf_ctx *ctx, struct lysc_node_case *node)
Michal Vasko20424b42020-08-31 12:29:38 +02001122{
1123 struct lysc_node *child, *child_next;
1124
Radek Krejci9a3823e2021-01-27 20:26:46 +01001125 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001126 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001127 lysc_node_free_(ctx, child);
Radek Krejci056d0a82018-12-06 16:57:25 +01001128 }
Radek Krejci9800fb82018-12-13 14:26:23 +01001129}
Radek Krejci056d0a82018-12-06 16:57:25 +01001130
Michal Vaskoc636ea42022-09-16 10:20:31 +02001131/**
1132 * @brief Free the compiled anyxml/anydata structure.
1133 *
1134 * @param[in] ctx Free context.
1135 * @param[in,out] node Compiled anyxml/anydata structure to be freed.
1136 * Since the structure is typically part of the sized array, the structure itself is not freed.
1137 */
Radek Krejci9800fb82018-12-13 14:26:23 +01001138static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001139lysc_node_anydata_free(struct lysf_ctx *ctx, struct lysc_node_anydata *node)
Radek Krejci9800fb82018-12-13 14:26:23 +01001140{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001141 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9800fb82018-12-13 14:26:23 +01001142 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +01001143}
1144
Michal Vaskoc636ea42022-09-16 10:20:31 +02001145/**
1146 * @brief Free the compiled node structure.
1147 *
1148 * @param[in] ctx Free context.
1149 * @param[in,out] node Compiled node structure to be freed.
1150 * Since the structure is typically part of the sized array, the structure itself is not freed.
1151 */
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001152static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001153lysc_node_free_(struct lysf_ctx *ctx, struct lysc_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001154{
Radek Krejci2a9fc652021-01-22 17:44:34 +01001155 ly_bool inout = 0;
1156
Radek Krejci19a96102018-11-15 13:38:09 +01001157 /* common part */
Michal Vaskoc636ea42022-09-16 10:20:31 +02001158 lydict_remove(ctx->ctx, node->name);
1159 lydict_remove(ctx->ctx, node->dsc);
1160 lydict_remove(ctx->ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +01001161
1162 /* nodetype-specific part */
Michal Vaskod989ba02020-08-24 10:59:24 +02001163 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +01001164 case LYS_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02001165 lysc_node_container_free(ctx, (struct lysc_node_container *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001166 break;
1167 case LYS_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02001168 lysc_node_leaf_free(ctx, (struct lysc_node_leaf *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001169 break;
Radek Krejci42452ac2018-11-28 17:09:52 +01001170 case LYS_LEAFLIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001171 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist *)node);
Radek Krejci42452ac2018-11-28 17:09:52 +01001172 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001173 case LYS_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001174 lysc_node_list_free(ctx, (struct lysc_node_list *)node);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001175 break;
Radek Krejci056d0a82018-12-06 16:57:25 +01001176 case LYS_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02001177 lysc_node_choice_free(ctx, (struct lysc_node_choice *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001178 break;
1179 case LYS_CASE:
Michal Vasko20424b42020-08-31 12:29:38 +02001180 lysc_node_case_free(ctx, (struct lysc_node_case *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001181 break;
Radek Krejci9800fb82018-12-13 14:26:23 +01001182 case LYS_ANYDATA:
1183 case LYS_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02001184 lysc_node_anydata_free(ctx, (struct lysc_node_anydata *)node);
Radek Krejci9800fb82018-12-13 14:26:23 +01001185 break;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001186 case LYS_RPC:
1187 case LYS_ACTION:
1188 lysc_node_action_free(ctx, (struct lysc_node_action *)node);
1189 break;
1190 case LYS_INPUT:
1191 case LYS_OUTPUT:
1192 lysc_node_action_inout_free(ctx, (struct lysc_node_action_inout *)node);
1193 inout = 1;
1194 break;
1195 case LYS_NOTIF:
1196 lysc_node_notif_free(ctx, (struct lysc_node_notif *)node);
1197 break;
Radek Krejci19a96102018-11-15 13:38:09 +01001198 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +02001199 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +01001200 }
1201
Radek Krejci056d0a82018-12-06 16:57:25 +01001202 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001203
1204 if (!inout) {
1205 free(node);
1206 }
Radek Krejci19a96102018-11-15 13:38:09 +01001207}
1208
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001209void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001210lysc_node_free(struct lysf_ctx *ctx, struct lysc_node *node, ly_bool unlink)
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001211{
Michal Vaskoe02e7402021-07-23 08:29:28 +02001212 struct lysc_node *next, *iter, **child_p;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001213
Radek Krejci2a9fc652021-01-22 17:44:34 +01001214 if (node->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
Michal Vaskoe02e7402021-07-23 08:29:28 +02001215 /* inouts are part of actions and cannot be unlinked/freed separately, we can only free all the children */
1216 struct lysc_node_action_inout *inout = (struct lysc_node_action_inout *)node;
Michal Vasko26bbb272022-08-02 14:54:33 +02001217
Michal Vaskoe02e7402021-07-23 08:29:28 +02001218 LY_LIST_FOR_SAFE(inout->child, next, iter) {
1219 lysc_node_free_(ctx, iter);
1220 }
1221 inout->child = NULL;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001222 return;
1223 }
1224
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001225 if (unlink) {
1226 /* unlink from siblings */
1227 if (node->prev->next) {
1228 node->prev->next = node->next;
1229 }
1230 if (node->next) {
1231 node->next->prev = node->prev;
1232 } else {
1233 /* unlinking the last node */
1234 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001235 if (node->nodetype == LYS_ACTION) {
1236 iter = (struct lysc_node *)lysc_node_actions(node->parent);
1237 } else if (node->nodetype == LYS_NOTIF) {
1238 iter = (struct lysc_node *)lysc_node_notifs(node->parent);
1239 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001240 iter = (struct lysc_node *)lysc_node_child(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001241 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001242 LY_CHECK_ERR_RET(!iter, LOGINT(ctx->ctx), );
Radek Krejci2a9fc652021-01-22 17:44:34 +01001243 } else if (node->nodetype == LYS_RPC) {
1244 iter = (struct lysc_node *)node->module->compiled->rpcs;
1245 } else if (node->nodetype == LYS_NOTIF) {
1246 iter = (struct lysc_node *)node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001247 } else {
1248 iter = node->module->compiled->data;
1249 }
1250 /* update the "last" pointer from the first node */
1251 iter->prev = node->prev;
1252 }
1253
1254 /* unlink from parent */
1255 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001256 if (node->nodetype == LYS_ACTION) {
1257 child_p = (struct lysc_node **)lysc_node_actions_p(node->parent);
1258 } else if (node->nodetype == LYS_NOTIF) {
1259 child_p = (struct lysc_node **)lysc_node_notifs_p(node->parent);
1260 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001261 child_p = lysc_node_child_p(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001262 }
1263 } else if (node->nodetype == LYS_RPC) {
1264 child_p = (struct lysc_node **)&node->module->compiled->rpcs;
1265 } else if (node->nodetype == LYS_NOTIF) {
1266 child_p = (struct lysc_node **)&node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001267 } else {
1268 child_p = &node->module->compiled->data;
1269 }
1270 if (child_p && (*child_p == node)) {
1271 /* the node is the first child */
1272 *child_p = node->next;
1273 }
1274 }
1275
1276 lysc_node_free_(ctx, node);
1277}
1278
Radek Krejci90ed21e2021-04-12 14:47:46 +02001279void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001280lysc_module_free(struct lysf_ctx *ctx, struct lysc_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +01001281{
Radek Krejci19a96102018-11-15 13:38:09 +01001282 struct lysc_node *node, *node_next;
1283
Radek Krejci90ed21e2021-04-12 14:47:46 +02001284 if (!module) {
1285 return;
1286 }
1287
Radek Krejci19a96102018-11-15 13:38:09 +01001288 LY_LIST_FOR_SAFE(module->data, node_next, node) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001289 lysc_node_free_(ctx, node);
Radek Krejci19a96102018-11-15 13:38:09 +01001290 }
Radek Krejci2a9fc652021-01-22 17:44:34 +01001291 LY_LIST_FOR_SAFE((struct lysc_node *)module->rpcs, node_next, node) {
1292 lysc_node_free_(ctx, node);
1293 }
1294 LY_LIST_FOR_SAFE((struct lysc_node *)module->notifs, node_next, node) {
1295 lysc_node_free_(ctx, node);
1296 }
Radek Krejci19a96102018-11-15 13:38:09 +01001297 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
1298
1299 free(module);
1300}
1301
1302void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001303lys_module_free(struct lysf_ctx *ctx, struct lys_module *module, ly_bool remove_links)
Radek Krejci19a96102018-11-15 13:38:09 +01001304{
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001305 LY_ARRAY_COUNT_TYPE u;
1306
Radek Krejci19a96102018-11-15 13:38:09 +01001307 if (!module) {
1308 return;
1309 }
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001310
Michal Vaskoee757602021-06-10 14:38:19 +02001311 assert(!module->implemented);
1312 assert(!module->compiled);
Radek Krejci19a96102018-11-15 13:38:09 +01001313
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001314 if (remove_links) {
1315 /* remove derived identity links */
1316 LY_ARRAY_FOR(module->identities, u) {
1317 lysc_ident_derived_unlink(&module->identities[u]);
1318 }
1319 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001320 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
1321 lysp_module_free(ctx, module->parsed);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001322
Michal Vasko7f45cf22020-10-01 12:49:44 +02001323 LY_ARRAY_FREE(module->augmented_by);
1324 LY_ARRAY_FREE(module->deviated_by);
1325
Michal Vaskoc636ea42022-09-16 10:20:31 +02001326 lydict_remove(ctx->ctx, module->name);
1327 lydict_remove(ctx->ctx, module->revision);
1328 lydict_remove(ctx->ctx, module->ns);
1329 lydict_remove(ctx->ctx, module->prefix);
1330 lydict_remove(ctx->ctx, module->filepath);
1331 lydict_remove(ctx->ctx, module->org);
1332 lydict_remove(ctx->ctx, module->contact);
1333 lydict_remove(ctx->ctx, module->dsc);
1334 lydict_remove(ctx->ctx, module->ref);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001335
Radek Krejci19a96102018-11-15 13:38:09 +01001336 free(module);
1337}
Michal Vasko33ff9422020-07-03 09:50:39 +02001338
Michal Vaskoc636ea42022-09-16 10:20:31 +02001339void
1340lysf_ctx_erase(struct lysf_ctx *ctx)
1341{
1342 struct lysc_ext *ext;
1343 uint32_t i;
1344
1345 for (i = 0; i < ctx->ext_set.count; ++i) {
1346 ext = ctx->ext_set.objs[i];
1347
1348 lydict_remove(ctx->ctx, ext->name);
1349 lydict_remove(ctx->ctx, ext->argname);
1350 free(ext);
1351 }
1352 ly_set_erase(&ctx->ext_set, NULL);
1353}
1354
Jan Kundrátc53a7ec2021-12-09 16:01:19 +01001355LIBYANG_API_DEF void
Michal Vasko193dacd2022-10-13 08:43:05 +02001356lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext_substmt *substmts)
Radek Krejci38d85362019-09-05 16:26:38 +02001357{
Radek Krejci1b2eef82021-02-17 11:17:27 +01001358 LY_ARRAY_COUNT_TYPE u;
Michal Vasko193dacd2022-10-13 08:43:05 +02001359 struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
1360 ly_bool node_free;
Radek Krejci1b2eef82021-02-17 11:17:27 +01001361
1362 LY_ARRAY_FOR(substmts, u) {
Radek Krejci38d85362019-09-05 16:26:38 +02001363 if (!substmts[u].storage) {
1364 continue;
1365 }
1366
Michal Vaskod989ba02020-08-24 10:59:24 +02001367 switch (substmts[u].stmt) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001368 case LY_STMT_NOTIFICATION:
1369 case LY_STMT_INPUT:
1370 case LY_STMT_OUTPUT:
Radek Krejci6b88a462021-02-17 12:39:34 +01001371 case LY_STMT_ACTION:
Michal Vasko193dacd2022-10-13 08:43:05 +02001372 case LY_STMT_RPC:
Radek Krejci6b88a462021-02-17 12:39:34 +01001373 case LY_STMT_ANYDATA:
1374 case LY_STMT_ANYXML:
Michal Vasko193dacd2022-10-13 08:43:05 +02001375 case LY_STMT_AUGMENT:
1376 case LY_STMT_CASE:
Radek Krejci6b88a462021-02-17 12:39:34 +01001377 case LY_STMT_CHOICE:
Michal Vasko193dacd2022-10-13 08:43:05 +02001378 case LY_STMT_CONTAINER:
1379 case LY_STMT_GROUPING:
Radek Krejci6b88a462021-02-17 12:39:34 +01001380 case LY_STMT_LEAF:
1381 case LY_STMT_LEAF_LIST:
1382 case LY_STMT_LIST:
Michal Vasko193dacd2022-10-13 08:43:05 +02001383 case LY_STMT_USES: {
1384 struct lysp_node *child, *child_next;
Radek Krejci6b88a462021-02-17 12:39:34 +01001385
Michal Vasko53eb6a12024-06-13 11:38:47 +02001386 LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001387 node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
1388 lysp_node_free(&fctx, child);
1389 if (node_free) {
1390 free(child);
1391 }
Radek Krejci38d85362019-09-05 16:26:38 +02001392 }
Michal Vasko53eb6a12024-06-13 11:38:47 +02001393 *VOIDPTR2_C(substmts[u].storage) = NULL;
Radek Krejci38d85362019-09-05 16:26:38 +02001394 break;
Radek Krejci6b88a462021-02-17 12:39:34 +01001395 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001396 case LY_STMT_BASE:
1397 /* multiple strings */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001398 FREE_ARRAY(ctx, **(const char ***)VOIDPTR2_C(substmts[u].storage), lydict_remove);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001399 break;
Michal Vasko193dacd2022-10-13 08:43:05 +02001400
1401 case LY_STMT_BIT:
1402 case LY_STMT_ENUM:
1403 /* single enum */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001404 lysp_type_enum_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001405 break;
1406
1407 case LY_STMT_DEVIATE:
1408 /* single deviate */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001409 lysp_deviate_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001410 break;
1411
1412 case LY_STMT_DEVIATION:
1413 /* single deviation */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001414 lysp_deviation_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001415 break;
1416
1417 case LY_STMT_EXTENSION:
1418 /* single extension */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001419 lysp_ext_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001420 break;
1421
1422 case LY_STMT_EXTENSION_INSTANCE:
1423 /* multiple extension instances */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001424 FREE_ARRAY(&fctx, *(struct lysp_ext_instance **)VOIDPTR2_C(substmts[u].storage), lysp_ext_instance_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001425 break;
1426
1427 case LY_STMT_FEATURE:
1428 /* multiple features */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001429 FREE_ARRAY(&fctx, *(struct lysp_feature **)VOIDPTR2_C(substmts[u].storage), lysp_feature_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001430 break;
1431
1432 case LY_STMT_IDENTITY:
1433 /* multiple identities */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001434 FREE_ARRAY(&fctx, *(struct lysp_ident **)VOIDPTR2_C(substmts[u].storage), lysp_ident_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001435 break;
1436
1437 case LY_STMT_IMPORT:
1438 /* multiple imports */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001439 FREE_ARRAY(&fctx, *(struct lysp_import **)VOIDPTR2_C(substmts[u].storage), lysp_import_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001440 break;
1441
1442 case LY_STMT_INCLUDE:
1443 /* multiple includes */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001444 FREE_ARRAY(&fctx, *(struct lysp_include **)VOIDPTR2_C(substmts[u].storage), lysp_include_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001445 break;
1446
1447 case LY_STMT_REFINE:
1448 /* multiple refines */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001449 FREE_ARRAY(&fctx, *(struct lysp_refine **)VOIDPTR2_C(substmts[u].storage), lysp_refine_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001450 break;
1451
1452 case LY_STMT_REVISION:
1453 /* multiple revisions */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001454 FREE_ARRAY(&fctx, *(struct lysp_revision **)VOIDPTR2_C(substmts[u].storage), lysp_revision_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001455 break;
1456
Radek Krejci6b88a462021-02-17 12:39:34 +01001457 case LY_STMT_CONFIG:
Michal Vasko193dacd2022-10-13 08:43:05 +02001458 case LY_STMT_FRACTION_DIGITS:
1459 case LY_STMT_MANDATORY:
1460 case LY_STMT_MAX_ELEMENTS:
1461 case LY_STMT_MIN_ELEMENTS:
1462 case LY_STMT_ORDERED_BY:
1463 case LY_STMT_POSITION:
1464 case LY_STMT_REQUIRE_INSTANCE:
Radek Krejci6b88a462021-02-17 12:39:34 +01001465 case LY_STMT_STATUS:
Michal Vasko193dacd2022-10-13 08:43:05 +02001466 case LY_STMT_VALUE:
1467 case LY_STMT_YANG_VERSION:
1468 case LY_STMT_YIN_ELEMENT:
Radek Krejci6b88a462021-02-17 12:39:34 +01001469 /* nothing to do */
1470 break;
Michal Vasko193dacd2022-10-13 08:43:05 +02001471
1472 case LY_STMT_ARGUMENT:
1473 case LY_STMT_BELONGS_TO:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001474 case LY_STMT_CONTACT:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001475 case LY_STMT_DESCRIPTION:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001476 case LY_STMT_ERROR_APP_TAG:
1477 case LY_STMT_ERROR_MESSAGE:
1478 case LY_STMT_KEY:
Michal Vasko193dacd2022-10-13 08:43:05 +02001479 case LY_STMT_MODIFIER:
1480 case LY_STMT_NAMESPACE:
1481 case LY_STMT_ORGANIZATION:
1482 case LY_STMT_PREFIX:
1483 case LY_STMT_PRESENCE:
1484 case LY_STMT_REFERENCE:
1485 case LY_STMT_REVISION_DATE:
1486 case LY_STMT_UNITS:
1487 /* single string */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001488 lydict_remove(ctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001489 break;
1490
1491 case LY_STMT_LENGTH:
1492 case LY_STMT_MUST:
1493 case LY_STMT_PATTERN:
1494 case LY_STMT_RANGE:
1495 /* multiple restrictions */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001496 FREE_ARRAY(&fctx, *(struct lysp_restr **)VOIDPTR2_C(substmts[u].storage), lysp_restr_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001497 break;
1498
1499 case LY_STMT_WHEN:
1500 /* multiple whens */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001501 FREE_ARRAY(&fctx, *(struct lysp_when **)VOIDPTR2_C(substmts[u].storage), lysp_when_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001502 break;
1503
1504 case LY_STMT_PATH:
1505 /* single expression */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001506 lyxp_expr_free(ctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001507 break;
1508
1509 case LY_STMT_DEFAULT:
1510 case LY_STMT_IF_FEATURE:
1511 case LY_STMT_UNIQUE:
1512 /* multiple qnames */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001513 FREE_ARRAY(ctx, *(struct lysp_qname **)VOIDPTR2_C(substmts[u].storage), lysp_qname_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001514 break;
1515
1516 case LY_STMT_TYPEDEF:
1517 /* multiple typedefs */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001518 FREE_ARRAY(&fctx, *(struct lysp_tpdf **)VOIDPTR2_C(substmts[u].storage), lysp_tpdf_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001519 break;
1520
1521 case LY_STMT_TYPE: {
1522 /* single type */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001523 struct lysp_type **type_p = VOIDPTR_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001524
1525 lysp_type_free(&fctx, *type_p);
1526 free(*type_p);
1527 break;
1528 }
1529 case LY_STMT_MODULE:
1530 case LY_STMT_SUBMODULE:
1531 /* single (sub)module */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001532 lysp_module_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001533 break;
1534
1535 default:
1536 LOGINT(ctx);
1537 }
1538 }
1539
1540 LY_ARRAY_FREE(substmts);
1541}
1542
1543LIBYANG_API_DEF void
1544lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
1545{
1546 LY_ARRAY_COUNT_TYPE u;
1547 struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
1548 ly_bool node_free;
1549
1550 LY_ARRAY_FOR(substmts, u) {
1551 if (!substmts[u].storage) {
1552 continue;
1553 }
1554
1555 switch (substmts[u].stmt) {
1556 case LY_STMT_NOTIFICATION:
1557 case LY_STMT_INPUT:
1558 case LY_STMT_OUTPUT:
1559 case LY_STMT_ACTION:
1560 case LY_STMT_RPC:
1561 case LY_STMT_ANYDATA:
1562 case LY_STMT_ANYXML:
1563 case LY_STMT_CASE:
1564 case LY_STMT_CHOICE:
1565 case LY_STMT_CONTAINER:
1566 case LY_STMT_LEAF:
1567 case LY_STMT_LEAF_LIST:
1568 case LY_STMT_LIST: {
1569 struct lysc_node *child, *child_next;
1570
Michal Vasko53eb6a12024-06-13 11:38:47 +02001571 LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001572 node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
1573 lysc_node_free_(&fctx, child);
1574 if (node_free) {
1575 free(child);
1576 }
1577 }
Michal Vasko53eb6a12024-06-13 11:38:47 +02001578 *VOIDPTR2_C(substmts[u].storage) = NULL;
Michal Vasko193dacd2022-10-13 08:43:05 +02001579 break;
1580 }
1581 case LY_STMT_USES:
1582 case LY_STMT_CONFIG:
1583 case LY_STMT_FRACTION_DIGITS:
1584 case LY_STMT_MANDATORY:
1585 case LY_STMT_MAX_ELEMENTS:
1586 case LY_STMT_MIN_ELEMENTS:
1587 case LY_STMT_ORDERED_BY:
1588 case LY_STMT_POSITION:
1589 case LY_STMT_REQUIRE_INSTANCE:
1590 case LY_STMT_STATUS:
1591 case LY_STMT_VALUE:
1592 /* nothing to do */
1593 break;
1594
1595 case LY_STMT_ARGUMENT:
1596 case LY_STMT_CONTACT:
1597 case LY_STMT_DESCRIPTION:
1598 case LY_STMT_ERROR_APP_TAG:
1599 case LY_STMT_ERROR_MESSAGE:
1600 case LY_STMT_KEY:
1601 case LY_STMT_MODIFIER:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001602 case LY_STMT_NAMESPACE:
1603 case LY_STMT_ORGANIZATION:
1604 case LY_STMT_PRESENCE:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001605 case LY_STMT_REFERENCE:
Michal Vasko9c3556a2022-10-06 16:08:47 +02001606 case LY_STMT_UNITS: {
1607 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001608 const char *str = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko26bbb272022-08-02 14:54:33 +02001609
Michal Vasko9c3556a2022-10-06 16:08:47 +02001610 lydict_remove(ctx, str);
Radek Krejci38d85362019-09-05 16:26:38 +02001611 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001612 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001613 case LY_STMT_BIT:
1614 case LY_STMT_ENUM: {
1615 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001616 struct lysc_type_bitenum_item *items = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001617
1618 FREE_ARRAY(&fctx, items, lysc_enum_item_free);
1619 break;
1620 }
1621 case LY_STMT_LENGTH:
1622 case LY_STMT_RANGE: {
1623 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001624 struct lysc_range *range = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001625
1626 lysc_range_free(&fctx, range);
1627 break;
1628 }
Michal Vasko9c3556a2022-10-06 16:08:47 +02001629 case LY_STMT_MUST: {
Michal Vasko193dacd2022-10-13 08:43:05 +02001630 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001631 struct lysc_must *musts = *VOIDPTR2_C(substmts[u].storage);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001632
Michal Vasko9c3556a2022-10-06 16:08:47 +02001633 FREE_ARRAY(&fctx, musts, lysc_must_free);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001634 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001635 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001636 case LY_STMT_WHEN:
1637 /* single item, expects a pointer */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001638 lysc_when_free(&fctx, VOIDPTR_C(substmts[u].storage));
Radek Krejci38d85362019-09-05 16:26:38 +02001639 break;
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001640
Michal Vasko193dacd2022-10-13 08:43:05 +02001641 case LY_STMT_PATTERN: {
1642 /* sized array of pointers */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001643 struct lysc_pattern **patterns = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001644
1645 FREE_ARRAY(&fctx, patterns, lysc_pattern_free);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001646 break;
1647 }
Michal Vasko9c3556a2022-10-06 16:08:47 +02001648 case LY_STMT_TYPE: {
1649 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001650 struct lysc_type *type = *VOIDPTR2_C(substmts[u].storage);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001651
Michal Vasko9c3556a2022-10-06 16:08:47 +02001652 lysc_type_free(&fctx, type);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001653 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001654 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001655 case LY_STMT_IDENTITY: {
1656 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001657 struct lysc_ident *idents = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001658
1659 FREE_ARRAY(&fctx, idents, lysc_ident_free);
1660 break;
1661 }
1662 case LY_STMT_EXTENSION_INSTANCE: {
1663 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001664 struct lysc_ext_instance *exts = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001665
1666 FREE_ARRAY(&fctx, exts, lysc_ext_instance_free);
1667 break;
1668 }
1669 case LY_STMT_AUGMENT:
1670 case LY_STMT_BASE:
1671 case LY_STMT_BELONGS_TO:
1672 case LY_STMT_DEFAULT:
1673 case LY_STMT_DEVIATE:
1674 case LY_STMT_DEVIATION:
1675 case LY_STMT_EXTENSION:
1676 case LY_STMT_FEATURE:
1677 case LY_STMT_GROUPING:
1678 case LY_STMT_IF_FEATURE:
1679 case LY_STMT_IMPORT:
1680 case LY_STMT_INCLUDE:
1681 case LY_STMT_MODULE:
1682 case LY_STMT_PATH:
1683 case LY_STMT_PREFIX:
1684 case LY_STMT_REFINE:
1685 case LY_STMT_REVISION:
1686 case LY_STMT_REVISION_DATE:
1687 case LY_STMT_SUBMODULE:
1688 case LY_STMT_TYPEDEF:
1689 case LY_STMT_UNIQUE:
1690 case LY_STMT_YANG_VERSION:
1691 case LY_STMT_YIN_ELEMENT:
1692 /* it is not possible to compile these statements */
1693 break;
1694
Radek Krejci38d85362019-09-05 16:26:38 +02001695 default:
1696 LOGINT(ctx);
1697 }
1698 }
Radek Krejci1b2eef82021-02-17 11:17:27 +01001699
1700 LY_ARRAY_FREE(substmts);
Radek Krejci38d85362019-09-05 16:26:38 +02001701}
David Sedlákebd3acf2019-07-26 15:04:32 +02001702
1703void
Michal Vaskod0625d72022-10-06 15:02:50 +02001704lysp_yang_ctx_free(struct lysp_yang_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001705{
1706 if (ctx) {
Michal Vaskod0625d72022-10-06 15:02:50 +02001707 if (ctx->main_ctx == (struct lysp_ctx *)ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001708 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1709 ly_set_erase(&ctx->grps_nodes, NULL);
1710 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001711 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vaskoc0c64ae2022-10-06 10:15:23 +02001712 ly_set_erase(&ctx->ext_inst, NULL);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001713 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1714 if (!ctx->parsed_mods->count) {
1715 ly_set_free(ctx->parsed_mods, NULL);
1716 }
David Sedlákebd3acf2019-07-26 15:04:32 +02001717 free(ctx);
1718 }
1719}
1720
1721void
Michal Vaskod0625d72022-10-06 15:02:50 +02001722lysp_yin_ctx_free(struct lysp_yin_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001723{
1724 if (ctx) {
Michal Vaskod0625d72022-10-06 15:02:50 +02001725 if (ctx->main_ctx == (struct lysp_ctx *)ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001726 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1727 ly_set_erase(&ctx->grps_nodes, NULL);
1728 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001729 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vaskoc0c64ae2022-10-06 10:15:23 +02001730 ly_set_erase(&ctx->ext_inst, NULL);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001731 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1732 if (!ctx->parsed_mods->count) {
1733 ly_set_free(ctx->parsed_mods, NULL);
1734 }
Michal Vaskob36053d2020-03-26 15:49:30 +01001735 lyxml_ctx_free(ctx->xmlctx);
David Sedlákebd3acf2019-07-26 15:04:32 +02001736 free(ctx);
1737 }
1738}