blob: 5f6a050c9e018f248f19281c0cddf53c16d30af7 [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"
17
Radek Krejci6f7feb62018-10-12 15:23:02 +020018#define FREE_ARRAY(CTX, ARRAY, ITER, FUNC) LY_ARRAY_FOR(ARRAY, ITER){FUNC(CTX, &ARRAY[ITER]);}free(ARRAY);
19#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
20#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
21
22static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
23static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
24
25static void
26lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
27{
28 struct lysp_stmt *child, *next;
29
30 FREE_STRING(ctx, stmt->stmt);
31 FREE_STRING(ctx, stmt->arg);
32
33 LY_LIST_FOR_SAFE(stmt->child, next, child) {
34 lysp_stmt_free(ctx, child);
35 }
36
37 free(stmt);
38}
39
40static void
41lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
42{
43 struct lysp_stmt *stmt, *next;
44
45 FREE_STRING(ctx, ext->name);
46 FREE_STRING(ctx, ext->argument);
47
48 LY_LIST_FOR_SAFE(ext->child, next, stmt) {
49 lysp_stmt_free(ctx, stmt);
50 }
51}
52
53static void
54lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
55{
56 unsigned int u;
57
58 FREE_STRING(ctx, import->name);
59 FREE_STRING(ctx, import->prefix);
60 FREE_STRING(ctx, import->dsc);
61 FREE_STRING(ctx, import->ref);
62 FREE_ARRAY(ctx, import->exts, u, lysp_ext_instance_free);
63}
64
65static void
66lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
67{
68 unsigned int u;
69 FREE_STRING(ctx, include->name);
70 FREE_STRING(ctx, include->dsc);
71 FREE_STRING(ctx, include->ref);
72 FREE_ARRAY(ctx, include->exts, u, lysp_ext_instance_free);
73}
74
75static void
76lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
77{
78 unsigned int u;
79 FREE_STRING(ctx, rev->dsc);
80 FREE_STRING(ctx, rev->ref);
81 FREE_ARRAY(ctx, rev->exts, u, lysp_ext_instance_free);
82}
83
84static void
85lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
86{
87 unsigned int u;
88 FREE_STRING(ctx, ext->name);
89 FREE_STRING(ctx, ext->argument);
90 FREE_STRING(ctx, ext->dsc);
91 FREE_STRING(ctx, ext->ref);
92 FREE_ARRAY(ctx, ext->exts, u, lysp_ext_instance_free);
93}
94
95static void
96lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
97{
98 unsigned int u;
99 FREE_STRING(ctx, feat->name);
100 for (u = 0; feat->iffeatures && feat->iffeatures[u]; ++u) {
101 FREE_STRING(ctx, feat->iffeatures[u]);
102 }
103 free(feat->iffeatures);
104 FREE_STRING(ctx, feat->dsc);
105 FREE_STRING(ctx, feat->ref);
106 FREE_ARRAY(ctx, feat->exts, u, lysp_ext_instance_free);
107}
108
109static void
110lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
111{
112 unsigned int u;
113 FREE_STRING(ctx, ident->name);
114 for (u = 0; ident->iffeatures && ident->iffeatures[u]; ++u) {
115 FREE_STRING(ctx, ident->iffeatures[u]);
116 }
117 free(ident->iffeatures);
118 for (u = 0; ident->bases && ident->bases[u]; ++u) {
119 FREE_STRING(ctx, ident->bases[u]);
120 }
121 free(ident->bases);
122 FREE_STRING(ctx, ident->dsc);
123 FREE_STRING(ctx, ident->ref);
124 FREE_ARRAY(ctx, ident->exts, u, lysp_ext_instance_free);
125}
126
127static void
128lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
129{
130 unsigned int u;
131 FREE_STRING(ctx, restr->arg);
132 FREE_STRING(ctx, restr->emsg);
133 FREE_STRING(ctx, restr->eapptag);
134 FREE_STRING(ctx, restr->dsc);
135 FREE_STRING(ctx, restr->ref);
136 FREE_ARRAY(ctx, restr->exts, u, lysp_ext_instance_free);
137}
138
139static void
140lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
141{
142 unsigned int u;
143 FREE_STRING(ctx, item->name);
144 FREE_STRING(ctx, item->dsc);
145 FREE_STRING(ctx, item->ref);
146 for (u = 0; item->iffeatures && item->iffeatures[u]; ++u) {
147 FREE_STRING(ctx, item->iffeatures[u]);
148 }
149 free(item->iffeatures);
150 FREE_ARRAY(ctx, item->exts, u, lysp_ext_instance_free);
151}
152
153static void
154lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
155{
156 unsigned int u;
157 FREE_STRING(ctx, type->name);
158 FREE_MEMBER(ctx, type->range, lysp_restr_free);
159 FREE_MEMBER(ctx, type->length, lysp_restr_free);
160 FREE_ARRAY(ctx, type->patterns, u, lysp_restr_free);
161 FREE_ARRAY(ctx, type->enums, u, lysp_type_enum_free);
162 FREE_ARRAY(ctx, type->bits, u, lysp_type_enum_free);
163 FREE_STRING(ctx, type->path);
164 for (u = 0; type->bases && type->bases[u]; ++u) {
165 FREE_STRING(ctx, type->bases[u]);
166 }
167 free(type->bases);
168 FREE_ARRAY(ctx, type->types, u, lysp_type_free);
169 FREE_ARRAY(ctx, type->exts, u, lysp_ext_instance_free);
170}
171
172static void
173lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
174{
175 unsigned int u;
176 FREE_STRING(ctx, tpdf->name);
177 FREE_STRING(ctx, tpdf->units);
178 FREE_STRING(ctx, tpdf->dflt);
179 FREE_STRING(ctx, tpdf->dsc);
180 FREE_STRING(ctx, tpdf->ref);
181 FREE_ARRAY(ctx, tpdf->exts, u, lysp_ext_instance_free);
182 lysp_type_free(ctx, &tpdf->type);
183}
184
185static void
186lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
187{
188 unsigned int u;
189 struct lysp_node *node, *next;
190
191 FREE_ARRAY(ctx, inout->musts, u, lysp_restr_free);
192 FREE_ARRAY(ctx, inout->typedefs, u, lysp_tpdf_free);
193 FREE_ARRAY(ctx, inout->groupings, u, lysp_grp_free);
194 LY_LIST_FOR_SAFE(inout->data, next, node) {
195 lysp_node_free(ctx, node);
196 }
197 FREE_ARRAY(ctx, inout->exts, u, lysp_ext_instance_free);
198
199}
200
201static void
202lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
203{
204 unsigned int u;
205 FREE_STRING(ctx, action->name);
206 FREE_STRING(ctx, action->dsc);
207 FREE_STRING(ctx, action->ref);
208 for (u = 0; action->iffeatures && action->iffeatures[u]; ++u) {
209 FREE_STRING(ctx, action->iffeatures[u]);
210 }
211 free(action->iffeatures);
212 FREE_ARRAY(ctx, action->typedefs, u, lysp_tpdf_free);
213 FREE_ARRAY(ctx, action->groupings, u, lysp_grp_free);
214 FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
215 FREE_MEMBER(ctx, action->output, lysp_action_inout_free);
216 FREE_ARRAY(ctx, action->exts, u, lysp_ext_instance_free);
217}
218
219static void
220lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
221{
222 unsigned int u;
223 struct lysp_node *node, *next;
224
225 FREE_STRING(ctx, notif->name);
226 FREE_STRING(ctx, notif->dsc);
227 FREE_STRING(ctx, notif->ref);
228 for (u = 0; notif->iffeatures && notif->iffeatures[u]; ++u) {
229 FREE_STRING(ctx, notif->iffeatures[u]);
230 }
231 free(notif->iffeatures);
232 FREE_ARRAY(ctx, notif->musts, u, lysp_restr_free);
233 FREE_ARRAY(ctx, notif->typedefs, u, lysp_tpdf_free);
234 FREE_ARRAY(ctx, notif->groupings, u, lysp_grp_free);
235 LY_LIST_FOR_SAFE(notif->data, next, node) {
236 lysp_node_free(ctx, node);
237 }
238 FREE_ARRAY(ctx, notif->exts, u, lysp_ext_instance_free);
239}
240
241static void
242lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
243{
244 unsigned int u;
245 struct lysp_node *node, *next;
246
247 FREE_STRING(ctx, grp->name);
248 FREE_STRING(ctx, grp->dsc);
249 FREE_STRING(ctx, grp->ref);
250 FREE_ARRAY(ctx, grp->typedefs, u, lysp_tpdf_free);
251 FREE_ARRAY(ctx, grp->groupings, u, lysp_grp_free);
252 LY_LIST_FOR_SAFE(grp->data, next, node) {
253 lysp_node_free(ctx, node);
254 }
255 FREE_ARRAY(ctx, grp->actions, u, lysp_action_free);
256 FREE_ARRAY(ctx, grp->notifs, u, lysp_notif_free);
257 FREE_ARRAY(ctx, grp->exts, u, lysp_ext_instance_free);
258}
259
260static void
261lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
262{
263 unsigned int u;
264 FREE_STRING(ctx, when->cond);
265 FREE_STRING(ctx, when->dsc);
266 FREE_STRING(ctx, when->ref);
267 FREE_ARRAY(ctx, when->exts, u, lysp_ext_instance_free);
268}
269
270static void
271lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
272{
273 unsigned int u;
274 struct lysp_node *node, *next;
275
276 FREE_STRING(ctx, augment->nodeid);
277 FREE_STRING(ctx, augment->dsc);
278 FREE_STRING(ctx, augment->ref);
279 FREE_MEMBER(ctx, augment->when, lysp_when_free);
280 for (u = 0; augment->iffeatures && augment->iffeatures[u]; ++u) {
281 FREE_STRING(ctx, augment->iffeatures[u]);
282 }
283 free(augment->iffeatures);
284 LY_LIST_FOR_SAFE(augment->child, next, node) {
285 lysp_node_free(ctx, node);
286 }
287 FREE_ARRAY(ctx, augment->actions, u, lysp_action_free);
288 FREE_ARRAY(ctx, augment->notifs, u, lysp_notif_free);
289 FREE_ARRAY(ctx, augment->exts, u, lysp_ext_instance_free);
290}
291
292static void
293lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
294{
295 unsigned int u;
296 struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
297 struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
298
299 FREE_ARRAY(ctx, d->exts, u, lysp_ext_instance_free);
300 switch(d->mod) {
301 case LYS_DEV_NOT_SUPPORTED:
302 /* nothing to do */
303 break;
304 case LYS_DEV_ADD:
305 case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
306 FREE_STRING(ctx, add->units);
307 FREE_ARRAY(ctx, add->musts, u, lysp_restr_free);
308 for (u = 0; add->uniques && add->uniques[u]; ++u) {
309 FREE_STRING(ctx, add->uniques[u]);
310 }
311 free(add->uniques);
312 for (u = 0; add->dflts && add->dflts[u]; ++u) {
313 FREE_STRING(ctx, add->dflts[u]);
314 }
315 free(add->dflts);
316 break;
317 case LYS_DEV_REPLACE:
318 FREE_MEMBER(ctx, rpl->type, lysp_type_free);
319 FREE_STRING(ctx, rpl->units);
320 FREE_STRING(ctx, rpl->dflt);
321 break;
322 default:
323 LOGINT(ctx);
324 break;
325 }
326}
327
328static void
329lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
330{
331 unsigned int u;
332 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) {
338 lysp_deviate_free(ctx, iter);
339 }
340 FREE_ARRAY(ctx, dev->exts, u, lysp_ext_instance_free);
341}
342
343static void
344lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
345{
346 unsigned int u;
347 FREE_STRING(ctx, ref->nodeid);
348 FREE_STRING(ctx, ref->dsc);
349 FREE_STRING(ctx, ref->ref);
350 for (u = 0; ref->iffeatures && ref->iffeatures[u]; ++u) {
351 FREE_STRING(ctx, ref->iffeatures[u]);
352 }
353 free(ref->iffeatures);
354 FREE_ARRAY(ctx, ref->musts, u, lysp_restr_free);
355 FREE_STRING(ctx, ref->presence);
356 for (u = 0; ref->dflts && ref->dflts[u]; ++u) {
357 FREE_STRING(ctx, ref->dflts[u]);
358 }
359 free(ref->dflts);
360 FREE_ARRAY(ctx, ref->exts, u, lysp_ext_instance_free);
361}
362
363static void
364lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
365{
366 unsigned int u;
367 struct lysp_node *child, *next;
368
369 FREE_STRING(ctx, node->name);
370 FREE_STRING(ctx, node->dsc);
371 FREE_STRING(ctx, node->ref);
372 FREE_MEMBER(ctx, node->when, lysp_when_free);
373 for (u = 0; node->iffeatures && node->iffeatures[u]; ++u) {
374 FREE_STRING(ctx, node->iffeatures[u]);
375 }
376 free(node->iffeatures);
377 FREE_ARRAY(ctx, node->exts, u, lysp_ext_instance_free);
378
379 switch(node->nodetype) {
380 case LYS_CONTAINER:
381 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, u, lysp_restr_free);
382 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
383 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, u, lysp_tpdf_free);
384 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, u, lysp_grp_free);
385 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
386 lysp_node_free(ctx, child);
387 }
388 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, u, lysp_action_free);
389 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, u, lysp_notif_free);
390 break;
391 case LYS_LEAF:
392 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, u, lysp_restr_free);
393 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
394 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
395 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
396 break;
397 case LYS_LEAFLIST:
398 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, u, lysp_restr_free);
399 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
400 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
401 for (u = 0; ((struct lysp_node_leaflist*)node)->dflts && ((struct lysp_node_leaflist*)node)->dflts[u]; ++u) {
402 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->dflts[u]);
403 }
404 free(((struct lysp_node_leaflist*)node)->dflts);
405 break;
406 case LYS_LIST:
407 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, u, lysp_restr_free);
408 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
409 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, u, lysp_tpdf_free);
410 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, u, lysp_grp_free);
411 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
412 lysp_node_free(ctx, child);
413 }
414 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, u, lysp_action_free);
415 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, u, lysp_notif_free);
416 for (u = 0; ((struct lysp_node_list*)node)->uniques && ((struct lysp_node_list*)node)->uniques[u]; ++u) {
417 FREE_STRING(ctx, ((struct lysp_node_list*)node)->uniques[u]);
418 }
419 free(((struct lysp_node_list*)node)->uniques);
420 break;
421 case LYS_CHOICE:
422 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
423 lysp_node_free(ctx, child);
424 }
425 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
426 break;
427 case LYS_CASE:
428 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
429 lysp_node_free(ctx, child);
430 }
431 break;
432 case LYS_ANYDATA:
433 case LYS_ANYXML:
434 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, u, lysp_restr_free);
435 break;
436 case LYS_USES:
437 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, u, lysp_refine_free);
438 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, u, lysp_augment_free);
439 break;
440 default:
441 LOGINT(ctx);
442 }
443
444 free(node);
445}
446
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200447API void
448lysp_module_free(struct lysp_module *module)
449{
450 struct ly_ctx *ctx;
Radek Krejci6f7feb62018-10-12 15:23:02 +0200451 unsigned int u;
452 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
462 FREE_ARRAY(ctx, module->imports, u, lysp_import_free);
463 FREE_ARRAY(ctx, module->includes, u, lysp_include_free);
464
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
470 FREE_ARRAY(ctx, module->revs, u, lysp_revision_free);
471 FREE_ARRAY(ctx, module->extensions, u, lysp_ext_free);
472 FREE_ARRAY(ctx, module->features, u, lysp_feature_free);
473 FREE_ARRAY(ctx, module->identities, u, lysp_ident_free);
474 FREE_ARRAY(ctx, module->typedefs, u, lysp_tpdf_free);
475 FREE_ARRAY(ctx, module->groupings, u, lysp_grp_free);
476 LY_LIST_FOR_SAFE(module->data, next, node) {
477 lysp_node_free(ctx, node);
478 }
479 FREE_ARRAY(ctx, module->augments, u, lysp_augment_free);
480 FREE_ARRAY(ctx, module->rpcs, u, lysp_action_free);
481 FREE_ARRAY(ctx, module->notifs, u, lysp_notif_free);
482 FREE_ARRAY(ctx, module->deviations, u, lysp_deviation_free);
483 FREE_ARRAY(ctx, module->exts, u, lysp_ext_instance_free);
484
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200485
486 free(module);
487}