blob: 1df393fde36e8e857e2c89c6c53892b3e3ba1fd8 [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 Krejci6f7feb62018-10-12 15:23:02 +020019#define FREE_ARRAY(CTX, ARRAY, ITER, FUNC) LY_ARRAY_FOR(ARRAY, ITER){FUNC(CTX, &ARRAY[ITER]);}free(ARRAY);
20#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
21#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
22
23static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
24static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
25
26static void
27lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
28{
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) {
35 lysp_stmt_free(ctx, child);
36 }
37
38 free(stmt);
39}
40
41static void
42lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
43{
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) {
50 lysp_stmt_free(ctx, stmt);
51 }
52}
53
54static void
55lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
56{
57 unsigned int u;
58
59 FREE_STRING(ctx, import->name);
60 FREE_STRING(ctx, import->prefix);
61 FREE_STRING(ctx, import->dsc);
62 FREE_STRING(ctx, import->ref);
63 FREE_ARRAY(ctx, import->exts, u, lysp_ext_instance_free);
64}
65
66static void
67lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
68{
69 unsigned int u;
70 FREE_STRING(ctx, include->name);
71 FREE_STRING(ctx, include->dsc);
72 FREE_STRING(ctx, include->ref);
73 FREE_ARRAY(ctx, include->exts, u, lysp_ext_instance_free);
74}
75
76static void
77lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
78{
79 unsigned int u;
80 FREE_STRING(ctx, rev->dsc);
81 FREE_STRING(ctx, rev->ref);
82 FREE_ARRAY(ctx, rev->exts, u, lysp_ext_instance_free);
83}
84
85static void
86lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
87{
88 unsigned int u;
89 FREE_STRING(ctx, ext->name);
90 FREE_STRING(ctx, ext->argument);
91 FREE_STRING(ctx, ext->dsc);
92 FREE_STRING(ctx, ext->ref);
93 FREE_ARRAY(ctx, ext->exts, u, lysp_ext_instance_free);
94}
95
96static void
97lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
98{
99 unsigned int u;
100 FREE_STRING(ctx, feat->name);
101 for (u = 0; feat->iffeatures && feat->iffeatures[u]; ++u) {
102 FREE_STRING(ctx, feat->iffeatures[u]);
103 }
104 free(feat->iffeatures);
105 FREE_STRING(ctx, feat->dsc);
106 FREE_STRING(ctx, feat->ref);
107 FREE_ARRAY(ctx, feat->exts, u, lysp_ext_instance_free);
108}
109
110static void
111lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
112{
113 unsigned int u;
114 FREE_STRING(ctx, ident->name);
115 for (u = 0; ident->iffeatures && ident->iffeatures[u]; ++u) {
116 FREE_STRING(ctx, ident->iffeatures[u]);
117 }
118 free(ident->iffeatures);
119 for (u = 0; ident->bases && ident->bases[u]; ++u) {
120 FREE_STRING(ctx, ident->bases[u]);
121 }
122 free(ident->bases);
123 FREE_STRING(ctx, ident->dsc);
124 FREE_STRING(ctx, ident->ref);
125 FREE_ARRAY(ctx, ident->exts, u, lysp_ext_instance_free);
126}
127
128static void
129lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
130{
131 unsigned int u;
132 FREE_STRING(ctx, restr->arg);
133 FREE_STRING(ctx, restr->emsg);
134 FREE_STRING(ctx, restr->eapptag);
135 FREE_STRING(ctx, restr->dsc);
136 FREE_STRING(ctx, restr->ref);
137 FREE_ARRAY(ctx, restr->exts, u, lysp_ext_instance_free);
138}
139
140static void
141lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
142{
143 unsigned int u;
144 FREE_STRING(ctx, item->name);
145 FREE_STRING(ctx, item->dsc);
146 FREE_STRING(ctx, item->ref);
147 for (u = 0; item->iffeatures && item->iffeatures[u]; ++u) {
148 FREE_STRING(ctx, item->iffeatures[u]);
149 }
150 free(item->iffeatures);
151 FREE_ARRAY(ctx, item->exts, u, lysp_ext_instance_free);
152}
153
154static void
155lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
156{
157 unsigned int u;
158 FREE_STRING(ctx, type->name);
159 FREE_MEMBER(ctx, type->range, lysp_restr_free);
160 FREE_MEMBER(ctx, type->length, lysp_restr_free);
161 FREE_ARRAY(ctx, type->patterns, u, lysp_restr_free);
162 FREE_ARRAY(ctx, type->enums, u, lysp_type_enum_free);
163 FREE_ARRAY(ctx, type->bits, u, lysp_type_enum_free);
164 FREE_STRING(ctx, type->path);
165 for (u = 0; type->bases && type->bases[u]; ++u) {
166 FREE_STRING(ctx, type->bases[u]);
167 }
168 free(type->bases);
169 FREE_ARRAY(ctx, type->types, u, lysp_type_free);
170 FREE_ARRAY(ctx, type->exts, u, lysp_ext_instance_free);
171}
172
173static void
174lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
175{
176 unsigned int u;
177 FREE_STRING(ctx, tpdf->name);
178 FREE_STRING(ctx, tpdf->units);
179 FREE_STRING(ctx, tpdf->dflt);
180 FREE_STRING(ctx, tpdf->dsc);
181 FREE_STRING(ctx, tpdf->ref);
182 FREE_ARRAY(ctx, tpdf->exts, u, lysp_ext_instance_free);
183 lysp_type_free(ctx, &tpdf->type);
184}
185
186static void
187lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
188{
189 unsigned int u;
190 struct lysp_node *node, *next;
191
192 FREE_ARRAY(ctx, inout->musts, u, lysp_restr_free);
193 FREE_ARRAY(ctx, inout->typedefs, u, lysp_tpdf_free);
194 FREE_ARRAY(ctx, inout->groupings, u, lysp_grp_free);
195 LY_LIST_FOR_SAFE(inout->data, next, node) {
196 lysp_node_free(ctx, node);
197 }
198 FREE_ARRAY(ctx, inout->exts, u, lysp_ext_instance_free);
199
200}
201
202static void
203lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
204{
205 unsigned int u;
206 FREE_STRING(ctx, action->name);
207 FREE_STRING(ctx, action->dsc);
208 FREE_STRING(ctx, action->ref);
209 for (u = 0; action->iffeatures && action->iffeatures[u]; ++u) {
210 FREE_STRING(ctx, action->iffeatures[u]);
211 }
212 free(action->iffeatures);
213 FREE_ARRAY(ctx, action->typedefs, u, lysp_tpdf_free);
214 FREE_ARRAY(ctx, action->groupings, u, lysp_grp_free);
215 FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
216 FREE_MEMBER(ctx, action->output, lysp_action_inout_free);
217 FREE_ARRAY(ctx, action->exts, u, lysp_ext_instance_free);
218}
219
220static void
221lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
222{
223 unsigned int u;
224 struct lysp_node *node, *next;
225
226 FREE_STRING(ctx, notif->name);
227 FREE_STRING(ctx, notif->dsc);
228 FREE_STRING(ctx, notif->ref);
229 for (u = 0; notif->iffeatures && notif->iffeatures[u]; ++u) {
230 FREE_STRING(ctx, notif->iffeatures[u]);
231 }
232 free(notif->iffeatures);
233 FREE_ARRAY(ctx, notif->musts, u, lysp_restr_free);
234 FREE_ARRAY(ctx, notif->typedefs, u, lysp_tpdf_free);
235 FREE_ARRAY(ctx, notif->groupings, u, lysp_grp_free);
236 LY_LIST_FOR_SAFE(notif->data, next, node) {
237 lysp_node_free(ctx, node);
238 }
239 FREE_ARRAY(ctx, notif->exts, u, lysp_ext_instance_free);
240}
241
242static void
243lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
244{
245 unsigned int u;
246 struct lysp_node *node, *next;
247
248 FREE_STRING(ctx, grp->name);
249 FREE_STRING(ctx, grp->dsc);
250 FREE_STRING(ctx, grp->ref);
251 FREE_ARRAY(ctx, grp->typedefs, u, lysp_tpdf_free);
252 FREE_ARRAY(ctx, grp->groupings, u, lysp_grp_free);
253 LY_LIST_FOR_SAFE(grp->data, next, node) {
254 lysp_node_free(ctx, node);
255 }
256 FREE_ARRAY(ctx, grp->actions, u, lysp_action_free);
257 FREE_ARRAY(ctx, grp->notifs, u, lysp_notif_free);
258 FREE_ARRAY(ctx, grp->exts, u, lysp_ext_instance_free);
259}
260
261static void
262lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
263{
264 unsigned int u;
265 FREE_STRING(ctx, when->cond);
266 FREE_STRING(ctx, when->dsc);
267 FREE_STRING(ctx, when->ref);
268 FREE_ARRAY(ctx, when->exts, u, lysp_ext_instance_free);
269}
270
271static void
272lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
273{
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) {
286 lysp_node_free(ctx, node);
287 }
288 FREE_ARRAY(ctx, augment->actions, u, lysp_action_free);
289 FREE_ARRAY(ctx, augment->notifs, u, lysp_notif_free);
290 FREE_ARRAY(ctx, augment->exts, u, lysp_ext_instance_free);
291}
292
293static void
294lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
295{
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
300 FREE_ARRAY(ctx, d->exts, u, lysp_ext_instance_free);
301 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);
308 FREE_ARRAY(ctx, add->musts, u, lysp_restr_free);
309 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
330lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
331{
332 unsigned int u;
333 struct lysp_deviate *next, *iter;
334
335 FREE_STRING(ctx, dev->nodeid);
336 FREE_STRING(ctx, dev->dsc);
337 FREE_STRING(ctx, dev->ref);
338 LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
339 lysp_deviate_free(ctx, iter);
Michal Vasko8447f6a2018-10-15 10:56:16 +0200340 free(iter);
Radek Krejci6f7feb62018-10-12 15:23:02 +0200341 }
342 FREE_ARRAY(ctx, dev->exts, u, lysp_ext_instance_free);
343}
344
345static void
346lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
347{
348 unsigned int u;
349 FREE_STRING(ctx, ref->nodeid);
350 FREE_STRING(ctx, ref->dsc);
351 FREE_STRING(ctx, ref->ref);
352 for (u = 0; ref->iffeatures && ref->iffeatures[u]; ++u) {
353 FREE_STRING(ctx, ref->iffeatures[u]);
354 }
355 free(ref->iffeatures);
356 FREE_ARRAY(ctx, ref->musts, u, lysp_restr_free);
357 FREE_STRING(ctx, ref->presence);
358 for (u = 0; ref->dflts && ref->dflts[u]; ++u) {
359 FREE_STRING(ctx, ref->dflts[u]);
360 }
361 free(ref->dflts);
362 FREE_ARRAY(ctx, ref->exts, u, lysp_ext_instance_free);
363}
364
365static void
366lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
367{
368 unsigned int u;
369 struct lysp_node *child, *next;
370
371 FREE_STRING(ctx, node->name);
372 FREE_STRING(ctx, node->dsc);
373 FREE_STRING(ctx, node->ref);
374 FREE_MEMBER(ctx, node->when, lysp_when_free);
375 for (u = 0; node->iffeatures && node->iffeatures[u]; ++u) {
376 FREE_STRING(ctx, node->iffeatures[u]);
377 }
378 free(node->iffeatures);
379 FREE_ARRAY(ctx, node->exts, u, lysp_ext_instance_free);
380
381 switch(node->nodetype) {
382 case LYS_CONTAINER:
383 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, u, lysp_restr_free);
384 FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
385 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, u, lysp_tpdf_free);
386 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, u, lysp_grp_free);
387 LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
388 lysp_node_free(ctx, child);
389 }
390 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, u, lysp_action_free);
391 FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, u, lysp_notif_free);
392 break;
393 case LYS_LEAF:
394 FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, u, lysp_restr_free);
395 lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
396 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
397 FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
398 break;
399 case LYS_LEAFLIST:
400 FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, u, lysp_restr_free);
401 lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
402 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
403 for (u = 0; ((struct lysp_node_leaflist*)node)->dflts && ((struct lysp_node_leaflist*)node)->dflts[u]; ++u) {
404 FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->dflts[u]);
405 }
406 free(((struct lysp_node_leaflist*)node)->dflts);
407 break;
408 case LYS_LIST:
409 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, u, lysp_restr_free);
410 FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
411 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, u, lysp_tpdf_free);
412 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, u, lysp_grp_free);
413 LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
414 lysp_node_free(ctx, child);
415 }
416 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, u, lysp_action_free);
417 FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, u, lysp_notif_free);
418 for (u = 0; ((struct lysp_node_list*)node)->uniques && ((struct lysp_node_list*)node)->uniques[u]; ++u) {
419 FREE_STRING(ctx, ((struct lysp_node_list*)node)->uniques[u]);
420 }
421 free(((struct lysp_node_list*)node)->uniques);
422 break;
423 case LYS_CHOICE:
424 LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
425 lysp_node_free(ctx, child);
426 }
427 FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
428 break;
429 case LYS_CASE:
430 LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
431 lysp_node_free(ctx, child);
432 }
433 break;
434 case LYS_ANYDATA:
435 case LYS_ANYXML:
436 FREE_ARRAY(ctx, ((struct lysp_node_anydata*)node)->musts, u, lysp_restr_free);
437 break;
438 case LYS_USES:
439 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->refines, u, lysp_refine_free);
440 FREE_ARRAY(ctx, ((struct lysp_node_uses*)node)->augments, u, lysp_augment_free);
441 break;
442 default:
443 LOGINT(ctx);
444 }
445
446 free(node);
447}
448
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200449API void
450lysp_module_free(struct lysp_module *module)
451{
452 struct ly_ctx *ctx;
Radek Krejci6f7feb62018-10-12 15:23:02 +0200453 unsigned int u;
454 struct lysp_node *node, *next;
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200455
456 LY_CHECK_ARG_RET(NULL, module,);
457 ctx = module->ctx;
458
Radek Krejci6f7feb62018-10-12 15:23:02 +0200459 FREE_STRING(ctx, module->name);
460 FREE_STRING(ctx, module->filepath);
461 FREE_STRING(ctx, module->ns); /* or belongs-to */
462 FREE_STRING(ctx, module->prefix);
463
464 FREE_ARRAY(ctx, module->imports, u, lysp_import_free);
465 FREE_ARRAY(ctx, module->includes, u, lysp_include_free);
466
467 FREE_STRING(ctx, module->org);
468 FREE_STRING(ctx, module->contact);
469 FREE_STRING(ctx, module->dsc);
470 FREE_STRING(ctx, module->ref);
471
472 FREE_ARRAY(ctx, module->revs, u, lysp_revision_free);
473 FREE_ARRAY(ctx, module->extensions, u, lysp_ext_free);
474 FREE_ARRAY(ctx, module->features, u, lysp_feature_free);
475 FREE_ARRAY(ctx, module->identities, u, lysp_ident_free);
476 FREE_ARRAY(ctx, module->typedefs, u, lysp_tpdf_free);
477 FREE_ARRAY(ctx, module->groupings, u, lysp_grp_free);
478 LY_LIST_FOR_SAFE(module->data, next, node) {
479 lysp_node_free(ctx, node);
480 }
481 FREE_ARRAY(ctx, module->augments, u, lysp_augment_free);
482 FREE_ARRAY(ctx, module->rpcs, u, lysp_action_free);
483 FREE_ARRAY(ctx, module->notifs, u, lysp_notif_free);
484 FREE_ARRAY(ctx, module->deviations, u, lysp_deviation_free);
485 FREE_ARRAY(ctx, module->exts, u, lysp_ext_instance_free);
486
Radek Krejci3f5e3db2018-10-11 15:57:47 +0200487
488 free(module);
489}
Radek Krejci70853c52018-10-15 14:46:16 +0200490
491LY_ERR
492lysp_check_prefix(struct ly_parser_ctx *ctx, struct lysp_module *module, const char **value)
493{
494 unsigned int u;
495
496 if (module->prefix && &module->prefix != value && !strcmp(module->prefix, *value)) {
497 LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
498 "Prefix \"%s\" already used as module prefix.", *value);
499 return LY_EEXIST;
500 }
501 if (module->imports) {
502 LY_ARRAY_FOR(module->imports, u) {
503 if (module->imports[u].prefix && &module->imports[u].prefix != value && !strcmp(module->imports[u].prefix, *value)) {
504 LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_REFERENCE,
505 "Prefix \"%s\" already used to import \"%s\" module.", *value, module->imports[u].name);
506 return LY_EEXIST;
507 }
508 }
509 }
510 return LY_SUCCESS;
511}