blob: ee05d3cf72b4a39b305a5e54f838bbd6407f708a [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 }
Michal Vasko35274cf2024-07-04 12:01:00 +020083
84 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +010085}
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/**
Michal Vasko193dacd2022-10-13 08:43:05 +0200167 * @brief Free the compiled extension definition and NULL the provided pointer.
168 *
169 * @param[in] ctx Free context.
170 * @param[in,out] ext Compiled extension definition to be freed.
171 */
172static void
173lysc_extension_free(struct lysf_ctx *ctx, struct lysc_ext **ext)
174{
175 if (ly_set_contains(&ctx->ext_set, *ext, NULL)) {
176 /* already freed and only referenced again in this module */
177 return;
178 }
179
180 /* remember this extension to be freed, nothing to do on error */
181 (void)ly_set_add(&ctx->ext_set, *ext, 0, NULL);
182
183 /* recursive exts free */
184 FREE_ARRAY(ctx, (*ext)->exts, lysc_ext_instance_free);
185
186 *ext = NULL;
187}
188
189/**
Michal Vaskoc636ea42022-09-16 10:20:31 +0200190 * @brief Free the parsed ext structure.
191 *
192 * @param[in] ctx Free context.
193 * @param[in] ext Parsed schema ext structure to free. Note that the structure itself is not freed.
194 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200195static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200196lysp_ext_free(struct lysf_ctx *ctx, struct lysp_ext *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100197{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200198 lydict_remove(ctx->ctx, ext->name);
199 lydict_remove(ctx->ctx, ext->argname);
200 lydict_remove(ctx->ctx, ext->dsc);
201 lydict_remove(ctx->ctx, ext->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100202 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
Michal Vasko5fe75f12020-03-02 13:52:37 +0100203 if (ext->compiled) {
204 lysc_extension_free(ctx, &ext->compiled);
205 }
Radek Krejci19a96102018-11-15 13:38:09 +0100206}
207
Michal Vaskoc636ea42022-09-16 10:20:31 +0200208/**
209 * @brief Free the parsed feature structure.
210 *
211 * @param[in] ctx Free context.
212 * @param[in] feat Parsed schema feature structure to free. Note that the structure itself is not freed.
213 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200214static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200215lysp_feature_free(struct lysf_ctx *ctx, struct lysp_feature *feat)
Radek Krejci19a96102018-11-15 13:38:09 +0100216{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200217 lydict_remove(ctx->ctx, feat->name);
218 FREE_ARRAY(ctx->ctx, feat->iffeatures, lysp_qname_free);
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100219 FREE_ARRAY(ctx, feat->iffeatures_c, lysc_iffeature_free);
220 LY_ARRAY_FREE(feat->depfeatures);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200221 lydict_remove(ctx->ctx, feat->dsc);
222 lydict_remove(ctx->ctx, feat->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100223 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
224}
225
Michal Vaskoc636ea42022-09-16 10:20:31 +0200226/**
227 * @brief Free the parsed identity structure.
228 *
229 * @param[in] ctx Free context.
230 * @param[in] ident Parsed schema identity structure to free. Note that the structure itself is not freed.
231 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200232static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200233lysp_ident_free(struct lysf_ctx *ctx, struct lysp_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100234{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200235 lydict_remove(ctx->ctx, ident->name);
236 FREE_ARRAY(ctx->ctx, ident->iffeatures, lysp_qname_free);
237 FREE_STRINGS(ctx->ctx, ident->bases);
238 lydict_remove(ctx->ctx, ident->dsc);
239 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100240 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
241}
242
Michal Vasko7f45cf22020-10-01 12:49:44 +0200243void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200244lysp_restr_free(struct lysf_ctx *ctx, struct lysp_restr *restr)
Radek Krejci19a96102018-11-15 13:38:09 +0100245{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200246 lydict_remove(ctx->ctx, restr->arg.str);
247 lydict_remove(ctx->ctx, restr->emsg);
248 lydict_remove(ctx->ctx, restr->eapptag);
249 lydict_remove(ctx->ctx, restr->dsc);
250 lydict_remove(ctx->ctx, restr->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100251 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
252}
253
Michal Vaskoc636ea42022-09-16 10:20:31 +0200254/**
255 * @brief Free the parsed type enum item.
256 *
257 * @param[in] ctx Free context.
258 * @param[in] item Parsed schema type enum item to free. Note that the structure itself is not freed.
259 */
Radek Krejci19a96102018-11-15 13:38:09 +0100260static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200261lysp_type_enum_free(struct lysf_ctx *ctx, struct lysp_type_enum *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100262{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200263 lydict_remove(ctx->ctx, item->name);
264 lydict_remove(ctx->ctx, item->dsc);
265 lydict_remove(ctx->ctx, item->ref);
266 FREE_ARRAY(ctx->ctx, item->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100267 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
268}
269
David Sedlák32488102019-07-15 17:44:10 +0200270void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200271lysp_type_free(struct lysf_ctx *ctx, struct lysp_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100272{
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200273 if (!type) {
274 return;
275 }
276
Michal Vaskoc636ea42022-09-16 10:20:31 +0200277 lydict_remove(ctx->ctx, type->name);
Radek Krejci19a96102018-11-15 13:38:09 +0100278 FREE_MEMBER(ctx, type->range, lysp_restr_free);
279 FREE_MEMBER(ctx, type->length, lysp_restr_free);
280 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
281 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
282 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200283 lyxp_expr_free(ctx->ctx, type->path);
284 FREE_STRINGS(ctx->ctx, type->bases);
Radek Krejci19a96102018-11-15 13:38:09 +0100285 FREE_ARRAY(ctx, type->types, lysp_type_free);
286 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
287 if (type->compiled) {
288 lysc_type_free(ctx, type->compiled);
289 }
290}
291
Michal Vaskoc636ea42022-09-16 10:20:31 +0200292/**
293 * @brief Free the parsed typedef structure.
294 *
295 * @param[in] ctx Free context.
296 * @param[in] tpdf Parsed schema typedef structure to free. Note that the structure itself is not freed.
297 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200298static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200299lysp_tpdf_free(struct lysf_ctx *ctx, struct lysp_tpdf *tpdf)
Radek Krejci19a96102018-11-15 13:38:09 +0100300{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200301 lydict_remove(ctx->ctx, tpdf->name);
302 lydict_remove(ctx->ctx, tpdf->units);
303 lydict_remove(ctx->ctx, tpdf->dflt.str);
304 lydict_remove(ctx->ctx, tpdf->dsc);
305 lydict_remove(ctx->ctx, tpdf->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100306 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
307
308 lysp_type_free(ctx, &tpdf->type);
309
310}
311
Michal Vaskoc636ea42022-09-16 10:20:31 +0200312/**
313 * @brief Free the parsed grouping structure.
314 *
315 * @param[in] ctx Free context.
316 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
317 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200318static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200319lysp_grp_free(struct lysf_ctx *ctx, struct lysp_node_grp *grp)
Radek Krejci19a96102018-11-15 13:38:09 +0100320{
321 struct lysp_node *node, *next;
322
Radek Krejci19a96102018-11-15 13:38:09 +0100323 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100324 LY_LIST_FOR_SAFE((struct lysp_node *)grp->groupings, next, node) {
325 lysp_node_free(ctx, node);
326 }
Radek Krejci01180ac2021-01-27 08:48:22 +0100327 LY_LIST_FOR_SAFE(grp->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100328 lysp_node_free(ctx, node);
329 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100330 LY_LIST_FOR_SAFE((struct lysp_node *)grp->actions, next, node) {
331 lysp_node_free(ctx, node);
332 }
333 LY_LIST_FOR_SAFE((struct lysp_node *)grp->notifs, next, node) {
334 lysp_node_free(ctx, node);
335 }
Radek Krejci19a96102018-11-15 13:38:09 +0100336}
337
Radek Krejcif09e4e82019-06-14 15:08:11 +0200338void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200339lysp_when_free(struct lysf_ctx *ctx, struct lysp_when *when)
Radek Krejci19a96102018-11-15 13:38:09 +0100340{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200341 lydict_remove(ctx->ctx, when->cond);
342 lydict_remove(ctx->ctx, when->dsc);
343 lydict_remove(ctx->ctx, when->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100344 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
345}
346
Michal Vaskoc636ea42022-09-16 10:20:31 +0200347/**
348 * @brief Free the parsed augment structure.
349 *
350 * @param[in] ctx Free context.
351 * @param[in] aug Parsed schema augment structure to free. Note that the structure itself is not freed.
352 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200353static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200354lysp_augment_free(struct lysf_ctx *ctx, struct lysp_node_augment *aug)
Radek Krejci19a96102018-11-15 13:38:09 +0100355{
356 struct lysp_node *node, *next;
357
Michal Vaskoc636ea42022-09-16 10:20:31 +0200358 LY_LIST_FOR_SAFE(aug->child, next, node) {
Radek Krejci19a96102018-11-15 13:38:09 +0100359 lysp_node_free(ctx, node);
360 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200361 LY_LIST_FOR_SAFE((struct lysp_node *)aug->actions, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100362 lysp_node_free(ctx, node);
363 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200364 LY_LIST_FOR_SAFE((struct lysp_node *)aug->notifs, next, node) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100365 lysp_node_free(ctx, node);
366 }
Radek Krejci19a96102018-11-15 13:38:09 +0100367}
368
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200369void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200370lysp_deviate_free(struct lysf_ctx *ctx, struct lysp_deviate *d)
Radek Krejci19a96102018-11-15 13:38:09 +0100371{
Michal Vasko22df3f02020-08-24 13:29:22 +0200372 struct lysp_deviate_add *add = (struct lysp_deviate_add *)d;
373 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl *)d;
Radek Krejci19a96102018-11-15 13:38:09 +0100374
Michal Vasko12ef5362022-09-16 15:13:58 +0200375 if (!d) {
376 return;
377 }
378
Radek Krejci19a96102018-11-15 13:38:09 +0100379 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
Michal Vaskod989ba02020-08-24 10:59:24 +0200380 switch (d->mod) {
Radek Krejci19a96102018-11-15 13:38:09 +0100381 case LYS_DEV_NOT_SUPPORTED:
382 /* nothing to do */
383 break;
384 case LYS_DEV_ADD:
385 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
Michal Vaskoc636ea42022-09-16 10:20:31 +0200386 lydict_remove(ctx->ctx, add->units);
Radek Krejci19a96102018-11-15 13:38:09 +0100387 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200388 FREE_ARRAY(ctx->ctx, add->uniques, lysp_qname_free);
389 FREE_ARRAY(ctx->ctx, add->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100390 break;
391 case LYS_DEV_REPLACE:
392 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200393 lydict_remove(ctx->ctx, rpl->units);
394 lysp_qname_free(ctx->ctx, &rpl->dflt);
Radek Krejci19a96102018-11-15 13:38:09 +0100395 break;
396 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200397 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100398 break;
399 }
400}
401
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200402void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200403lysp_deviation_free(struct lysf_ctx *ctx, struct lysp_deviation *dev)
Radek Krejci19a96102018-11-15 13:38:09 +0100404{
405 struct lysp_deviate *next, *iter;
406
Michal Vaskoc636ea42022-09-16 10:20:31 +0200407 lydict_remove(ctx->ctx, dev->nodeid);
408 lydict_remove(ctx->ctx, dev->dsc);
409 lydict_remove(ctx->ctx, dev->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100410 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
411 lysp_deviate_free(ctx, iter);
412 free(iter);
413 }
414 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
415}
416
Michal Vaskoc636ea42022-09-16 10:20:31 +0200417/**
418 * @brief Free the parsed refine structure.
419 *
420 * @param[in] ctx Free context.
421 * @param[in] ref Parsed schema refine structure to free. Note that the structure itself is not freed.
422 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200423static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200424lysp_refine_free(struct lysf_ctx *ctx, struct lysp_refine *ref)
Radek Krejci19a96102018-11-15 13:38:09 +0100425{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200426 lydict_remove(ctx->ctx, ref->nodeid);
427 lydict_remove(ctx->ctx, ref->dsc);
428 lydict_remove(ctx->ctx, ref->ref);
429 FREE_ARRAY(ctx->ctx, ref->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100430 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200431 lydict_remove(ctx->ctx, ref->presence);
432 FREE_ARRAY(ctx->ctx, ref->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100433 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
434}
435
Radek Krejci2d7a47b2019-05-16 13:34:10 +0200436void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200437lysp_node_free(struct lysf_ctx *ctx, struct lysp_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +0100438{
439 struct lysp_node *child, *next;
Michal Vasko856ea972021-06-09 09:44:30 +0200440 struct lysp_node_container *cont;
441 struct lysp_node_leaf *leaf;
442 struct lysp_node_leaflist *llist;
443 struct lysp_node_list *list;
444 struct lysp_node_choice *choice;
445 struct lysp_node_case *cas;
446 struct lysp_node_uses *uses;
447 struct lysp_node_action *act;
448 struct lysp_node_action_inout *inout;
449 struct lysp_node_notif *notif;
Radek Krejci9a3823e2021-01-27 20:26:46 +0100450 struct lysp_restr *musts = lysp_node_musts(node);
451 struct lysp_when *when = lysp_node_when(node);
Radek Krejci19a96102018-11-15 13:38:09 +0100452
Michal Vaskoc636ea42022-09-16 10:20:31 +0200453 lydict_remove(ctx->ctx, node->name);
454 lydict_remove(ctx->ctx, node->dsc);
455 lydict_remove(ctx->ctx, node->ref);
456 FREE_ARRAY(ctx->ctx, node->iffeatures, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100457 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
458
Radek Krejci9a3823e2021-01-27 20:26:46 +0100459 FREE_MEMBER(ctx, when, lysp_when_free);
460 FREE_ARRAY(ctx, musts, lysp_restr_free);
461
Michal Vaskod989ba02020-08-24 10:59:24 +0200462 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100463 case LYS_CONTAINER:
Michal Vasko856ea972021-06-09 09:44:30 +0200464 cont = (struct lysp_node_container *)node;
465
Michal Vaskoc636ea42022-09-16 10:20:31 +0200466 lydict_remove(ctx->ctx, cont->presence);
Michal Vasko856ea972021-06-09 09:44:30 +0200467 FREE_ARRAY(ctx, cont->typedefs, lysp_tpdf_free);
468 if (cont->groupings) {
469 LY_LIST_FOR_SAFE(&cont->groupings->node, next, child) {
470 lysp_node_free(ctx, child);
471 }
472 }
473 LY_LIST_FOR_SAFE(cont->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100474 lysp_node_free(ctx, child);
475 }
Michal Vasko856ea972021-06-09 09:44:30 +0200476 if (cont->actions) {
477 LY_LIST_FOR_SAFE(&cont->actions->node, next, child) {
478 lysp_node_free(ctx, child);
479 }
Radek Krejci19a96102018-11-15 13:38:09 +0100480 }
Michal Vasko856ea972021-06-09 09:44:30 +0200481 if (cont->notifs) {
482 LY_LIST_FOR_SAFE(&cont->notifs->node, next, child) {
483 lysp_node_free(ctx, child);
484 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100485 }
Radek Krejci19a96102018-11-15 13:38:09 +0100486 break;
487 case LYS_LEAF:
Michal Vasko856ea972021-06-09 09:44:30 +0200488 leaf = (struct lysp_node_leaf *)node;
489
490 lysp_type_free(ctx, &leaf->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200491 lydict_remove(ctx->ctx, leaf->units);
492 lydict_remove(ctx->ctx, leaf->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100493 break;
494 case LYS_LEAFLIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200495 llist = (struct lysp_node_leaflist *)node;
496
497 lysp_type_free(ctx, &llist->type);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200498 lydict_remove(ctx->ctx, llist->units);
499 FREE_ARRAY(ctx->ctx, llist->dflts, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100500 break;
501 case LYS_LIST:
Michal Vasko856ea972021-06-09 09:44:30 +0200502 list = (struct lysp_node_list *)node;
503
Michal Vaskoc636ea42022-09-16 10:20:31 +0200504 lydict_remove(ctx->ctx, list->key);
Michal Vasko856ea972021-06-09 09:44:30 +0200505 FREE_ARRAY(ctx, list->typedefs, lysp_tpdf_free);
506 if (list->groupings) {
507 LY_LIST_FOR_SAFE(&list->groupings->node, next, child) {
508 lysp_node_free(ctx, child);
509 }
510 }
511 LY_LIST_FOR_SAFE(list->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100512 lysp_node_free(ctx, child);
513 }
Michal Vasko856ea972021-06-09 09:44:30 +0200514 if (list->actions) {
515 LY_LIST_FOR_SAFE(&list->actions->node, next, child) {
516 lysp_node_free(ctx, child);
517 }
Radek Krejci19a96102018-11-15 13:38:09 +0100518 }
Michal Vasko856ea972021-06-09 09:44:30 +0200519 if (list->notifs) {
520 LY_LIST_FOR_SAFE(&list->notifs->node, next, child) {
521 lysp_node_free(ctx, child);
522 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100523 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200524 FREE_ARRAY(ctx->ctx, list->uniques, lysp_qname_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100525 break;
526 case LYS_CHOICE:
Michal Vasko856ea972021-06-09 09:44:30 +0200527 choice = (struct lysp_node_choice *)node;
528
529 LY_LIST_FOR_SAFE(choice->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100530 lysp_node_free(ctx, child);
531 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200532 lydict_remove(ctx->ctx, choice->dflt.str);
Radek Krejci19a96102018-11-15 13:38:09 +0100533 break;
534 case LYS_CASE:
Michal Vasko856ea972021-06-09 09:44:30 +0200535 cas = (struct lysp_node_case *)node;
536
537 LY_LIST_FOR_SAFE(cas->child, next, child) {
Radek Krejci19a96102018-11-15 13:38:09 +0100538 lysp_node_free(ctx, child);
539 }
540 break;
541 case LYS_ANYDATA:
542 case LYS_ANYXML:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100543 /* nothing special to do */
Radek Krejci19a96102018-11-15 13:38:09 +0100544 break;
545 case LYS_USES:
Michal Vasko856ea972021-06-09 09:44:30 +0200546 uses = (struct lysp_node_uses *)node;
547
548 FREE_ARRAY(ctx, uses->refines, lysp_refine_free);
549 if (uses->augments) {
550 LY_LIST_FOR_SAFE(&uses->augments->node, next, child) {
551 lysp_node_free(ctx, child);
552 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100553 }
554 break;
555 case LYS_RPC:
556 case LYS_ACTION:
Michal Vasko856ea972021-06-09 09:44:30 +0200557 act = (struct lysp_node_action *)node;
558
559 FREE_ARRAY(ctx, act->typedefs, lysp_tpdf_free);
560 if (act->groupings) {
561 LY_LIST_FOR_SAFE(&act->groupings->node, next, child) {
562 lysp_node_free(ctx, child);
563 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100564 }
Michal Vasko856ea972021-06-09 09:44:30 +0200565 if (act->input.nodetype) {
566 lysp_node_free(ctx, &act->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100567 }
Michal Vasko856ea972021-06-09 09:44:30 +0200568 if (act->output.nodetype) {
569 lysp_node_free(ctx, &act->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100570 }
571 break;
572 case LYS_INPUT:
573 case LYS_OUTPUT:
Michal Vasko856ea972021-06-09 09:44:30 +0200574 inout = (struct lysp_node_action_inout *)node;
575
576 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
577 if (inout->groupings) {
578 LY_LIST_FOR_SAFE(&inout->groupings->node, next, child) {
579 lysp_node_free(ctx, child);
580 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100581 }
Michal Vasko856ea972021-06-09 09:44:30 +0200582 LY_LIST_FOR_SAFE(inout->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100583 lysp_node_free(ctx, child);
584 }
585 /* do not free the node, it is never standalone but part of the action node */
586 return;
587 case LYS_NOTIF:
Michal Vasko856ea972021-06-09 09:44:30 +0200588 notif = (struct lysp_node_notif *)node;
589
590 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
591 if (notif->groupings) {
592 LY_LIST_FOR_SAFE(&notif->groupings->node, next, child) {
593 lysp_node_free(ctx, child);
594 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100595 }
Michal Vasko856ea972021-06-09 09:44:30 +0200596 LY_LIST_FOR_SAFE(notif->child, next, child) {
Radek Krejci2a9fc652021-01-22 17:44:34 +0100597 lysp_node_free(ctx, child);
598 }
599 break;
600 case LYS_GROUPING:
601 lysp_grp_free(ctx, (struct lysp_node_grp *)node);
602 break;
603 case LYS_AUGMENT:
Radek Krejci9a3823e2021-01-27 20:26:46 +0100604 lysp_augment_free(ctx, ((struct lysp_node_augment *)node));
Radek Krejci19a96102018-11-15 13:38:09 +0100605 break;
606 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200607 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +0100608 }
609
610 free(node);
611}
612
Radek Krejci15f10ab2020-11-03 14:14:14 +0100613void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200614lysp_module_free(struct lysf_ctx *ctx, struct lysp_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +0100615{
Radek Krejci19a96102018-11-15 13:38:09 +0100616 struct lysp_node *node, *next;
617
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100618 if (!module) {
619 return;
620 }
Radek Krejci19a96102018-11-15 13:38:09 +0100621
622 FREE_ARRAY(ctx, module->imports, lysp_import_free);
Radek Krejci771928a2021-01-19 13:42:36 +0100623 FREE_ARRAY(ctx, module->includes, module->is_submod ? lysp_include_free_submodule : lysp_include_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100624
Radek Krejci19a96102018-11-15 13:38:09 +0100625 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
626 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
627 FREE_ARRAY(ctx, module->features, lysp_feature_free);
628 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
629 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100630 LY_LIST_FOR_SAFE((struct lysp_node *)module->groupings, next, node) {
631 lysp_node_free(ctx, node);
632 }
Radek Krejci19a96102018-11-15 13:38:09 +0100633 LY_LIST_FOR_SAFE(module->data, next, node) {
634 lysp_node_free(ctx, node);
635 }
Radek Krejci2a9fc652021-01-22 17:44:34 +0100636 LY_LIST_FOR_SAFE((struct lysp_node *)module->augments, next, node) {
637 lysp_node_free(ctx, node);
638 }
639 LY_LIST_FOR_SAFE((struct lysp_node *)module->rpcs, next, node) {
640 lysp_node_free(ctx, node);
641 }
642 LY_LIST_FOR_SAFE((struct lysp_node *)module->notifs, next, node) {
643 lysp_node_free(ctx, node);
644 }
Radek Krejci19a96102018-11-15 13:38:09 +0100645 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
646 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
647
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200648 if (module->is_submod) {
649 struct lysp_submodule *submod = (struct lysp_submodule *)module;
650
Michal Vaskoc636ea42022-09-16 10:20:31 +0200651 lydict_remove(ctx->ctx, submod->name);
652 lydict_remove(ctx->ctx, submod->filepath);
653 lydict_remove(ctx->ctx, submod->prefix);
654 lydict_remove(ctx->ctx, submod->org);
655 lydict_remove(ctx->ctx, submod->contact);
656 lydict_remove(ctx->ctx, submod->dsc);
657 lydict_remove(ctx->ctx, submod->ref);
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200658 }
659
Radek Krejci19a96102018-11-15 13:38:09 +0100660 free(module);
661}
662
Michal Vasko6f4cbb62020-02-28 11:15:47 +0100663void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200664lysc_ext_instance_free(struct lysf_ctx *ctx, struct lysc_ext_instance *ext)
Radek Krejci19a96102018-11-15 13:38:09 +0100665{
Michal Vasko193dacd2022-10-13 08:43:05 +0200666 if (ext->def && ext->def->plugin && ext->def->plugin->cfree) {
667 ext->def->plugin->cfree(ctx->ctx, ext);
Radek Krejci38d85362019-09-05 16:26:38 +0200668 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200669 lydict_remove(ctx->ctx, ext->argument);
Radek Krejci0935f412019-08-20 16:15:18 +0200670 FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
671}
672
673void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200674lysc_iffeature_free(struct lysf_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
Radek Krejci19a96102018-11-15 13:38:09 +0100675{
676 LY_ARRAY_FREE(iff->features);
677 free(iff->expr);
678}
679
Michal Vaskoc636ea42022-09-16 10:20:31 +0200680/**
681 * @brief Free the compiled when structure (decrease refcount) and NULL the provided pointer.
682 *
683 * @param[in] ctx Free context.
684 * @param[in] grp Parsed schema grouping structure to free. Note that the structure itself is not freed.
685 */
Radek Krejci19a96102018-11-15 13:38:09 +0100686static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200687lysc_when_free(struct lysf_ctx *ctx, struct lysc_when **w)
Radek Krejci58d171e2018-11-23 13:50:55 +0100688{
Radek Krejci00b874b2019-02-12 10:54:50 +0100689 if (--(*w)->refcount) {
690 return;
691 }
Michal Vaskoc636ea42022-09-16 10:20:31 +0200692 lyxp_expr_free(ctx->ctx, (*w)->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200693 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, (*w)->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200694 lydict_remove(ctx->ctx, (*w)->dsc);
695 lydict_remove(ctx->ctx, (*w)->ref);
Radek Krejci00b874b2019-02-12 10:54:50 +0100696 FREE_ARRAY(ctx, (*w)->exts, lysc_ext_instance_free);
697 free(*w);
Radek Krejci58d171e2018-11-23 13:50:55 +0100698}
699
Michal Vaskoc636ea42022-09-16 10:20:31 +0200700/**
701 * @brief Free the compiled must structure.
702 *
703 * @param[in] ctx Free context.
704 * @param[in,out] must Compiled must structure to be freed.
705 * Since the structure is typically part of the sized array, the structure itself is not freed.
706 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200707static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200708lysc_must_free(struct lysf_ctx *ctx, struct lysc_must *must)
Radek Krejci58d171e2018-11-23 13:50:55 +0100709{
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200710 if (!must) {
711 return;
712 }
713
Michal Vaskoc636ea42022-09-16 10:20:31 +0200714 lyxp_expr_free(ctx->ctx, must->cond);
Radek Krejci8df109d2021-04-23 12:19:08 +0200715 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, must->prefixes);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200716 lydict_remove(ctx->ctx, must->emsg);
717 lydict_remove(ctx->ctx, must->eapptag);
718 lydict_remove(ctx->ctx, must->dsc);
719 lydict_remove(ctx->ctx, must->ref);
Radek Krejci58d171e2018-11-23 13:50:55 +0100720 FREE_ARRAY(ctx, must->exts, lysc_ext_instance_free);
721}
722
Michal Vaskoc636ea42022-09-16 10:20:31 +0200723/**
724 * @brief Unlink the identity from all derived identity arrays.
725 *
726 * @param[in] ident Identity to unlink.
727 */
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100728static void
729lysc_ident_derived_unlink(const struct lysc_ident *ident)
730{
731 LY_ARRAY_COUNT_TYPE u, v, w;
732 const struct lysp_submodule *submod;
Michal Vaskod84b8132022-03-15 10:45:44 +0100733 const struct lysp_module *base_pmod = NULL;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100734 const struct lysp_ident *identp = NULL;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100735 const struct lys_module *mod, *iter;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100736 const char *base_name;
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100737 uint32_t i;
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100738
739 /* find the parsed identity */
740 LY_ARRAY_FOR(ident->module->parsed->identities, u) {
741 if (ident->module->parsed->identities[u].name == ident->name) {
742 identp = &ident->module->parsed->identities[u];
743 base_pmod = ident->module->parsed;
744 break;
745 }
746 }
747 if (!identp) {
748 LY_ARRAY_FOR(ident->module->parsed->includes, v) {
749 submod = ident->module->parsed->includes[v].submodule;
750 LY_ARRAY_FOR(submod->identities, u) {
751 if (submod->identities[u].name == ident->name) {
752 identp = &submod->identities[u];
753 base_pmod = (struct lysp_module *)submod;
754 break;
755 }
756 }
757 }
758 }
759 assert(identp);
760
761 /* remove link from all the foreign bases, it may not be there if identity compilation failed */
762 LY_ARRAY_FOR(identp->bases, u) {
763 base_name = strchr(identp->bases[u], ':');
764 if (!base_name) {
765 continue;
766 }
767
768 /* prefixed identity */
769 mod = ly_resolve_prefix(ident->module->ctx, identp->bases[u], base_name - identp->bases[u], LY_VALUE_SCHEMA,
770 (void *)base_pmod);
771 if (!mod) {
772 continue;
773 }
774 ++base_name;
775
Michal Vaskod6b5d4e2022-03-16 09:23:32 +0100776 i = 0;
777 while ((iter = ly_ctx_get_module_iter(ident->module->ctx, &i))) {
778 if (iter == mod) {
779 break;
780 }
781 }
782 if (!iter) {
783 /* target module was freed already */
784 continue;
785 }
786
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100787 /* find the compiled base */
788 LY_ARRAY_FOR(mod->identities, v) {
789 if (!strcmp(mod->identities[v].name, base_name)) {
790 /* find the derived link */
791 LY_ARRAY_FOR(mod->identities[v].derived, w) {
792 if (mod->identities[v].derived[w] == ident) {
793 /* remove the link */
794 LY_ARRAY_DECREMENT(mod->identities[v].derived);
Michal Vasko3fedda12022-03-16 09:23:45 +0100795 if (!LY_ARRAY_COUNT(mod->identities[v].derived)) {
796 LY_ARRAY_FREE(mod->identities[v].derived);
797 mod->identities[v].derived = NULL;
798 } else if (w < LY_ARRAY_COUNT(mod->identities[v].derived)) {
Michal Vasko4f9da5e2022-03-14 13:11:26 +0100799 memmove(mod->identities[v].derived + w, mod->identities[v].derived + w + 1,
800 (LY_ARRAY_COUNT(mod->identities[v].derived) - w) * sizeof ident);
801 }
802 break;
803 }
804 }
805 break;
806 }
807 }
808 }
809}
810
Michal Vaskoc636ea42022-09-16 10:20:31 +0200811/**
812 * @brief Free the compiled identity structure.
813 *
814 * @param[in] ctx Free context.
815 * @param[in,out] ident Compiled identity structure to be freed.
816 * Since the structure is typically part of the sized array, the structure itself is not freed.
817 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200818static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200819lysc_ident_free(struct lysf_ctx *ctx, struct lysc_ident *ident)
Radek Krejci19a96102018-11-15 13:38:09 +0100820{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200821 lydict_remove(ctx->ctx, ident->name);
822 lydict_remove(ctx->ctx, ident->dsc);
823 lydict_remove(ctx->ctx, ident->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100824 LY_ARRAY_FREE(ident->derived);
825 FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
826}
827
Michal Vaskoc636ea42022-09-16 10:20:31 +0200828/**
829 * @brief Free the compiled range structure.
830 *
831 * @param[in] ctx Free context.
832 * @param[in,out] range Compiled range structure to be freed.
833 * Since the structure is typically part of the sized array, the structure itself is not freed.
834 */
Radek Krejci19a96102018-11-15 13:38:09 +0100835static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200836lysc_range_free(struct lysf_ctx *ctx, struct lysc_range *range)
Radek Krejci19a96102018-11-15 13:38:09 +0100837{
838 LY_ARRAY_FREE(range->parts);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200839 lydict_remove(ctx->ctx, range->eapptag);
840 lydict_remove(ctx->ctx, range->emsg);
841 lydict_remove(ctx->ctx, range->dsc);
842 lydict_remove(ctx->ctx, range->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100843 FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
844}
845
Michal Vasko51de7b72022-04-29 09:50:22 +0200846void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200847lysc_pattern_free(struct lysf_ctx *ctx, struct lysc_pattern **pattern)
Radek Krejci19a96102018-11-15 13:38:09 +0100848{
849 if (--(*pattern)->refcount) {
850 return;
851 }
Radek Krejci54579462019-04-30 12:47:06 +0200852 pcre2_code_free((*pattern)->code);
Michal Vaskoc636ea42022-09-16 10:20:31 +0200853 lydict_remove(ctx->ctx, (*pattern)->expr);
854 lydict_remove(ctx->ctx, (*pattern)->eapptag);
855 lydict_remove(ctx->ctx, (*pattern)->emsg);
856 lydict_remove(ctx->ctx, (*pattern)->dsc);
857 lydict_remove(ctx->ctx, (*pattern)->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100858 FREE_ARRAY(ctx, (*pattern)->exts, lysc_ext_instance_free);
859 free(*pattern);
860}
861
Michal Vaskof4fa90d2021-11-11 15:05:19 +0100862void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200863lysc_enum_item_free(struct lysf_ctx *ctx, struct lysc_type_bitenum_item *item)
Radek Krejci19a96102018-11-15 13:38:09 +0100864{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200865 lydict_remove(ctx->ctx, item->name);
866 lydict_remove(ctx->ctx, item->dsc);
867 lydict_remove(ctx->ctx, item->ref);
Radek Krejci19a96102018-11-15 13:38:09 +0100868 FREE_ARRAY(ctx, item->exts, lysc_ext_instance_free);
869}
870
Michal Vaskoc636ea42022-09-16 10:20:31 +0200871/**
872 * @brief Free the compiled type structure.
873 *
874 * @param[in] ctx Free context.
875 * @param[in,out] type Pointer to compiled type structure to be freed.
876 * Since the structure is typically part of the sized array, the structure itself is not freed.
877 */
Radek Krejcia3045382018-11-22 14:30:31 +0100878static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200879lysc_type2_free(struct lysf_ctx *ctx, struct lysc_type **type)
Radek Krejcia3045382018-11-22 14:30:31 +0100880{
881 lysc_type_free(ctx, *type);
882}
Radek Krejci0f969882020-08-21 16:56:47 +0200883
Radek Krejcicdfecd92018-11-26 11:27:32 +0100884void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200885lysc_type_free(struct lysf_ctx *ctx, struct lysc_type *type)
Radek Krejci19a96102018-11-15 13:38:09 +0100886{
Michal Vaskod15c7de2022-05-09 15:34:09 +0200887 if (!type || (LY_ATOMIC_DEC_BARRIER(type->refcount) > 1)) {
Radek Krejci19a96102018-11-15 13:38:09 +0100888 return;
889 }
Radek Krejcib915ac92020-08-14 23:31:04 +0200890
Michal Vaskod989ba02020-08-24 10:59:24 +0200891 switch (type->basetype) {
Radek Krejci19a96102018-11-15 13:38:09 +0100892 case LY_TYPE_BINARY:
Michal Vasko22df3f02020-08-24 13:29:22 +0200893 FREE_MEMBER(ctx, ((struct lysc_type_bin *)type)->length, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100894 break;
895 case LY_TYPE_BITS:
Michal Vasko22df3f02020-08-24 13:29:22 +0200896 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 +0100897 break;
Radek Krejci6cba4292018-11-15 17:33:29 +0100898 case LY_TYPE_DEC64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200899 FREE_MEMBER(ctx, ((struct lysc_type_dec *)type)->range, lysc_range_free);
Radek Krejci6cba4292018-11-15 17:33:29 +0100900 break;
Radek Krejci19a96102018-11-15 13:38:09 +0100901 case LY_TYPE_STRING:
Michal Vasko22df3f02020-08-24 13:29:22 +0200902 FREE_MEMBER(ctx, ((struct lysc_type_str *)type)->length, lysc_range_free);
903 FREE_ARRAY(ctx, ((struct lysc_type_str *)type)->patterns, lysc_pattern_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100904 break;
905 case LY_TYPE_ENUM:
Michal Vasko22df3f02020-08-24 13:29:22 +0200906 FREE_ARRAY(ctx, ((struct lysc_type_enum *)type)->enums, lysc_enum_item_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100907 break;
908 case LY_TYPE_INT8:
909 case LY_TYPE_UINT8:
910 case LY_TYPE_INT16:
911 case LY_TYPE_UINT16:
912 case LY_TYPE_INT32:
913 case LY_TYPE_UINT32:
914 case LY_TYPE_INT64:
915 case LY_TYPE_UINT64:
Michal Vasko22df3f02020-08-24 13:29:22 +0200916 FREE_MEMBER(ctx, ((struct lysc_type_num *)type)->range, lysc_range_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100917 break;
Radek Krejci555cb5b2018-11-16 14:54:33 +0100918 case LY_TYPE_IDENT:
Michal Vasko22df3f02020-08-24 13:29:22 +0200919 LY_ARRAY_FREE(((struct lysc_type_identityref *)type)->bases);
Radek Krejci555cb5b2018-11-16 14:54:33 +0100920 break;
Radek Krejcia3045382018-11-22 14:30:31 +0100921 case LY_TYPE_UNION:
Michal Vasko22df3f02020-08-24 13:29:22 +0200922 FREE_ARRAY(ctx, ((struct lysc_type_union *)type)->types, lysc_type2_free);
Radek Krejcia3045382018-11-22 14:30:31 +0100923 break;
924 case LY_TYPE_LEAFREF:
Michal Vaskoc636ea42022-09-16 10:20:31 +0200925 lyxp_expr_free(ctx->ctx, ((struct lysc_type_leafref *)type)->path);
Radek Krejci8df109d2021-04-23 12:19:08 +0200926 ly_free_prefix_data(LY_VALUE_SCHEMA_RESOLVED, ((struct lysc_type_leafref *)type)->prefixes);
Michal Vaskod15c7de2022-05-09 15:34:09 +0200927 lysc_type_free(ctx, ((struct lysc_type_leafref *)type)->realtype);
Radek Krejcia3045382018-11-22 14:30:31 +0100928 break;
Radek Krejci16c0f822018-11-16 10:46:10 +0100929 case LY_TYPE_INST:
Radek Krejci19a96102018-11-15 13:38:09 +0100930 case LY_TYPE_BOOL:
931 case LY_TYPE_EMPTY:
Radek Krejci43699232018-11-23 14:59:46 +0100932 case LY_TYPE_UNKNOWN:
Radek Krejci19a96102018-11-15 13:38:09 +0100933 /* nothing to do */
934 break;
935 }
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200936
Michal Vaskof309c482024-01-22 12:07:00 +0100937 lydict_remove(ctx->ctx, type->name);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200938 FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
Radek Krejci19a96102018-11-15 13:38:09 +0100939 free(type);
940}
941
Michal Vaskoc636ea42022-09-16 10:20:31 +0200942/**
943 * @brief Free the compiled input/output structure.
944 *
945 * @param[in] ctx Free context.
946 * @param[in,out] inout Compiled inout structure to be freed.
947 * Since the structure is part of the RPC/action structure, it is not freed itself.
948 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200949static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200950lysc_node_action_inout_free(struct lysf_ctx *ctx, struct lysc_node_action_inout *inout)
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100951{
952 struct lysc_node *child, *child_next;
953
Radek Krejcif538ce52019-03-05 10:46:14 +0100954 FREE_ARRAY(ctx, inout->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100955 LY_LIST_FOR_SAFE(inout->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100956 lysc_node_free_(ctx, child);
Radek Krejcif538ce52019-03-05 10:46:14 +0100957 }
958}
959
Michal Vaskoc636ea42022-09-16 10:20:31 +0200960/**
961 * @brief Free the compiled RPC/action structure.
962 *
963 * @param[in] ctx Free context.
964 * @param[in,out] action Compiled RPC/action structure to be freed.
965 * Since the structure is typically part of the sized array, the structure itself is not freed.
966 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200967static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200968lysc_node_action_free(struct lysf_ctx *ctx, struct lysc_node_action *action)
Radek Krejcif538ce52019-03-05 10:46:14 +0100969{
Michal Vasko37a0fe62021-02-03 09:53:04 +0100970 FREE_ARRAY(ctx, action->when, lysc_when_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100971 if (action->input.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100972 lysc_node_free_(ctx, &action->input.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100973 }
974 if (action->output.nodetype) {
Michal Vasko14ed9cd2021-01-28 14:16:25 +0100975 lysc_node_free_(ctx, &action->output.node);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100976 }
Radek Krejci6eeb58f2019-02-22 16:29:37 +0100977}
978
Michal Vaskoc636ea42022-09-16 10:20:31 +0200979/**
980 * @brief Free the compiled notification structure.
981 *
982 * @param[in] ctx Free context.
983 * @param[in,out] notif Compiled notification structure to be freed.
984 * Since the structure is typically part of the sized array, the structure itself is not freed.
985 */
Michal Vasko12ef5362022-09-16 15:13:58 +0200986static void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200987lysc_node_notif_free(struct lysf_ctx *ctx, struct lysc_node_notif *notif)
Radek Krejcifc11bd72019-04-11 16:00:05 +0200988{
989 struct lysc_node *child, *child_next;
990
Michal Vasko37a0fe62021-02-03 09:53:04 +0100991 FREE_ARRAY(ctx, notif->when, lysc_when_free);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200992 FREE_ARRAY(ctx, notif->musts, lysc_must_free);
Radek Krejci01180ac2021-01-27 08:48:22 +0100993 LY_LIST_FOR_SAFE(notif->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100994 lysc_node_free_(ctx, child);
Radek Krejcifc11bd72019-04-11 16:00:05 +0200995 }
996}
997
Radek Krejcif2de0ed2019-05-02 14:13:18 +0200998void
Michal Vaskoc636ea42022-09-16 10:20:31 +0200999lysc_node_container_free(struct lysf_ctx *ctx, struct lysc_node_container *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001000{
1001 struct lysc_node *child, *child_next;
1002
1003 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001004 lysc_node_free_(ctx, child);
Radek Krejci19a96102018-11-15 13:38:09 +01001005 }
Radek Krejci2a9fc652021-01-22 17:44:34 +01001006 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
1007 lysc_node_free_(ctx, child);
1008 }
1009 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1010 lysc_node_free_(ctx, child);
1011 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001012 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001013 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001014}
1015
Michal Vaskoc636ea42022-09-16 10:20:31 +02001016/**
1017 * @brief Free the compiled leaf structure.
1018 *
1019 * @param[in] ctx Free context.
1020 * @param[in,out] node Compiled leaf structure to be freed.
1021 * Since the structure is typically part of the sized array, the structure itself is not freed.
1022 */
Radek Krejci19a96102018-11-15 13:38:09 +01001023static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001024lysc_node_leaf_free(struct lysf_ctx *ctx, struct lysc_node_leaf *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001025{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001026 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci58d171e2018-11-23 13:50:55 +01001027 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci19a96102018-11-15 13:38:09 +01001028 if (node->type) {
1029 lysc_type_free(ctx, node->type);
1030 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001031 lydict_remove(ctx->ctx, node->units);
Radek Krejcia1911222019-07-22 17:24:50 +02001032 if (node->dflt) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001033 node->dflt->realtype->plugin->free(ctx->ctx, node->dflt);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001034 lysc_type_free(ctx, (struct lysc_type *)node->dflt->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001035 free(node->dflt);
1036 }
Radek Krejci19a96102018-11-15 13:38:09 +01001037}
1038
Michal Vaskoc636ea42022-09-16 10:20:31 +02001039/**
1040 * @brief Free the compiled leaflist structure.
1041 *
1042 * @param[in] ctx Free context.
1043 * @param[in,out] node Compiled leaflist structure to be freed.
1044 * Since the structure is typically part of the sized array, the structure itself is not freed.
1045 */
Radek Krejci42452ac2018-11-28 17:09:52 +01001046static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001047lysc_node_leaflist_free(struct lysf_ctx *ctx, struct lysc_node_leaflist *node)
Radek Krejci42452ac2018-11-28 17:09:52 +01001048{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001049 LY_ARRAY_COUNT_TYPE u;
Radek Krejci42452ac2018-11-28 17:09:52 +01001050
Radek Krejci9a3823e2021-01-27 20:26:46 +01001051 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci42452ac2018-11-28 17:09:52 +01001052 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1053 if (node->type) {
1054 lysc_type_free(ctx, node->type);
1055 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001056 lydict_remove(ctx->ctx, node->units);
Radek Krejci42452ac2018-11-28 17:09:52 +01001057 LY_ARRAY_FOR(node->dflts, u) {
Michal Vaskoc636ea42022-09-16 10:20:31 +02001058 node->dflts[u]->realtype->plugin->free(ctx->ctx, node->dflts[u]);
Michal Vaskofeca4fb2020-10-05 08:58:40 +02001059 lysc_type_free(ctx, (struct lysc_type *)node->dflts[u]->realtype);
Radek Krejcia1911222019-07-22 17:24:50 +02001060 free(node->dflts[u]);
Radek Krejci42452ac2018-11-28 17:09:52 +01001061 }
1062 LY_ARRAY_FREE(node->dflts);
1063}
1064
Michal Vaskoc636ea42022-09-16 10:20:31 +02001065/**
1066 * @brief Free the compiled list structure.
1067 *
1068 * @param[in] ctx Free context.
1069 * @param[in,out] node Compiled list structure to be freed.
1070 * Since the structure is typically part of the sized array, the structure itself is not freed.
1071 */
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001072static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001073lysc_node_list_free(struct lysf_ctx *ctx, struct lysc_node_list *node)
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001074{
Michal Vaskofd69e1d2020-07-03 11:57:17 +02001075 LY_ARRAY_COUNT_TYPE u;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001076 struct lysc_node *child, *child_next;
1077
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001078 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001079 lysc_node_free_(ctx, child);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001080 }
Radek Krejci9a3823e2021-01-27 20:26:46 +01001081 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001082 FREE_ARRAY(ctx, node->musts, lysc_must_free);
1083
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001084 LY_ARRAY_FOR(node->uniques, u) {
1085 LY_ARRAY_FREE(node->uniques[u]);
1086 }
1087 LY_ARRAY_FREE(node->uniques);
1088
Radek Krejci2a9fc652021-01-22 17:44:34 +01001089 LY_LIST_FOR_SAFE((struct lysc_node *)node->actions, child_next, child) {
1090 lysc_node_free_(ctx, child);
1091 }
1092 LY_LIST_FOR_SAFE((struct lysc_node *)node->notifs, child_next, child) {
1093 lysc_node_free_(ctx, child);
1094 }
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001095}
1096
Michal Vaskoc636ea42022-09-16 10:20:31 +02001097/**
1098 * @brief Free the compiled choice structure.
1099 *
1100 * @param[in] ctx Free context.
1101 * @param[in,out] node Compiled choice structure to be freed.
1102 * Since the structure is typically part of the sized array, the structure itself is not freed.
1103 */
Radek Krejci056d0a82018-12-06 16:57:25 +01001104static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001105lysc_node_choice_free(struct lysf_ctx *ctx, struct lysc_node_choice *node)
Radek Krejci056d0a82018-12-06 16:57:25 +01001106{
1107 struct lysc_node *child, *child_next;
1108
Radek Krejci9a3823e2021-01-27 20:26:46 +01001109 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001110 LY_LIST_FOR_SAFE((struct lysc_node *)node->cases, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001111 lysc_node_free_(ctx, child);
Michal Vasko20424b42020-08-31 12:29:38 +02001112 }
1113}
1114
Michal Vaskoc636ea42022-09-16 10:20:31 +02001115/**
1116 * @brief Free the compiled case structure.
1117 *
1118 * @param[in] ctx Free context.
1119 * @param[in,out] node Compiled case structure to be freed.
1120 * Since the structure is typically part of the sized array, the structure itself is not freed.
1121 */
Michal Vasko20424b42020-08-31 12:29:38 +02001122static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001123lysc_node_case_free(struct lysf_ctx *ctx, struct lysc_node_case *node)
Michal Vasko20424b42020-08-31 12:29:38 +02001124{
1125 struct lysc_node *child, *child_next;
1126
Radek Krejci9a3823e2021-01-27 20:26:46 +01001127 FREE_ARRAY(ctx, node->when, lysc_when_free);
Michal Vasko20424b42020-08-31 12:29:38 +02001128 LY_LIST_FOR_SAFE(node->child, child_next, child) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001129 lysc_node_free_(ctx, child);
Radek Krejci056d0a82018-12-06 16:57:25 +01001130 }
Radek Krejci9800fb82018-12-13 14:26:23 +01001131}
Radek Krejci056d0a82018-12-06 16:57:25 +01001132
Michal Vaskoc636ea42022-09-16 10:20:31 +02001133/**
1134 * @brief Free the compiled anyxml/anydata structure.
1135 *
1136 * @param[in] ctx Free context.
1137 * @param[in,out] node Compiled anyxml/anydata structure to be freed.
1138 * Since the structure is typically part of the sized array, the structure itself is not freed.
1139 */
Radek Krejci9800fb82018-12-13 14:26:23 +01001140static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001141lysc_node_anydata_free(struct lysf_ctx *ctx, struct lysc_node_anydata *node)
Radek Krejci9800fb82018-12-13 14:26:23 +01001142{
Radek Krejci9a3823e2021-01-27 20:26:46 +01001143 FREE_ARRAY(ctx, node->when, lysc_when_free);
Radek Krejci9800fb82018-12-13 14:26:23 +01001144 FREE_ARRAY(ctx, node->musts, lysc_must_free);
Radek Krejci056d0a82018-12-06 16:57:25 +01001145}
1146
Michal Vaskoc636ea42022-09-16 10:20:31 +02001147/**
1148 * @brief Free the compiled node structure.
1149 *
1150 * @param[in] ctx Free context.
1151 * @param[in,out] node Compiled node structure to be freed.
1152 * Since the structure is typically part of the sized array, the structure itself is not freed.
1153 */
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001154static void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001155lysc_node_free_(struct lysf_ctx *ctx, struct lysc_node *node)
Radek Krejci19a96102018-11-15 13:38:09 +01001156{
Radek Krejci2a9fc652021-01-22 17:44:34 +01001157 ly_bool inout = 0;
1158
Radek Krejci19a96102018-11-15 13:38:09 +01001159 /* common part */
Michal Vaskoc636ea42022-09-16 10:20:31 +02001160 lydict_remove(ctx->ctx, node->name);
1161 lydict_remove(ctx->ctx, node->dsc);
1162 lydict_remove(ctx->ctx, node->ref);
Radek Krejci19a96102018-11-15 13:38:09 +01001163
1164 /* nodetype-specific part */
Michal Vaskod989ba02020-08-24 10:59:24 +02001165 switch (node->nodetype) {
Radek Krejci19a96102018-11-15 13:38:09 +01001166 case LYS_CONTAINER:
Michal Vasko22df3f02020-08-24 13:29:22 +02001167 lysc_node_container_free(ctx, (struct lysc_node_container *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001168 break;
1169 case LYS_LEAF:
Michal Vasko22df3f02020-08-24 13:29:22 +02001170 lysc_node_leaf_free(ctx, (struct lysc_node_leaf *)node);
Radek Krejci19a96102018-11-15 13:38:09 +01001171 break;
Radek Krejci42452ac2018-11-28 17:09:52 +01001172 case LYS_LEAFLIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001173 lysc_node_leaflist_free(ctx, (struct lysc_node_leaflist *)node);
Radek Krejci42452ac2018-11-28 17:09:52 +01001174 break;
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001175 case LYS_LIST:
Michal Vasko22df3f02020-08-24 13:29:22 +02001176 lysc_node_list_free(ctx, (struct lysc_node_list *)node);
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001177 break;
Radek Krejci056d0a82018-12-06 16:57:25 +01001178 case LYS_CHOICE:
Michal Vasko22df3f02020-08-24 13:29:22 +02001179 lysc_node_choice_free(ctx, (struct lysc_node_choice *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001180 break;
1181 case LYS_CASE:
Michal Vasko20424b42020-08-31 12:29:38 +02001182 lysc_node_case_free(ctx, (struct lysc_node_case *)node);
Radek Krejci056d0a82018-12-06 16:57:25 +01001183 break;
Radek Krejci9800fb82018-12-13 14:26:23 +01001184 case LYS_ANYDATA:
1185 case LYS_ANYXML:
Michal Vasko22df3f02020-08-24 13:29:22 +02001186 lysc_node_anydata_free(ctx, (struct lysc_node_anydata *)node);
Radek Krejci9800fb82018-12-13 14:26:23 +01001187 break;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001188 case LYS_RPC:
1189 case LYS_ACTION:
1190 lysc_node_action_free(ctx, (struct lysc_node_action *)node);
1191 break;
1192 case LYS_INPUT:
1193 case LYS_OUTPUT:
1194 lysc_node_action_inout_free(ctx, (struct lysc_node_action_inout *)node);
1195 inout = 1;
1196 break;
1197 case LYS_NOTIF:
1198 lysc_node_notif_free(ctx, (struct lysc_node_notif *)node);
1199 break;
Radek Krejci19a96102018-11-15 13:38:09 +01001200 default:
Michal Vaskoc636ea42022-09-16 10:20:31 +02001201 LOGINT(ctx->ctx);
Radek Krejci19a96102018-11-15 13:38:09 +01001202 }
1203
Radek Krejci056d0a82018-12-06 16:57:25 +01001204 FREE_ARRAY(ctx, node->exts, lysc_ext_instance_free);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001205
1206 if (!inout) {
1207 free(node);
1208 }
Radek Krejci19a96102018-11-15 13:38:09 +01001209}
1210
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001211void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001212lysc_node_free(struct lysf_ctx *ctx, struct lysc_node *node, ly_bool unlink)
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001213{
Michal Vaskoe02e7402021-07-23 08:29:28 +02001214 struct lysc_node *next, *iter, **child_p;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001215
Radek Krejci2a9fc652021-01-22 17:44:34 +01001216 if (node->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
Michal Vaskoe02e7402021-07-23 08:29:28 +02001217 /* inouts are part of actions and cannot be unlinked/freed separately, we can only free all the children */
1218 struct lysc_node_action_inout *inout = (struct lysc_node_action_inout *)node;
Michal Vasko26bbb272022-08-02 14:54:33 +02001219
Michal Vaskoe02e7402021-07-23 08:29:28 +02001220 LY_LIST_FOR_SAFE(inout->child, next, iter) {
1221 lysc_node_free_(ctx, iter);
1222 }
1223 inout->child = NULL;
Radek Krejci2a9fc652021-01-22 17:44:34 +01001224 return;
1225 }
1226
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001227 if (unlink) {
1228 /* unlink from siblings */
1229 if (node->prev->next) {
1230 node->prev->next = node->next;
1231 }
1232 if (node->next) {
1233 node->next->prev = node->prev;
1234 } else {
1235 /* unlinking the last node */
1236 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001237 if (node->nodetype == LYS_ACTION) {
1238 iter = (struct lysc_node *)lysc_node_actions(node->parent);
1239 } else if (node->nodetype == LYS_NOTIF) {
1240 iter = (struct lysc_node *)lysc_node_notifs(node->parent);
1241 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001242 iter = (struct lysc_node *)lysc_node_child(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001243 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001244 LY_CHECK_ERR_RET(!iter, LOGINT(ctx->ctx), );
Radek Krejci2a9fc652021-01-22 17:44:34 +01001245 } else if (node->nodetype == LYS_RPC) {
1246 iter = (struct lysc_node *)node->module->compiled->rpcs;
1247 } else if (node->nodetype == LYS_NOTIF) {
1248 iter = (struct lysc_node *)node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001249 } else {
1250 iter = node->module->compiled->data;
1251 }
1252 /* update the "last" pointer from the first node */
1253 iter->prev = node->prev;
1254 }
1255
1256 /* unlink from parent */
1257 if (node->parent) {
Radek Krejci2a9fc652021-01-22 17:44:34 +01001258 if (node->nodetype == LYS_ACTION) {
1259 child_p = (struct lysc_node **)lysc_node_actions_p(node->parent);
1260 } else if (node->nodetype == LYS_NOTIF) {
1261 child_p = (struct lysc_node **)lysc_node_notifs_p(node->parent);
1262 } else {
Michal Vasko544e58a2021-01-28 14:33:41 +01001263 child_p = lysc_node_child_p(node->parent);
Radek Krejci2a9fc652021-01-22 17:44:34 +01001264 }
1265 } else if (node->nodetype == LYS_RPC) {
1266 child_p = (struct lysc_node **)&node->module->compiled->rpcs;
1267 } else if (node->nodetype == LYS_NOTIF) {
1268 child_p = (struct lysc_node **)&node->module->compiled->notifs;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001269 } else {
1270 child_p = &node->module->compiled->data;
1271 }
1272 if (child_p && (*child_p == node)) {
1273 /* the node is the first child */
1274 *child_p = node->next;
1275 }
1276 }
1277
1278 lysc_node_free_(ctx, node);
1279}
1280
Radek Krejci90ed21e2021-04-12 14:47:46 +02001281void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001282lysc_module_free(struct lysf_ctx *ctx, struct lysc_module *module)
Radek Krejci19a96102018-11-15 13:38:09 +01001283{
Radek Krejci19a96102018-11-15 13:38:09 +01001284 struct lysc_node *node, *node_next;
1285
Radek Krejci90ed21e2021-04-12 14:47:46 +02001286 if (!module) {
1287 return;
1288 }
1289
Radek Krejci19a96102018-11-15 13:38:09 +01001290 LY_LIST_FOR_SAFE(module->data, node_next, node) {
Michal Vasko7b1ad1a2020-11-02 15:41:27 +01001291 lysc_node_free_(ctx, node);
Radek Krejci19a96102018-11-15 13:38:09 +01001292 }
Radek Krejci2a9fc652021-01-22 17:44:34 +01001293 LY_LIST_FOR_SAFE((struct lysc_node *)module->rpcs, node_next, node) {
1294 lysc_node_free_(ctx, node);
1295 }
1296 LY_LIST_FOR_SAFE((struct lysc_node *)module->notifs, node_next, node) {
1297 lysc_node_free_(ctx, node);
1298 }
Radek Krejci19a96102018-11-15 13:38:09 +01001299 FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
1300
1301 free(module);
1302}
1303
1304void
Michal Vaskoc636ea42022-09-16 10:20:31 +02001305lys_module_free(struct lysf_ctx *ctx, struct lys_module *module, ly_bool remove_links)
Radek Krejci19a96102018-11-15 13:38:09 +01001306{
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001307 LY_ARRAY_COUNT_TYPE u;
1308
Radek Krejci19a96102018-11-15 13:38:09 +01001309 if (!module) {
1310 return;
1311 }
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001312
Michal Vaskoee757602021-06-10 14:38:19 +02001313 assert(!module->implemented);
1314 assert(!module->compiled);
Radek Krejci19a96102018-11-15 13:38:09 +01001315
Michal Vasko4f9da5e2022-03-14 13:11:26 +01001316 if (remove_links) {
1317 /* remove derived identity links */
1318 LY_ARRAY_FOR(module->identities, u) {
1319 lysc_ident_derived_unlink(&module->identities[u]);
1320 }
1321 }
Michal Vaskoc636ea42022-09-16 10:20:31 +02001322 FREE_ARRAY(ctx, module->identities, lysc_ident_free);
1323 lysp_module_free(ctx, module->parsed);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001324
Michal Vasko7f45cf22020-10-01 12:49:44 +02001325 LY_ARRAY_FREE(module->augmented_by);
1326 LY_ARRAY_FREE(module->deviated_by);
1327
Michal Vaskoc636ea42022-09-16 10:20:31 +02001328 lydict_remove(ctx->ctx, module->name);
1329 lydict_remove(ctx->ctx, module->revision);
1330 lydict_remove(ctx->ctx, module->ns);
1331 lydict_remove(ctx->ctx, module->prefix);
1332 lydict_remove(ctx->ctx, module->filepath);
1333 lydict_remove(ctx->ctx, module->org);
1334 lydict_remove(ctx->ctx, module->contact);
1335 lydict_remove(ctx->ctx, module->dsc);
1336 lydict_remove(ctx->ctx, module->ref);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001337
Radek Krejci19a96102018-11-15 13:38:09 +01001338 free(module);
1339}
Michal Vasko33ff9422020-07-03 09:50:39 +02001340
Michal Vaskoc636ea42022-09-16 10:20:31 +02001341void
1342lysf_ctx_erase(struct lysf_ctx *ctx)
1343{
1344 struct lysc_ext *ext;
1345 uint32_t i;
1346
1347 for (i = 0; i < ctx->ext_set.count; ++i) {
1348 ext = ctx->ext_set.objs[i];
1349
1350 lydict_remove(ctx->ctx, ext->name);
1351 lydict_remove(ctx->ctx, ext->argname);
1352 free(ext);
1353 }
1354 ly_set_erase(&ctx->ext_set, NULL);
1355}
1356
Jan Kundrátc53a7ec2021-12-09 16:01:19 +01001357LIBYANG_API_DEF void
Michal Vasko193dacd2022-10-13 08:43:05 +02001358lyplg_ext_pfree_instance_substatements(const struct ly_ctx *ctx, struct lysp_ext_substmt *substmts)
Radek Krejci38d85362019-09-05 16:26:38 +02001359{
Radek Krejci1b2eef82021-02-17 11:17:27 +01001360 LY_ARRAY_COUNT_TYPE u;
Michal Vasko193dacd2022-10-13 08:43:05 +02001361 struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
1362 ly_bool node_free;
Radek Krejci1b2eef82021-02-17 11:17:27 +01001363
1364 LY_ARRAY_FOR(substmts, u) {
Radek Krejci38d85362019-09-05 16:26:38 +02001365 if (!substmts[u].storage) {
1366 continue;
1367 }
1368
Michal Vaskod989ba02020-08-24 10:59:24 +02001369 switch (substmts[u].stmt) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001370 case LY_STMT_NOTIFICATION:
1371 case LY_STMT_INPUT:
1372 case LY_STMT_OUTPUT:
Radek Krejci6b88a462021-02-17 12:39:34 +01001373 case LY_STMT_ACTION:
Michal Vasko193dacd2022-10-13 08:43:05 +02001374 case LY_STMT_RPC:
Radek Krejci6b88a462021-02-17 12:39:34 +01001375 case LY_STMT_ANYDATA:
1376 case LY_STMT_ANYXML:
Michal Vasko193dacd2022-10-13 08:43:05 +02001377 case LY_STMT_AUGMENT:
1378 case LY_STMT_CASE:
Radek Krejci6b88a462021-02-17 12:39:34 +01001379 case LY_STMT_CHOICE:
Michal Vasko193dacd2022-10-13 08:43:05 +02001380 case LY_STMT_CONTAINER:
1381 case LY_STMT_GROUPING:
Radek Krejci6b88a462021-02-17 12:39:34 +01001382 case LY_STMT_LEAF:
1383 case LY_STMT_LEAF_LIST:
1384 case LY_STMT_LIST:
Michal Vasko193dacd2022-10-13 08:43:05 +02001385 case LY_STMT_USES: {
1386 struct lysp_node *child, *child_next;
Radek Krejci6b88a462021-02-17 12:39:34 +01001387
Michal Vasko53eb6a12024-06-13 11:38:47 +02001388 LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001389 node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
1390 lysp_node_free(&fctx, child);
1391 if (node_free) {
1392 free(child);
1393 }
Radek Krejci38d85362019-09-05 16:26:38 +02001394 }
Michal Vasko53eb6a12024-06-13 11:38:47 +02001395 *VOIDPTR2_C(substmts[u].storage) = NULL;
Radek Krejci38d85362019-09-05 16:26:38 +02001396 break;
Radek Krejci6b88a462021-02-17 12:39:34 +01001397 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001398 case LY_STMT_BASE:
1399 /* multiple strings */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001400 FREE_ARRAY(ctx, **(const char ***)VOIDPTR2_C(substmts[u].storage), lydict_remove);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001401 break;
Michal Vasko193dacd2022-10-13 08:43:05 +02001402
1403 case LY_STMT_BIT:
1404 case LY_STMT_ENUM:
1405 /* single enum */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001406 lysp_type_enum_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001407 break;
1408
1409 case LY_STMT_DEVIATE:
1410 /* single deviate */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001411 lysp_deviate_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001412 break;
1413
1414 case LY_STMT_DEVIATION:
1415 /* single deviation */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001416 lysp_deviation_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001417 break;
1418
1419 case LY_STMT_EXTENSION:
1420 /* single extension */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001421 lysp_ext_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001422 break;
1423
1424 case LY_STMT_EXTENSION_INSTANCE:
1425 /* multiple extension instances */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001426 FREE_ARRAY(&fctx, *(struct lysp_ext_instance **)VOIDPTR2_C(substmts[u].storage), lysp_ext_instance_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001427 break;
1428
1429 case LY_STMT_FEATURE:
1430 /* multiple features */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001431 FREE_ARRAY(&fctx, *(struct lysp_feature **)VOIDPTR2_C(substmts[u].storage), lysp_feature_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001432 break;
1433
1434 case LY_STMT_IDENTITY:
1435 /* multiple identities */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001436 FREE_ARRAY(&fctx, *(struct lysp_ident **)VOIDPTR2_C(substmts[u].storage), lysp_ident_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001437 break;
1438
1439 case LY_STMT_IMPORT:
1440 /* multiple imports */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001441 FREE_ARRAY(&fctx, *(struct lysp_import **)VOIDPTR2_C(substmts[u].storage), lysp_import_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001442 break;
1443
1444 case LY_STMT_INCLUDE:
1445 /* multiple includes */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001446 FREE_ARRAY(&fctx, *(struct lysp_include **)VOIDPTR2_C(substmts[u].storage), lysp_include_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001447 break;
1448
1449 case LY_STMT_REFINE:
1450 /* multiple refines */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001451 FREE_ARRAY(&fctx, *(struct lysp_refine **)VOIDPTR2_C(substmts[u].storage), lysp_refine_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001452 break;
1453
1454 case LY_STMT_REVISION:
1455 /* multiple revisions */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001456 FREE_ARRAY(&fctx, *(struct lysp_revision **)VOIDPTR2_C(substmts[u].storage), lysp_revision_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001457 break;
1458
Radek Krejci6b88a462021-02-17 12:39:34 +01001459 case LY_STMT_CONFIG:
Michal Vasko193dacd2022-10-13 08:43:05 +02001460 case LY_STMT_FRACTION_DIGITS:
1461 case LY_STMT_MANDATORY:
1462 case LY_STMT_MAX_ELEMENTS:
1463 case LY_STMT_MIN_ELEMENTS:
1464 case LY_STMT_ORDERED_BY:
1465 case LY_STMT_POSITION:
1466 case LY_STMT_REQUIRE_INSTANCE:
Radek Krejci6b88a462021-02-17 12:39:34 +01001467 case LY_STMT_STATUS:
Michal Vasko193dacd2022-10-13 08:43:05 +02001468 case LY_STMT_VALUE:
1469 case LY_STMT_YANG_VERSION:
1470 case LY_STMT_YIN_ELEMENT:
Radek Krejci6b88a462021-02-17 12:39:34 +01001471 /* nothing to do */
1472 break;
Michal Vasko193dacd2022-10-13 08:43:05 +02001473
1474 case LY_STMT_ARGUMENT:
1475 case LY_STMT_BELONGS_TO:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001476 case LY_STMT_CONTACT:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001477 case LY_STMT_DESCRIPTION:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001478 case LY_STMT_ERROR_APP_TAG:
1479 case LY_STMT_ERROR_MESSAGE:
1480 case LY_STMT_KEY:
Michal Vasko193dacd2022-10-13 08:43:05 +02001481 case LY_STMT_MODIFIER:
1482 case LY_STMT_NAMESPACE:
1483 case LY_STMT_ORGANIZATION:
1484 case LY_STMT_PREFIX:
1485 case LY_STMT_PRESENCE:
1486 case LY_STMT_REFERENCE:
1487 case LY_STMT_REVISION_DATE:
1488 case LY_STMT_UNITS:
1489 /* single string */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001490 lydict_remove(ctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001491 break;
1492
1493 case LY_STMT_LENGTH:
1494 case LY_STMT_MUST:
1495 case LY_STMT_PATTERN:
1496 case LY_STMT_RANGE:
1497 /* multiple restrictions */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001498 FREE_ARRAY(&fctx, *(struct lysp_restr **)VOIDPTR2_C(substmts[u].storage), lysp_restr_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001499 break;
1500
1501 case LY_STMT_WHEN:
1502 /* multiple whens */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001503 FREE_ARRAY(&fctx, *(struct lysp_when **)VOIDPTR2_C(substmts[u].storage), lysp_when_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001504 break;
1505
1506 case LY_STMT_PATH:
1507 /* single expression */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001508 lyxp_expr_free(ctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001509 break;
1510
1511 case LY_STMT_DEFAULT:
1512 case LY_STMT_IF_FEATURE:
1513 case LY_STMT_UNIQUE:
1514 /* multiple qnames */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001515 FREE_ARRAY(ctx, *(struct lysp_qname **)VOIDPTR2_C(substmts[u].storage), lysp_qname_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001516 break;
1517
1518 case LY_STMT_TYPEDEF:
1519 /* multiple typedefs */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001520 FREE_ARRAY(&fctx, *(struct lysp_tpdf **)VOIDPTR2_C(substmts[u].storage), lysp_tpdf_free);
Michal Vasko193dacd2022-10-13 08:43:05 +02001521 break;
1522
1523 case LY_STMT_TYPE: {
1524 /* single type */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001525 struct lysp_type **type_p = VOIDPTR_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001526
1527 lysp_type_free(&fctx, *type_p);
1528 free(*type_p);
1529 break;
1530 }
1531 case LY_STMT_MODULE:
1532 case LY_STMT_SUBMODULE:
1533 /* single (sub)module */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001534 lysp_module_free(&fctx, *VOIDPTR2_C(substmts[u].storage));
Michal Vasko193dacd2022-10-13 08:43:05 +02001535 break;
1536
1537 default:
1538 LOGINT(ctx);
1539 }
1540 }
1541
1542 LY_ARRAY_FREE(substmts);
1543}
1544
1545LIBYANG_API_DEF void
1546lyplg_ext_cfree_instance_substatements(const struct ly_ctx *ctx, struct lysc_ext_substmt *substmts)
1547{
1548 LY_ARRAY_COUNT_TYPE u;
1549 struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
1550 ly_bool node_free;
1551
1552 LY_ARRAY_FOR(substmts, u) {
1553 if (!substmts[u].storage) {
1554 continue;
1555 }
1556
1557 switch (substmts[u].stmt) {
1558 case LY_STMT_NOTIFICATION:
1559 case LY_STMT_INPUT:
1560 case LY_STMT_OUTPUT:
1561 case LY_STMT_ACTION:
1562 case LY_STMT_RPC:
1563 case LY_STMT_ANYDATA:
1564 case LY_STMT_ANYXML:
1565 case LY_STMT_CASE:
1566 case LY_STMT_CHOICE:
1567 case LY_STMT_CONTAINER:
1568 case LY_STMT_LEAF:
1569 case LY_STMT_LEAF_LIST:
1570 case LY_STMT_LIST: {
1571 struct lysc_node *child, *child_next;
1572
Michal Vasko53eb6a12024-06-13 11:38:47 +02001573 LY_LIST_FOR_SAFE(*VOIDPTR2_C(substmts[u].storage), child_next, child) {
Michal Vasko193dacd2022-10-13 08:43:05 +02001574 node_free = (child->nodetype & (LYS_INPUT | LYS_OUTPUT)) ? 1 : 0;
1575 lysc_node_free_(&fctx, child);
1576 if (node_free) {
1577 free(child);
1578 }
1579 }
Michal Vasko53eb6a12024-06-13 11:38:47 +02001580 *VOIDPTR2_C(substmts[u].storage) = NULL;
Michal Vasko193dacd2022-10-13 08:43:05 +02001581 break;
1582 }
1583 case LY_STMT_USES:
1584 case LY_STMT_CONFIG:
1585 case LY_STMT_FRACTION_DIGITS:
1586 case LY_STMT_MANDATORY:
1587 case LY_STMT_MAX_ELEMENTS:
1588 case LY_STMT_MIN_ELEMENTS:
1589 case LY_STMT_ORDERED_BY:
1590 case LY_STMT_POSITION:
1591 case LY_STMT_REQUIRE_INSTANCE:
1592 case LY_STMT_STATUS:
1593 case LY_STMT_VALUE:
1594 /* nothing to do */
1595 break;
1596
1597 case LY_STMT_ARGUMENT:
1598 case LY_STMT_CONTACT:
1599 case LY_STMT_DESCRIPTION:
1600 case LY_STMT_ERROR_APP_TAG:
1601 case LY_STMT_ERROR_MESSAGE:
1602 case LY_STMT_KEY:
1603 case LY_STMT_MODIFIER:
Michal Vasko3ac60e52022-09-05 11:08:31 +02001604 case LY_STMT_NAMESPACE:
1605 case LY_STMT_ORGANIZATION:
1606 case LY_STMT_PRESENCE:
Radek Krejci1b2eef82021-02-17 11:17:27 +01001607 case LY_STMT_REFERENCE:
Michal Vasko9c3556a2022-10-06 16:08:47 +02001608 case LY_STMT_UNITS: {
1609 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001610 const char *str = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko26bbb272022-08-02 14:54:33 +02001611
Michal Vasko9c3556a2022-10-06 16:08:47 +02001612 lydict_remove(ctx, str);
Radek Krejci38d85362019-09-05 16:26:38 +02001613 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001614 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001615 case LY_STMT_BIT:
1616 case LY_STMT_ENUM: {
1617 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001618 struct lysc_type_bitenum_item *items = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001619
1620 FREE_ARRAY(&fctx, items, lysc_enum_item_free);
1621 break;
1622 }
1623 case LY_STMT_LENGTH:
1624 case LY_STMT_RANGE: {
1625 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001626 struct lysc_range *range = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001627
1628 lysc_range_free(&fctx, range);
1629 break;
1630 }
Michal Vasko9c3556a2022-10-06 16:08:47 +02001631 case LY_STMT_MUST: {
Michal Vasko193dacd2022-10-13 08:43:05 +02001632 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001633 struct lysc_must *musts = *VOIDPTR2_C(substmts[u].storage);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001634
Michal Vasko9c3556a2022-10-06 16:08:47 +02001635 FREE_ARRAY(&fctx, musts, lysc_must_free);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001636 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001637 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001638 case LY_STMT_WHEN:
1639 /* single item, expects a pointer */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001640 lysc_when_free(&fctx, VOIDPTR_C(substmts[u].storage));
Radek Krejci38d85362019-09-05 16:26:38 +02001641 break;
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001642
Michal Vasko193dacd2022-10-13 08:43:05 +02001643 case LY_STMT_PATTERN: {
1644 /* sized array of pointers */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001645 struct lysc_pattern **patterns = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001646
1647 FREE_ARRAY(&fctx, patterns, lysc_pattern_free);
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001648 break;
1649 }
Michal Vasko9c3556a2022-10-06 16:08:47 +02001650 case LY_STMT_TYPE: {
1651 /* single item */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001652 struct lysc_type *type = *VOIDPTR2_C(substmts[u].storage);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001653
Michal Vasko9c3556a2022-10-06 16:08:47 +02001654 lysc_type_free(&fctx, type);
Michal Vaskof8647fa2022-09-05 11:07:54 +02001655 break;
Michal Vasko9c3556a2022-10-06 16:08:47 +02001656 }
Michal Vasko193dacd2022-10-13 08:43:05 +02001657 case LY_STMT_IDENTITY: {
1658 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001659 struct lysc_ident *idents = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001660
1661 FREE_ARRAY(&fctx, idents, lysc_ident_free);
1662 break;
1663 }
1664 case LY_STMT_EXTENSION_INSTANCE: {
1665 /* sized array */
Michal Vasko53eb6a12024-06-13 11:38:47 +02001666 struct lysc_ext_instance *exts = *VOIDPTR2_C(substmts[u].storage);
Michal Vasko193dacd2022-10-13 08:43:05 +02001667
1668 FREE_ARRAY(&fctx, exts, lysc_ext_instance_free);
1669 break;
1670 }
1671 case LY_STMT_AUGMENT:
1672 case LY_STMT_BASE:
1673 case LY_STMT_BELONGS_TO:
1674 case LY_STMT_DEFAULT:
1675 case LY_STMT_DEVIATE:
1676 case LY_STMT_DEVIATION:
1677 case LY_STMT_EXTENSION:
1678 case LY_STMT_FEATURE:
1679 case LY_STMT_GROUPING:
1680 case LY_STMT_IF_FEATURE:
1681 case LY_STMT_IMPORT:
1682 case LY_STMT_INCLUDE:
1683 case LY_STMT_MODULE:
1684 case LY_STMT_PATH:
1685 case LY_STMT_PREFIX:
1686 case LY_STMT_REFINE:
1687 case LY_STMT_REVISION:
1688 case LY_STMT_REVISION_DATE:
1689 case LY_STMT_SUBMODULE:
1690 case LY_STMT_TYPEDEF:
1691 case LY_STMT_UNIQUE:
1692 case LY_STMT_YANG_VERSION:
1693 case LY_STMT_YIN_ELEMENT:
1694 /* it is not possible to compile these statements */
1695 break;
1696
Radek Krejci38d85362019-09-05 16:26:38 +02001697 default:
1698 LOGINT(ctx);
1699 }
1700 }
Radek Krejci1b2eef82021-02-17 11:17:27 +01001701
1702 LY_ARRAY_FREE(substmts);
Radek Krejci38d85362019-09-05 16:26:38 +02001703}
David Sedlákebd3acf2019-07-26 15:04:32 +02001704
1705void
Michal Vaskod0625d72022-10-06 15:02:50 +02001706lysp_yang_ctx_free(struct lysp_yang_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001707{
1708 if (ctx) {
Michal Vaskod0625d72022-10-06 15:02:50 +02001709 if (ctx->main_ctx == (struct lysp_ctx *)ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001710 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1711 ly_set_erase(&ctx->grps_nodes, NULL);
1712 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001713 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vaskoc0c64ae2022-10-06 10:15:23 +02001714 ly_set_erase(&ctx->ext_inst, NULL);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001715 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1716 if (!ctx->parsed_mods->count) {
1717 ly_set_free(ctx->parsed_mods, NULL);
1718 }
David Sedlákebd3acf2019-07-26 15:04:32 +02001719 free(ctx);
1720 }
1721}
1722
1723void
Michal Vaskod0625d72022-10-06 15:02:50 +02001724lysp_yin_ctx_free(struct lysp_yin_ctx *ctx)
David Sedlákebd3acf2019-07-26 15:04:32 +02001725{
1726 if (ctx) {
Michal Vaskod0625d72022-10-06 15:02:50 +02001727 if (ctx->main_ctx == (struct lysp_ctx *)ctx) {
aPiecek8d4e75d2021-06-24 14:47:06 +02001728 ly_set_erase(&ctx->tpdfs_nodes, NULL);
1729 ly_set_erase(&ctx->grps_nodes, NULL);
1730 }
Michal Vaskodd6d5a32022-07-14 13:54:58 +02001731 assert(!ctx->tpdfs_nodes.count && !ctx->grps_nodes.count);
Michal Vaskoc0c64ae2022-10-06 10:15:23 +02001732 ly_set_erase(&ctx->ext_inst, NULL);
Michal Vasko8a67eff2021-12-07 14:04:47 +01001733 ly_set_rm_index(ctx->parsed_mods, ctx->parsed_mods->count - 1, NULL);
1734 if (!ctx->parsed_mods->count) {
1735 ly_set_free(ctx->parsed_mods, NULL);
1736 }
Michal Vaskob36053d2020-03-26 15:49:30 +01001737 lyxml_ctx_free(ctx->xmlctx);
David Sedlákebd3acf2019-07-26 15:04:32 +02001738 free(ctx);
1739 }
1740}