blob: 955f8ab1cee506ddcf6637ab4cee5a4def12cb67 [file] [log] [blame]
Radek Krejci3f5e3db2018-10-11 15:57:47 +02001/**
2 * @file tree_schema.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Schema tree implementation
5 *
6 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#include "libyang.h"
16#include "common.h"
Radek Krejci70853c52018-10-15 14:46:16 +020017#include "tree_schema_internal.h"
Radek Krejci3f5e3db2018-10-11 15:57:47 +020018
Radek Krejcie53a8dc2018-10-17 12:52:40 +020019#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, LY_ARRAY_INDEX(ARRAY, c__), dict);}free(ARRAY);}
Radek Krejcidd4e8d42018-10-16 14:55:43 +020020#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER, dict);free(MEMBER);}
21#define FREE_STRING(CTX, STRING) if (dict && STRING) {lydict_remove(CTX, STRING);}
Radek Krejci6f7feb62018-10-12 15:23:02 +020022
Radek Krejcidd4e8d42018-10-16 14:55:43 +020023static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp, int dict);
24static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node, int dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +020025
26static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020027lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020028{
29 struct lysp_stmt *child, *next;
30
31 FREE_STRING(ctx, stmt->stmt);
32 FREE_STRING(ctx, stmt->arg);
33
34 LY_LIST_FOR_SAFE(stmt->child, next, child) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +020035 lysp_stmt_free(ctx, child, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +020036 }
37
38 free(stmt);
39}
40
41static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020042lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020043{
44 struct lysp_stmt *stmt, *next;
45
46 FREE_STRING(ctx, ext->name);
47 FREE_STRING(ctx, ext->argument);
48
49 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +020050 lysp_stmt_free(ctx, stmt, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +020051 }
52}
53
54static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020055lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020056{
Radek Krejci6f7feb62018-10-12 15:23:02 +020057 FREE_STRING(ctx, import->name);
58 FREE_STRING(ctx, import->prefix);
59 FREE_STRING(ctx, import->dsc);
60 FREE_STRING(ctx, import->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +020061 FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
62 {
63 void *p__;
64 int64_t c__;
65 for(p__ = ((void*)((uint32_t*)((import->exts) + 0) + 1)), c__ = 0;
66 (import->exts) && c__ < (*(uint32_t*)(import->exts));
67 p__ = ((void*)((uint32_t*)((import->exts) + c__) + 1))) {
68 lysp_ext_instance_free(ctx, p__, dict);
69 }
70 free(import->exts);
71 }
Radek Krejci6f7feb62018-10-12 15:23:02 +020072}
73
74static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020075lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020076{
Radek Krejci6f7feb62018-10-12 15:23:02 +020077 FREE_STRING(ctx, include->name);
78 FREE_STRING(ctx, include->dsc);
79 FREE_STRING(ctx, include->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +020080 FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +020081}
82
83static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020084lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020085{
Radek Krejci6f7feb62018-10-12 15:23:02 +020086 FREE_STRING(ctx, rev->dsc);
87 FREE_STRING(ctx, rev->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +020088 FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +020089}
90
91static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +020092lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +020093{
Radek Krejci6f7feb62018-10-12 15:23:02 +020094 FREE_STRING(ctx, ext->name);
95 FREE_STRING(ctx, ext->argument);
96 FREE_STRING(ctx, ext->dsc);
97 FREE_STRING(ctx, ext->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +020098 FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +020099}
100
101static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200102lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200103{
104 unsigned int u;
105 FREE_STRING(ctx, feat->name);
106 for (u = 0; feat->iffeatures && feat->iffeatures[u]; ++u) {
107 FREE_STRING(ctx, feat->iffeatures[u]);
108 }
109 free(feat->iffeatures);
110 FREE_STRING(ctx, feat->dsc);
111 FREE_STRING(ctx, feat->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200112 FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200113}
114
115static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200116lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200117{
118 unsigned int u;
119 FREE_STRING(ctx, ident->name);
120 for (u = 0; ident->iffeatures && ident->iffeatures[u]; ++u) {
121 FREE_STRING(ctx, ident->iffeatures[u]);
122 }
123 free(ident->iffeatures);
124 for (u = 0; ident->bases && ident->bases[u]; ++u) {
125 FREE_STRING(ctx, ident->bases[u]);
126 }
127 free(ident->bases);
128 FREE_STRING(ctx, ident->dsc);
129 FREE_STRING(ctx, ident->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200130 FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200131}
132
133static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200134lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200135{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200136 FREE_STRING(ctx, restr->arg);
137 FREE_STRING(ctx, restr->emsg);
138 FREE_STRING(ctx, restr->eapptag);
139 FREE_STRING(ctx, restr->dsc);
140 FREE_STRING(ctx, restr->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200141 FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200142}
143
144static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200145lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200146{
147 unsigned int u;
148 FREE_STRING(ctx, item->name);
149 FREE_STRING(ctx, item->dsc);
150 FREE_STRING(ctx, item->ref);
151 for (u = 0; item->iffeatures && item->iffeatures[u]; ++u) {
152 FREE_STRING(ctx, item->iffeatures[u]);
153 }
154 free(item->iffeatures);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200155 FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200156}
157
158static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200159lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200160{
161 unsigned int u;
162 FREE_STRING(ctx, type->name);
163 FREE_MEMBER(ctx, type->range, lysp_restr_free);
164 FREE_MEMBER(ctx, type->length, lysp_restr_free);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200165 FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
166 FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
167 FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200168 FREE_STRING(ctx, type->path);
169 for (u = 0; type->bases && type->bases[u]; ++u) {
170 FREE_STRING(ctx, type->bases[u]);
171 }
172 free(type->bases);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200173 FREE_ARRAY(ctx, type->types, lysp_type_free);
174 FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200175}
176
177static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200178lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200179{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200180 FREE_STRING(ctx, tpdf->name);
181 FREE_STRING(ctx, tpdf->units);
182 FREE_STRING(ctx, tpdf->dflt);
183 FREE_STRING(ctx, tpdf->dsc);
184 FREE_STRING(ctx, tpdf->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200185 FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200186 lysp_type_free(ctx, &tpdf->type, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200187}
188
189static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200190lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200191{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200192 struct lysp_node *node, *next;
193
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200194 FREE_ARRAY(ctx, inout->musts, lysp_restr_free);
195 FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
196 FREE_ARRAY(ctx, inout->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200197 LY_LIST_FOR_SAFE(inout->data, next, node) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200198 lysp_node_free(ctx, node, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200199 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200200 FREE_ARRAY(ctx, inout->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200201
202}
203
204static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200205lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200206{
207 unsigned int u;
208 FREE_STRING(ctx, action->name);
209 FREE_STRING(ctx, action->dsc);
210 FREE_STRING(ctx, action->ref);
211 for (u = 0; action->iffeatures && action->iffeatures[u]; ++u) {
212 FREE_STRING(ctx, action->iffeatures[u]);
213 }
214 free(action->iffeatures);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200215 FREE_ARRAY(ctx, action->typedefs, lysp_tpdf_free);
216 FREE_ARRAY(ctx, action->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200217 FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
218 FREE_MEMBER(ctx, action->output, lysp_action_inout_free);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200219 FREE_ARRAY(ctx, action->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200220}
221
222static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200223lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200224{
225 unsigned int u;
226 struct lysp_node *node, *next;
227
228 FREE_STRING(ctx, notif->name);
229 FREE_STRING(ctx, notif->dsc);
230 FREE_STRING(ctx, notif->ref);
231 for (u = 0; notif->iffeatures && notif->iffeatures[u]; ++u) {
232 FREE_STRING(ctx, notif->iffeatures[u]);
233 }
234 free(notif->iffeatures);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200235 FREE_ARRAY(ctx, notif->musts, lysp_restr_free);
236 FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
237 FREE_ARRAY(ctx, notif->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200238 LY_LIST_FOR_SAFE(notif->data, next, node) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200239 lysp_node_free(ctx, node, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200240 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200241 FREE_ARRAY(ctx, notif->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200242}
243
244static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200245lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200246{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200247 struct lysp_node *node, *next;
248
249 FREE_STRING(ctx, grp->name);
250 FREE_STRING(ctx, grp->dsc);
251 FREE_STRING(ctx, grp->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200252 FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
253 FREE_ARRAY(ctx, grp->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200254 LY_LIST_FOR_SAFE(grp->data, next, node) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200255 lysp_node_free(ctx, node, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200256 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200257 FREE_ARRAY(ctx, grp->actions, lysp_action_free);
258 FREE_ARRAY(ctx, grp->notifs, lysp_notif_free);
259 FREE_ARRAY(ctx, grp->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200260}
261
262static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200263lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200264{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200265 FREE_STRING(ctx, when->cond);
266 FREE_STRING(ctx, when->dsc);
267 FREE_STRING(ctx, when->ref);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200268 FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200269}
270
271static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200272lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200273{
274 unsigned int u;
275 struct lysp_node *node, *next;
276
277 FREE_STRING(ctx, augment->nodeid);
278 FREE_STRING(ctx, augment->dsc);
279 FREE_STRING(ctx, augment->ref);
280 FREE_MEMBER(ctx, augment->when, lysp_when_free);
281 for (u = 0; augment->iffeatures && augment->iffeatures[u]; ++u) {
282 FREE_STRING(ctx, augment->iffeatures[u]);
283 }
284 free(augment->iffeatures);
285 LY_LIST_FOR_SAFE(augment->child, next, node) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200286 lysp_node_free(ctx, node, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200287 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200288 FREE_ARRAY(ctx, augment->actions, lysp_action_free);
289 FREE_ARRAY(ctx, augment->notifs, lysp_notif_free);
290 FREE_ARRAY(ctx, augment->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200291}
292
293static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200294lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200295{
296 unsigned int u;
297 struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
298 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
299
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200300 FREE_ARRAY(ctx, d->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200301 switch(d->mod) {
302 case LYS_DEV_NOT_SUPPORTED:
303 /* nothing to do */
304 break;
305 case LYS_DEV_ADD:
306 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
307 FREE_STRING(ctx, add->units);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200308 FREE_ARRAY(ctx, add->musts, lysp_restr_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200309 for (u = 0; add->uniques && add->uniques[u]; ++u) {
310 FREE_STRING(ctx, add->uniques[u]);
311 }
312 free(add->uniques);
313 for (u = 0; add->dflts && add->dflts[u]; ++u) {
314 FREE_STRING(ctx, add->dflts[u]);
315 }
316 free(add->dflts);
317 break;
318 case LYS_DEV_REPLACE:
319 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
320 FREE_STRING(ctx, rpl->units);
321 FREE_STRING(ctx, rpl->dflt);
322 break;
323 default:
324 LOGINT(ctx);
325 break;
326 }
327}
328
329static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200330lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200331{
Radek Krejci6f7feb62018-10-12 15:23:02 +0200332 struct lysp_deviate *next, *iter;
333
334 FREE_STRING(ctx, dev->nodeid);
335 FREE_STRING(ctx, dev->dsc);
336 FREE_STRING(ctx, dev->ref);
337 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200338 lysp_deviate_free(ctx, iter, dict);
Michal Vasko8447f6a2018-10-15 10:56:16 +0200339 free(iter);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200340 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200341 FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200342}
343
344static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200345lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200346{
347 unsigned int u;
348 FREE_STRING(ctx, ref->nodeid);
349 FREE_STRING(ctx, ref->dsc);
350 FREE_STRING(ctx, ref->ref);
351 for (u = 0; ref->iffeatures && ref->iffeatures[u]; ++u) {
352 FREE_STRING(ctx, ref->iffeatures[u]);
353 }
354 free(ref->iffeatures);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200355 FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200356 FREE_STRING(ctx, ref->presence);
357 for (u = 0; ref->dflts && ref->dflts[u]; ++u) {
358 FREE_STRING(ctx, ref->dflts[u]);
359 }
360 free(ref->dflts);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200361 FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200362}
363
364static void
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200365lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node, int dict)
Radek Krejci6f7feb62018-10-12 15:23:02 +0200366{
367 unsigned int u;
368 struct lysp_node *child, *next;
369
370 FREE_STRING(ctx, node->name);
371 FREE_STRING(ctx, node->dsc);
372 FREE_STRING(ctx, node->ref);
373 FREE_MEMBER(ctx, node->when, lysp_when_free);
374 for (u = 0; node->iffeatures && node->iffeatures[u]; ++u) {
375 FREE_STRING(ctx, node->iffeatures[u]);
376 }
377 free(node->iffeatures);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200378 FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200379
380 switch(node->nodetype) {
381 case LYS_CONTAINER:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200382 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, lysp_restr_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200383 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200384 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, lysp_tpdf_free);
385 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200386 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200387 lysp_node_free(ctx, child, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200388 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200389 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, lysp_action_free);
390 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, lysp_notif_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200391 break;
392 case LYS_LEAF:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200393 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, lysp_restr_free);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200394 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200395 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
396 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
397 break;
398 case LYS_LEAFLIST:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200399 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, lysp_restr_free);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200400 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200401 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
402 for (u = 0; ((struct lysp_node_leaflist*)node)->dflts && ((struct lysp_node_leaflist*)node)->dflts[u]; ++u) {
403 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->dflts[u]);
404 }
405 free(((struct lysp_node_leaflist*)node)->dflts);
406 break;
407 case LYS_LIST:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200408 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, lysp_restr_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200409 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200410 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, lysp_tpdf_free);
411 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200412 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200413 lysp_node_free(ctx, child, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200414 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200415 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, lysp_action_free);
416 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, lysp_notif_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200417 for (u = 0; ((struct lysp_node_list*)node)->uniques && ((struct lysp_node_list*)node)->uniques[u]; ++u) {
418 FREE_STRING(ctx, ((struct lysp_node_list*)node)->uniques[u]);
419 }
420 free(((struct lysp_node_list*)node)->uniques);
421 break;
422 case LYS_CHOICE:
423 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200424 lysp_node_free(ctx, child, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200425 }
426 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
427 break;
428 case LYS_CASE:
429 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200430 lysp_node_free(ctx, child, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200431 }
432 break;
433 case LYS_ANYDATA:
434 case LYS_ANYXML:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200435 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, lysp_restr_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200436 break;
437 case LYS_USES:
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200438 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, lysp_refine_free);
439 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, lysp_augment_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200440 break;
441 default:
442 LOGINT(ctx);
443 }
444
445 free(node);
446}
447
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200448static void
449lysp_module_free_(struct lysp_module *module, int dict)
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200450{
451 struct ly_ctx *ctx;
Radek Krejci6f7feb62018-10-12 15:23:02 +0200452 struct lysp_node *node, *next;
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200453
454 LY_CHECK_ARG_RET(NULL, module,);
455 ctx = module->ctx;
456
Radek Krejci6f7feb62018-10-12 15:23:02 +0200457 FREE_STRING(ctx, module->name);
458 FREE_STRING(ctx, module->filepath);
459 FREE_STRING(ctx, module->ns); /* or belongs-to */
460 FREE_STRING(ctx, module->prefix);
461
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200462 FREE_ARRAY(ctx, module->imports, lysp_import_free);
463 FREE_ARRAY(ctx, module->includes, lysp_include_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200464
465 FREE_STRING(ctx, module->org);
466 FREE_STRING(ctx, module->contact);
467 FREE_STRING(ctx, module->dsc);
468 FREE_STRING(ctx, module->ref);
469
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200470 FREE_ARRAY(ctx, module->revs, lysp_revision_free);
471 FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
472 FREE_ARRAY(ctx, module->features, lysp_feature_free);
473 FREE_ARRAY(ctx, module->identities, lysp_ident_free);
474 FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
475 FREE_ARRAY(ctx, module->groupings, lysp_grp_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200476 LY_LIST_FOR_SAFE(module->data, next, node) {
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200477 lysp_node_free(ctx, node, dict);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200478 }
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200479 FREE_ARRAY(ctx, module->augments, lysp_augment_free);
480 FREE_ARRAY(ctx, module->rpcs, lysp_action_free);
481 FREE_ARRAY(ctx, module->notifs, lysp_notif_free);
482 FREE_ARRAY(ctx, module->deviations, lysp_deviation_free);
483 FREE_ARRAY(ctx, module->exts, lysp_ext_instance_free);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200484
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200485 free(module);
486}
487
488API void
489lysp_module_free(struct lysp_module *module)
490{
491 lysp_module_free_(module, 1);
492}
493
494static void
495lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat, int dict)
496{
497 FREE_STRING(ctx, feat->name);
498
499}
500
501static void
502lysc_module_free_(struct lysc_module *module, int dict)
503{
504 struct ly_ctx *ctx;
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200505
506 LY_CHECK_ARG_RET(NULL, module,);
507 ctx = module->ctx;
508
509 FREE_STRING(ctx, module->name);
510 FREE_STRING(ctx, module->ns);
511 FREE_STRING(ctx, module->prefix);
512
513
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200514 FREE_ARRAY(ctx, module->features, lysc_feature_free);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200515
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200516
517 free(module);
518}
Radek Krejci70853c52018-10-15 14:46:16 +0200519
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200520API void
521lysc_module_free(struct lysc_module *module)
522{
523 lysc_module_free_(module, 1);
524}
525
Radek Krejci70853c52018-10-15 14:46:16 +0200526LY_ERR
527lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value)
528{
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200529 struct lysp_import *i;
Radek Krejci70853c52018-10-15 14:46:16 +0200530
531 if (module->prefix && &module->prefix != value && !strcmp(module->prefix, *value)) {
532 LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
533 "Prefix \"%s\" already used as module prefix.", *value);
534 return LY_EEXIST;
535 }
536 if (module->imports) {
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200537 LY_ARRAY_FOR(module->imports, struct lysp_import, i) {
538 if (i->prefix && &i->prefix != value && !strcmp(i->prefix, *value)) {
Radek Krejci70853c52018-10-15 14:46:16 +0200539 LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200540 "Prefix \"%s\" already used to import \"%s\" module.", *value, i->name);
Radek Krejci70853c52018-10-15 14:46:16 +0200541 return LY_EEXIST;
542 }
543 }
544 }
545 return LY_SUCCESS;
546}
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200547
548static LY_ERR
549lys_compile_feature(struct ly_ctx *ctx, struct lysp_feature *feature_p, int options, struct lysc_feature **features)
550{
551 struct lysc_feature *feature;
552
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200553 LYSP_ARRAY_NEW_RET(ctx, *features, feature, LY_EMEM);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200554
555 if (options & LYSC_OPT_FREE_SP) {
556 /* just switch the pointers */
557 feature->name = feature_p->name;
558 } else {
559 /* keep refcounts correct for lysp_module_free() */
560 feature->name = lydict_insert(ctx, feature_p->name, 0);
561 }
562 feature->flags = feature_p->flags;
563
564 return LY_SUCCESS;
565}
566
567LY_ERR
568lys_compile(struct lysp_module *sp, int options, struct lysc_module **sc)
569{
570 /* shortcuts */
571 struct ly_ctx *ctx;
572 struct lysc_module *mod_c;
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200573 void *p;
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200574
575 LY_ERR ret;
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200576
577 LY_CHECK_ARG_RET(NULL, sc, sp, sp->ctx, LY_EINVAL);
578 ctx = sp->ctx;
579
580 if (sp->submodule) {
581 LOGERR(ctx, LY_EINVAL, "Submodules (%s) are not supposed to be compiled, compile only the main modules.", sp->name);
582 return LY_EINVAL;
583 }
584
585 mod_c = calloc(1, sizeof *mod_c);
586 LY_CHECK_ERR_RET(!mod_c, LOGMEM(ctx), LY_EMEM);
587 mod_c->ctx = ctx;
588
589 if (options & LYSC_OPT_FREE_SP) {
590 /* just switch the pointers */
591 mod_c->name = sp->name;
592 mod_c->ns = sp->ns;
593 mod_c->prefix = sp->prefix;
594 } else {
595 /* keep refcounts correct for lysp_module_free() */
596 mod_c->name = lydict_insert(ctx, sp->name, 0);
597 mod_c->ns = lydict_insert(ctx, sp->ns, 0);
598 mod_c->prefix = lydict_insert(ctx, sp->prefix, 0);
599 }
600
601 if (sp->features) {
Radek Krejcie53a8dc2018-10-17 12:52:40 +0200602 LY_ARRAY_FOR(sp->features, struct lysp_feature, p) {
603 ret = lys_compile_feature(ctx, p, options, &mod_c->features);
Radek Krejcidd4e8d42018-10-16 14:55:43 +0200604 LY_CHECK_GOTO(ret != LY_SUCCESS, error);
605 }
606 }
607
608 if (options & LYSC_OPT_FREE_SP) {
609 lysp_module_free_(sp, 0);
610 }
611
612 (*sc) = mod_c;
613 return LY_SUCCESS;
614
615error:
616
617 if (options & LYSC_OPT_FREE_SP) {
618 lysc_module_free_(mod_c, 0);
619 } else {
620 lysc_module_free_(mod_c, 1);
621 }
622 return ret;
623}