blob: 7402f7e674801662183305ef5c99c9ad5543d6b4 [file] [log] [blame]
Radek Krejci19a96102018-11-15 13:38:09 +01001/**
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 "common.h"
16
17#include <ctype.h>
18#include <dirent.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <linux/limits.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28#include "libyang.h"
29#include "context.h"
30#include "tree_schema_internal.h"
31#include "xpath.h"
32
33/**
34 * @brief Duplicate string into dictionary
35 * @param[in] CTX libyang context of the dictionary.
36 * @param[in] ORIG String to duplicate.
37 * @param[out] DUP Where to store the result.
38 */
39#define DUP_STRING(CTX, ORIG, DUP) if (ORIG) {DUP = lydict_insert(CTX, ORIG, 0);}
40
41#define COMPILE_ARRAY_GOTO(CTX, ARRAY_P, ARRAY_C, OPTIONS, ITER, FUNC, RET, GOTO) \
42 if (ARRAY_P) { \
43 LY_ARRAY_CREATE_GOTO((CTX)->ctx, ARRAY_C, LY_ARRAY_SIZE(ARRAY_P), RET, GOTO); \
44 for (ITER = 0; ITER < LY_ARRAY_SIZE(ARRAY_P); ++ITER) { \
45 LY_ARRAY_INCREMENT(ARRAY_C); \
46 RET = FUNC(CTX, &(ARRAY_P)[ITER], OPTIONS, &(ARRAY_C)[ITER]); \
47 LY_CHECK_GOTO(RET != LY_SUCCESS, GOTO); \
48 } \
49 }
50
51#define COMPILE_MEMBER_GOTO(CTX, MEMBER_P, MEMBER_C, OPTIONS, FUNC, RET, GOTO) \
52 if (MEMBER_P) { \
53 MEMBER_C = calloc(1, sizeof *(MEMBER_C)); \
54 LY_CHECK_ERR_GOTO(!(MEMBER_C), LOGMEM((CTX)->ctx); RET = LY_EMEM, GOTO); \
55 RET = FUNC(CTX, MEMBER_P, OPTIONS, MEMBER_C); \
56 LY_CHECK_GOTO(RET != LY_SUCCESS, GOTO); \
57 }
58
59const char* ly_data_type2str[LY_DATA_TYPE_COUNT] = {"unknown", "binary", "bits", "boolean", "decimal64", "empty", "enumeration",
60 "identityref", "instance-identifier", "leafref", "string", "union", "8bit integer", "8bit unsigned integer", "16bit integer",
61 "16bit unsigned integer", "32bit integer", "32bit unsigned integer", "64bit integer", "64bit unsigned integer"
62};
63
64static struct lysc_ext_instance *
65lysc_ext_instance_dup(struct ly_ctx *ctx, struct lysc_ext_instance *orig)
66{
67 /* TODO */
68 (void) ctx;
69 (void) orig;
70 return NULL;
71}
72
73static struct lysc_pattern*
74lysc_pattern_dup(struct lysc_pattern *orig)
75{
76 ++orig->refcount;
77 return orig;
78}
79
80static struct lysc_pattern**
81lysc_patterns_dup(struct ly_ctx *ctx, struct lysc_pattern **orig)
82{
83 struct lysc_pattern **dup;
84 unsigned int u;
85
86 LY_ARRAY_CREATE_RET(ctx, dup, LY_ARRAY_SIZE(orig), NULL);
87 LY_ARRAY_FOR(orig, u) {
88 dup[u] = lysc_pattern_dup(orig[u]);
89 LY_ARRAY_INCREMENT(dup);
90 }
91 return dup;
92}
93
94struct lysc_range*
95lysc_range_dup(struct ly_ctx *ctx, const struct lysc_range *orig)
96{
97 struct lysc_range *dup;
98 LY_ERR ret;
99
100 dup = calloc(1, sizeof *dup);
101 LY_CHECK_ERR_RET(!dup, LOGMEM(ctx), NULL);
102 if (orig->parts) {
103 LY_ARRAY_CREATE_GOTO(ctx, dup->parts, LY_ARRAY_SIZE(orig->parts), ret, cleanup);
104 LY_ARRAY_SIZE(dup->parts) = LY_ARRAY_SIZE(orig->parts);
105 memcpy(dup->parts, orig->parts, LY_ARRAY_SIZE(dup->parts) * sizeof *dup->parts);
106 }
107 DUP_STRING(ctx, orig->eapptag, dup->eapptag);
108 DUP_STRING(ctx, orig->emsg, dup->emsg);
109 dup->exts = lysc_ext_instance_dup(ctx, orig->exts);
110
111 return dup;
112cleanup:
113 free(dup);
114 (void) ret; /* set but not used due to the return type */
115 return NULL;
116}
117
118struct iff_stack {
119 int size;
120 int index; /* first empty item */
121 uint8_t *stack;
122};
123
124static LY_ERR
125iff_stack_push(struct iff_stack *stack, uint8_t value)
126{
127 if (stack->index == stack->size) {
128 stack->size += 4;
129 stack->stack = ly_realloc(stack->stack, stack->size * sizeof *stack->stack);
130 LY_CHECK_ERR_RET(!stack->stack, LOGMEM(NULL); stack->size = 0, LY_EMEM);
131 }
132 stack->stack[stack->index++] = value;
133 return LY_SUCCESS;
134}
135
136static uint8_t
137iff_stack_pop(struct iff_stack *stack)
138{
139 stack->index--;
140 return stack->stack[stack->index];
141}
142
143static void
144iff_stack_clean(struct iff_stack *stack)
145{
146 stack->size = 0;
147 free(stack->stack);
148}
149
150static void
151iff_setop(uint8_t *list, uint8_t op, int pos)
152{
153 uint8_t *item;
154 uint8_t mask = 3;
155
156 assert(pos >= 0);
157 assert(op <= 3); /* max 2 bits */
158
159 item = &list[pos / 4];
160 mask = mask << 2 * (pos % 4);
161 *item = (*item) & ~mask;
162 *item = (*item) | (op << 2 * (pos % 4));
163}
164
165#define LYS_IFF_LP 0x04 /* ( */
166#define LYS_IFF_RP 0x08 /* ) */
167
168static struct lysc_feature *
169lysc_feature_find(struct lysc_module *mod, const char *name, size_t len)
170{
171 size_t i;
172 struct lysc_feature *f;
173
174 for (i = 0; i < len; ++i) {
175 if (name[i] == ':') {
176 /* we have a prefixed feature */
177 mod = lysc_module_find_prefix(mod, name, i);
178 LY_CHECK_RET(!mod, NULL);
179
180 name = &name[i + 1];
181 len = len - i - 1;
182 }
183 }
184
185 /* we have the correct module, get the feature */
186 LY_ARRAY_FOR(mod->features, i) {
187 f = &mod->features[i];
188 if (!strncmp(f->name, name, len) && f->name[len] == '\0') {
189 return f;
190 }
191 }
192
193 return NULL;
194}
195
196static LY_ERR
197lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, int UNUSED(options), struct lysc_ext_instance *ext)
198{
199 const char *name;
200 unsigned int u;
201 const struct lys_module *mod;
202 struct lysp_ext *edef = NULL;
203
204 DUP_STRING(ctx->ctx, ext_p->argument, ext->argument);
205 ext->insubstmt = ext_p->insubstmt;
206 ext->insubstmt_index = ext_p->insubstmt_index;
207
208 /* get module where the extension definition should be placed */
209 for (u = 0; ext_p->name[u] != ':'; ++u);
210 mod = lys_module_find_prefix(ctx->mod, ext_p->name, u);
211 LY_CHECK_ERR_RET(!mod, LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
212 "Invalid prefix \"%.*s\" used for extension instance identifier.", u, ext_p->name),
213 LY_EVALID);
214 LY_CHECK_ERR_RET(!mod->parsed->extensions,
215 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
216 "Extension instance \"%s\" refers \"%s\" module that does not contain extension definitions.",
217 ext_p->name, mod->parsed->name),
218 LY_EVALID);
219 name = &ext_p->name[u + 1];
220 /* find the extension definition there */
221 for (ext = NULL, u = 0; u < LY_ARRAY_SIZE(mod->parsed->extensions); ++u) {
222 if (!strcmp(name, mod->parsed->extensions[u].name)) {
223 edef = &mod->parsed->extensions[u];
224 break;
225 }
226 }
227 LY_CHECK_ERR_RET(!edef, LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
228 "Extension definition of extension instance \"%s\" not found.", ext_p->name),
229 LY_EVALID);
230 /* TODO plugins */
231
232 return LY_SUCCESS;
233}
234
235static LY_ERR
236lys_compile_iffeature(struct lysc_ctx *ctx, const char **value, int UNUSED(options), struct lysc_iffeature *iff)
237{
238 const char *c = *value;
239 int r, rc = EXIT_FAILURE;
240 int i, j, last_not, checkversion = 0;
241 unsigned int f_size = 0, expr_size = 0, f_exp = 1;
242 uint8_t op;
243 struct iff_stack stack = {0, 0, NULL};
244 struct lysc_feature *f;
245
246 assert(c);
247
248 /* pre-parse the expression to get sizes for arrays, also do some syntax checks of the expression */
249 for (i = j = last_not = 0; c[i]; i++) {
250 if (c[i] == '(') {
251 j++;
252 checkversion = 1;
253 continue;
254 } else if (c[i] == ')') {
255 j--;
256 continue;
257 } else if (isspace(c[i])) {
258 checkversion = 1;
259 continue;
260 }
261
262 if (!strncmp(&c[i], "not", r = 3) || !strncmp(&c[i], "and", r = 3) || !strncmp(&c[i], "or", r = 2)) {
263 if (c[i + r] == '\0') {
264 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
265 "Invalid value \"%s\" of if-feature - unexpected end of expression.", *value);
266 return LY_EVALID;
267 } else if (!isspace(c[i + r])) {
268 /* feature name starting with the not/and/or */
269 last_not = 0;
270 f_size++;
271 } else if (c[i] == 'n') { /* not operation */
272 if (last_not) {
273 /* double not */
274 expr_size = expr_size - 2;
275 last_not = 0;
276 } else {
277 last_not = 1;
278 }
279 } else { /* and, or */
280 f_exp++;
281 /* not a not operation */
282 last_not = 0;
283 }
284 i += r;
285 } else {
286 f_size++;
287 last_not = 0;
288 }
289 expr_size++;
290
291 while (!isspace(c[i])) {
292 if (!c[i] || c[i] == ')') {
293 i--;
294 break;
295 }
296 i++;
297 }
298 }
299 if (j || f_exp != f_size) {
300 /* not matching count of ( and ) */
301 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
302 "Invalid value \"%s\" of if-feature - non-matching opening and closing parentheses.", *value);
303 return LY_EVALID;
304 }
305
306 if (checkversion || expr_size > 1) {
307 /* check that we have 1.1 module */
308 if (ctx->mod->compiled->version != LYS_VERSION_1_1) {
309 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
310 "Invalid value \"%s\" of if-feature - YANG 1.1 expression in YANG 1.0 module.", *value);
311 return LY_EVALID;
312 }
313 }
314
315 /* allocate the memory */
316 LY_ARRAY_CREATE_RET(ctx->ctx, iff->features, f_size, LY_EMEM);
317 iff->expr = calloc((j = (expr_size / 4) + ((expr_size % 4) ? 1 : 0)), sizeof *iff->expr);
318 stack.stack = malloc(expr_size * sizeof *stack.stack);
319 LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr, LOGMEM(ctx->ctx), error);
320
321 stack.size = expr_size;
322 f_size--; expr_size--; /* used as indexes from now */
323
324 for (i--; i >= 0; i--) {
325 if (c[i] == ')') {
326 /* push it on stack */
327 iff_stack_push(&stack, LYS_IFF_RP);
328 continue;
329 } else if (c[i] == '(') {
330 /* pop from the stack into result all operators until ) */
331 while((op = iff_stack_pop(&stack)) != LYS_IFF_RP) {
332 iff_setop(iff->expr, op, expr_size--);
333 }
334 continue;
335 } else if (isspace(c[i])) {
336 continue;
337 }
338
339 /* end of operator or operand -> find beginning and get what is it */
340 j = i + 1;
341 while (i >= 0 && !isspace(c[i]) && c[i] != '(') {
342 i--;
343 }
344 i++; /* go back by one step */
345
346 if (!strncmp(&c[i], "not", 3) && isspace(c[i + 3])) {
347 if (stack.index && stack.stack[stack.index - 1] == LYS_IFF_NOT) {
348 /* double not */
349 iff_stack_pop(&stack);
350 } else {
351 /* not has the highest priority, so do not pop from the stack
352 * as in case of AND and OR */
353 iff_stack_push(&stack, LYS_IFF_NOT);
354 }
355 } else if (!strncmp(&c[i], "and", 3) && isspace(c[i + 3])) {
356 /* as for OR - pop from the stack all operators with the same or higher
357 * priority and store them to the result, then push the AND to the stack */
358 while (stack.index && stack.stack[stack.index - 1] <= LYS_IFF_AND) {
359 op = iff_stack_pop(&stack);
360 iff_setop(iff->expr, op, expr_size--);
361 }
362 iff_stack_push(&stack, LYS_IFF_AND);
363 } else if (!strncmp(&c[i], "or", 2) && isspace(c[i + 2])) {
364 while (stack.index && stack.stack[stack.index - 1] <= LYS_IFF_OR) {
365 op = iff_stack_pop(&stack);
366 iff_setop(iff->expr, op, expr_size--);
367 }
368 iff_stack_push(&stack, LYS_IFF_OR);
369 } else {
370 /* feature name, length is j - i */
371
372 /* add it to the expression */
373 iff_setop(iff->expr, LYS_IFF_F, expr_size--);
374
375 /* now get the link to the feature definition */
376 f = lysc_feature_find(ctx->mod->compiled, &c[i], j - i);
377 LY_CHECK_ERR_GOTO(!f,
378 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
379 "Invalid value \"%s\" of if-feature - unable to find feature \"%.*s\".", *value, j - i, &c[i]);
380 rc = LY_EVALID,
381 error)
382 iff->features[f_size] = f;
383 LY_ARRAY_INCREMENT(iff->features);
384 f_size--;
385 }
386 }
387 while (stack.index) {
388 op = iff_stack_pop(&stack);
389 iff_setop(iff->expr, op, expr_size--);
390 }
391
392 if (++expr_size || ++f_size) {
393 /* not all expected operators and operands found */
394 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
395 "Invalid value \"%s\" of if-feature - processing error.", *value);
396 rc = LY_EINT;
397 } else {
398 rc = LY_SUCCESS;
399 }
400
401error:
402 /* cleanup */
403 iff_stack_clean(&stack);
404
405 return rc;
406}
407
408static LY_ERR
409lys_compile_when(struct lysc_ctx *ctx, struct lysp_when *when_p, int options, struct lysc_when *when)
410{
411 unsigned int u;
412 LY_ERR ret = LY_SUCCESS;
413
414 when->cond = lyxp_expr_parse(ctx->ctx, when_p->cond);
415 LY_CHECK_ERR_GOTO(!when->cond, ret = ly_errcode(ctx->ctx), done);
416 COMPILE_ARRAY_GOTO(ctx, when_p->exts, when->exts, options, u, lys_compile_ext, ret, done);
417
418done:
419 return ret;
420}
421
422static LY_ERR
423lys_compile_must(struct lysc_ctx *ctx, struct lysp_restr *must_p, int options, struct lysc_must *must)
424{
425 unsigned int u;
426 LY_ERR ret = LY_SUCCESS;
427
428 must->cond = lyxp_expr_parse(ctx->ctx, must_p->arg);
429 LY_CHECK_ERR_GOTO(!must->cond, ret = ly_errcode(ctx->ctx), done);
430
431 DUP_STRING(ctx->ctx, must_p->eapptag, must->eapptag);
432 DUP_STRING(ctx->ctx, must_p->emsg, must->emsg);
433 COMPILE_ARRAY_GOTO(ctx, must_p->exts, must->exts, options, u, lys_compile_ext, ret, done);
434
435done:
436 return ret;
437}
438
439static LY_ERR
440lys_compile_import(struct lysc_ctx *ctx, struct lysp_import *imp_p, int options, struct lysc_import *imp)
441{
442 unsigned int u;
443 struct lys_module *mod = NULL;
444 struct lysc_module *comp;
445 LY_ERR ret = LY_SUCCESS;
446
447 DUP_STRING(ctx->ctx, imp_p->prefix, imp->prefix);
448 COMPILE_ARRAY_GOTO(ctx, imp_p->exts, imp->exts, options, u, lys_compile_ext, ret, done);
449 imp->module = imp_p->module;
450
451 /* make sure that we have both versions (lysp_ and lysc_) of the imported module. To import groupings or
452 * typedefs, the lysp_ is needed. To augment or deviate imported module, we need the lysc_ structure */
453 if (!imp->module->parsed) {
454 comp = imp->module->compiled;
455 /* try to get filepath from the compiled version */
456 if (comp->filepath) {
457 mod = (struct lys_module*)lys_parse_path(ctx->ctx, comp->filepath,
458 !strcmp(&comp->filepath[strlen(comp->filepath - 4)], ".yin") ? LYS_IN_YIN : LYS_IN_YANG);
459 if (mod != imp->module) {
460 LOGERR(ctx->ctx, LY_EINT, "Filepath \"%s\" of the module \"%s\" does not match.",
461 comp->filepath, comp->name);
462 mod = NULL;
463 }
464 }
465 if (!mod) {
466 if (lysp_load_module(ctx->ctx, comp->name, comp->revision, 0, 1, &mod)) {
467 LOGERR(ctx->ctx, LY_ENOTFOUND, "Unable to reload \"%s\" module to import it into \"%s\", source data not found.",
468 comp->name, ctx->mod->compiled->name);
469 return LY_ENOTFOUND;
470 }
471 }
472 } else if (!imp->module->compiled) {
473 return lys_compile(imp->module, options);
474 }
475
476done:
477 return ret;
478}
479
480static LY_ERR
481lys_compile_identity(struct lysc_ctx *ctx, struct lysp_ident *ident_p, int options, struct lysc_ident *ident)
482{
483 unsigned int u;
484 LY_ERR ret = LY_SUCCESS;
485
486 DUP_STRING(ctx->ctx, ident_p->name, ident->name);
487 COMPILE_ARRAY_GOTO(ctx, ident_p->iffeatures, ident->iffeatures, options, u, lys_compile_iffeature, ret, done);
488 /* backlings (derived) can be added no sooner than when all the identities in the current module are present */
489 COMPILE_ARRAY_GOTO(ctx, ident_p->exts, ident->exts, options, u, lys_compile_ext, ret, done);
490 ident->flags = ident_p->flags;
491
492done:
493 return ret;
494}
495
496static LY_ERR
497lys_compile_identities_derived(struct lysc_ctx *ctx, struct lysp_ident *idents_p, struct lysc_ident *idents)
498{
499 unsigned int i, u, v;
500 const char *s, *name;
501 struct lysc_module *mod;
502 struct lysc_ident **dident;
503
504 for (i = 0; i < LY_ARRAY_SIZE(idents_p); ++i) {
505 if (!idents_p[i].bases) {
506 continue;
507 }
508 for (u = 0; u < LY_ARRAY_SIZE(idents_p[i].bases); ++u) {
509 s = strchr(idents_p[i].bases[u], ':');
510 if (s) {
511 /* prefixed identity */
512 name = &s[1];
513 mod = lysc_module_find_prefix(ctx->mod->compiled, idents_p[i].bases[u], s - idents_p[i].bases[u]);
514 } else {
515 name = idents_p[i].bases[u];
516 mod = ctx->mod->compiled;
517 }
518 LY_CHECK_ERR_RET(!mod, LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
519 "Invalid prefix used for base (%s) of identity \"%s\".", idents_p[i].bases[u], idents[i].name),
520 LY_EVALID);
521 if (mod->identities) {
522 for (v = 0; v < LY_ARRAY_SIZE(mod->identities); ++v) {
523 if (!strcmp(name, mod->identities[v].name)) {
524 /* we have match! store the backlink */
525 LY_ARRAY_NEW_RET(ctx->ctx, mod->identities[v].derived, dident, LY_EMEM);
526 *dident = &idents[i];
527 break;
528 }
529 }
530 }
531 LY_CHECK_ERR_RET(!dident, LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
532 "Unable to find base (%s) of identity \"%s\".", idents_p[i].bases[u], idents[i].name),
533 LY_EVALID);
534 }
535 }
536 return LY_SUCCESS;
537}
538
539static LY_ERR
540lys_compile_feature(struct lysc_ctx *ctx, struct lysp_feature *feature_p, int options, struct lysc_feature *feature)
541{
542 unsigned int u, v;
543 LY_ERR ret = LY_SUCCESS;
544 struct lysc_feature **df;
545
546 DUP_STRING(ctx->ctx, feature_p->name, feature->name);
547 feature->flags = feature_p->flags;
548
549 COMPILE_ARRAY_GOTO(ctx, feature_p->exts, feature->exts, options, u, lys_compile_ext, ret, done);
550 COMPILE_ARRAY_GOTO(ctx, feature_p->iffeatures, feature->iffeatures, options, u, lys_compile_iffeature, ret, done);
551 if (feature->iffeatures) {
552 for (u = 0; u < LY_ARRAY_SIZE(feature->iffeatures); ++u) {
553 if (feature->iffeatures[u].features) {
554 for (v = 0; v < LY_ARRAY_SIZE(feature->iffeatures[u].features); ++v) {
555 /* add itself into the dependants list */
556 LY_ARRAY_NEW_RET(ctx->ctx, feature->iffeatures[u].features[v]->depfeatures, df, LY_EMEM);
557 *df = feature;
558 }
559 /* TODO check for circular dependency */
560 }
561 }
562 }
563done:
564 return ret;
565}
566
567static LY_ERR
568range_part_check_value_syntax(struct lysc_ctx *ctx, LY_DATA_TYPE basetype, const char *value, size_t *len, char **valcopy)
569{
570 size_t fraction = 0;
571 *len = 0;
572
573 assert(value);
574 /* parse value */
575 if (!isdigit(value[*len]) && (value[*len] != '-') && (value[*len] != '+')) {
576 return LY_EVALID;
577 }
578
579 if ((value[*len] == '-') || (value[*len] == '+')) {
580 ++(*len);
581 }
582
583 while (isdigit(value[*len])) {
584 ++(*len);
585 }
586
587 if ((basetype != LY_TYPE_DEC64) || (value[*len] != '.') || !isdigit(value[*len + 1])) {
588 *valcopy = strndup(value, *len);
589 return LY_SUCCESS;
590 }
591 fraction = *len;
592
593 ++(*len);
594 while (isdigit(value[*len])) {
595 ++(*len);
596 }
597
598 if (fraction) {
599 *valcopy = malloc(((*len) - 1) * sizeof **valcopy);
600 LY_CHECK_ERR_RET(!(*valcopy), LOGMEM(ctx->ctx), LY_EMEM);
601
602 *valcopy[(*len) - 1] = '\0';
603 memcpy(&(*valcopy)[0], &value[0], fraction);
604 memcpy(&(*valcopy)[fraction], &value[fraction + 1], (*len) - 1 - (fraction + 1));
605 }
606 return LY_SUCCESS;
607}
608
609static LY_ERR
610range_part_check_ascendance(int unsigned_value, int64_t value, int64_t prev_value)
611{
612 if (unsigned_value) {
613 if ((uint64_t)prev_value >= (uint64_t)value) {
614 return LY_EEXIST;
615 }
616 } else {
617 if (prev_value >= value) {
618 return LY_EEXIST;
619 }
620 }
621 return LY_SUCCESS;
622}
623
624static LY_ERR
625range_part_minmax(struct lysc_ctx *ctx, struct lysc_range_part *part, int max, int64_t prev, LY_DATA_TYPE basetype, int first, int length_restr,
626 const char **value)
627{
628 LY_ERR ret = LY_SUCCESS;
629 char *valcopy = NULL;
630 size_t len;
631
632 if (value) {
633 ret = range_part_check_value_syntax(ctx, basetype, *value, &len, &valcopy);
634 LY_CHECK_GOTO(ret, error);
635 }
636
637 switch (basetype) {
638 case LY_TYPE_BINARY: /* length */
639 if (valcopy) {
640 ret = ly_parse_uint(valcopy, UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
641 } else if (max) {
642 part->max_u64 = UINT64_C(18446744073709551615);
643 } else {
644 part->min_u64 = UINT64_C(0);
645 }
646 if (!first) {
647 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
648 }
649 break;
650 case LY_TYPE_DEC64: /* range */
651 if (valcopy) {
652 ret = ly_parse_int(valcopy, INT64_C(-9223372036854775807) - INT64_C(1), INT64_C(9223372036854775807), 10,
653 max ? &part->max_64 : &part->min_64);
654 } else if (max) {
655 part->max_64 = INT64_C(9223372036854775807);
656 } else {
657 part->min_64 = INT64_C(-9223372036854775807) - INT64_C(1);
658 }
659 if (!first) {
660 ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
661 }
662 break;
663 case LY_TYPE_INT8: /* range */
664 if (valcopy) {
665 ret = ly_parse_int(valcopy, INT64_C(-128), INT64_C(127), 10, max ? &part->max_64 : &part->min_64);
666 } else if (max) {
667 part->max_64 = INT64_C(127);
668 } else {
669 part->min_64 = INT64_C(-128);
670 }
671 if (!first) {
672 ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
673 }
674 break;
675 case LY_TYPE_INT16: /* range */
676 if (valcopy) {
677 ret = ly_parse_int(valcopy, INT64_C(-32768), INT64_C(32767), 10, max ? &part->max_64 : &part->min_64);
678 } else if (max) {
679 part->max_64 = INT64_C(32767);
680 } else {
681 part->min_64 = INT64_C(-32768);
682 }
683 if (!first) {
684 ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
685 }
686 break;
687 case LY_TYPE_INT32: /* range */
688 if (valcopy) {
689 ret = ly_parse_int(valcopy, INT64_C(-2147483648), INT64_C(2147483647), 10, max ? &part->max_64 : &part->min_64);
690 } else if (max) {
691 part->max_64 = INT64_C(2147483647);
692 } else {
693 part->min_64 = INT64_C(-2147483648);
694 }
695 if (!first) {
696 ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
697 }
698 break;
699 case LY_TYPE_INT64: /* range */
700 if (valcopy) {
701 ret = ly_parse_int(valcopy, INT64_C(-9223372036854775807) - INT64_C(1), INT64_C(9223372036854775807), 10,
702 max ? &part->max_64 : &part->min_64);
703 } else if (max) {
704 part->max_64 = INT64_C(9223372036854775807);
705 } else {
706 part->min_64 = INT64_C(-9223372036854775807) - INT64_C(1);
707 }
708 if (!first) {
709 ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
710 }
711 break;
712 case LY_TYPE_UINT8: /* range */
713 if (valcopy) {
714 ret = ly_parse_uint(valcopy, UINT64_C(255), 10, max ? &part->max_u64 : &part->min_u64);
715 } else if (max) {
716 part->max_u64 = UINT64_C(255);
717 } else {
718 part->min_u64 = UINT64_C(0);
719 }
720 if (!first) {
721 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
722 }
723 break;
724 case LY_TYPE_UINT16: /* range */
725 if (valcopy) {
726 ret = ly_parse_uint(valcopy, UINT64_C(65535), 10, max ? &part->max_u64 : &part->min_u64);
727 } else if (max) {
728 part->max_u64 = UINT64_C(65535);
729 } else {
730 part->min_u64 = UINT64_C(0);
731 }
732 if (!first) {
733 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
734 }
735 break;
736 case LY_TYPE_UINT32: /* range */
737 if (valcopy) {
738 ret = ly_parse_uint(valcopy, UINT64_C(4294967295), 10, max ? &part->max_u64 : &part->min_u64);
739 } else if (max) {
740 part->max_u64 = UINT64_C(4294967295);
741 } else {
742 part->min_u64 = UINT64_C(0);
743 }
744 if (!first) {
745 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
746 }
747 break;
748 case LY_TYPE_UINT64: /* range */
749 if (valcopy) {
750 ret = ly_parse_uint(valcopy, UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
751 } else if (max) {
752 part->max_u64 = UINT64_C(18446744073709551615);
753 } else {
754 part->min_u64 = UINT64_C(0);
755 }
756 if (!first) {
757 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
758 }
759 break;
760 case LY_TYPE_STRING: /* length */
761 if (valcopy) {
762 ret = ly_parse_uint(valcopy, UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
763 } else if (max) {
764 part->max_u64 = UINT64_C(18446744073709551615);
765 } else {
766 part->min_u64 = UINT64_C(0);
767 }
768 if (!first) {
769 ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
770 }
771 break;
772 default:
773 LOGINT(ctx->ctx);
774 ret = LY_EINT;
775 }
776
777error:
778 if (ret == LY_EDENIED) {
779 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
780 "Invalid %s restriction - value \"%s\" does not fit the type limitations.",
781 length_restr ? "length" : "range", valcopy ? valcopy : *value);
782 } else if (ret == LY_EVALID) {
783 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
784 "Invalid %s restriction - invalid value \"%s\".",
785 length_restr ? "length" : "range", valcopy ? valcopy : *value);
786 } else if (ret == LY_EEXIST) {
787 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
788 "Invalid %s restriction - values are not in ascending order (%s).",
789 length_restr ? "length" : "range", valcopy ? valcopy : *value);
790 } else if (!ret && value) {
791 *value = *value + len;
792 }
793 free(valcopy);
794 return ret;
795}
796
797static LY_ERR
798lys_compile_type_range(struct lysc_ctx *ctx, struct lysp_restr *range_p, LY_DATA_TYPE basetype, int length_restr,
799 struct lysc_range *base_range, struct lysc_range **range)
800{
801 LY_ERR ret = LY_EVALID;
802 const char *expr;
803 struct lysc_range_part *parts = NULL, *part;
804 int range_expected = 0, uns;
805 unsigned int parts_done = 0, u, v;
806
807 assert(range);
808 assert(range_p);
809
810 expr = range_p->arg;
811 while(1) {
812 if (isspace(*expr)) {
813 ++expr;
814 } else if (*expr == '\0') {
815 if (range_expected) {
816 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
817 "Invalid %s restriction - unexpected end of the expression after \"..\" (%s).",
818 length_restr ? "length" : "range", range_p->arg);
819 goto cleanup;
820 } else if (!parts || parts_done == LY_ARRAY_SIZE(parts)) {
821 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
822 "Invalid %s restriction - unexpected end of the expression (%s).",
823 length_restr ? "length" : "range", range_p->arg);
824 goto cleanup;
825 }
826 parts_done++;
827 break;
828 } else if (!strncmp(expr, "min", 3)) {
829 if (parts) {
830 /* min cannot be used elsewhere than in the first part */
831 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
832 "Invalid %s restriction - unexpected data before min keyword (%.*s).", length_restr ? "length" : "range",
833 expr - range_p->arg, range_p->arg);
834 goto cleanup;
835 }
836 expr += 3;
837
838 LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
839 LY_CHECK_GOTO(range_part_minmax(ctx, part, 0, 0, basetype, 1, length_restr, NULL), cleanup);
840 part->max_64 = part->min_64;
841 } else if (*expr == '|') {
842 if (!parts || range_expected) {
843 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
844 "Invalid %s restriction - unexpected beginning of the expression (%s).", length_restr ? "length" : "range", expr);
845 goto cleanup;
846 }
847 expr++;
848 parts_done++;
849 /* process next part of the expression */
850 } else if (!strncmp(expr, "..", 2)) {
851 expr += 2;
852 while (isspace(*expr)) {
853 expr++;
854 }
855 if (!parts || LY_ARRAY_SIZE(parts) == parts_done) {
856 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
857 "Invalid %s restriction - unexpected \"..\" without a lower bound.", length_restr ? "length" : "range");
858 goto cleanup;
859 }
860 /* continue expecting the upper boundary */
861 range_expected = 1;
862 } else if (isdigit(*expr) || (*expr == '-') || (*expr == '+')) {
863 /* number */
864 if (range_expected) {
865 part = &parts[LY_ARRAY_SIZE(parts) - 1];
866 LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, part->min_64, basetype, 0, length_restr, &expr), cleanup);
867 range_expected = 0;
868 } else {
869 LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
870 LY_CHECK_GOTO(range_part_minmax(ctx, part, 0, parts_done ? parts[LY_ARRAY_SIZE(parts) - 2].max_64 : 0,
871 basetype, parts_done ? 0 : 1, length_restr, &expr), cleanup);
872 part->max_64 = part->min_64;
873 }
874
875 /* continue with possible another expression part */
876 } else if (!strncmp(expr, "max", 3)) {
877 expr += 3;
878 while (isspace(*expr)) {
879 expr++;
880 }
881 if (*expr != '\0') {
882 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data after max keyword (%s).",
883 length_restr ? "length" : "range", expr);
884 goto cleanup;
885 }
886 if (range_expected) {
887 part = &parts[LY_ARRAY_SIZE(parts) - 1];
888 LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, part->min_64, basetype, 0, length_restr, NULL), cleanup);
889 range_expected = 0;
890 } else {
891 LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
892 LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, parts_done ? parts[LY_ARRAY_SIZE(parts) - 2].max_64 : 0,
893 basetype, parts_done ? 0 : 1, length_restr, NULL), cleanup);
894 part->min_64 = part->max_64;
895 }
896 } else {
897 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data (%s).",
898 length_restr ? "length" : "range", expr);
899 goto cleanup;
900 }
901 }
902
903 /* check with the previous range/length restriction */
904 if (base_range) {
905 switch (basetype) {
906 case LY_TYPE_BINARY:
907 case LY_TYPE_UINT8:
908 case LY_TYPE_UINT16:
909 case LY_TYPE_UINT32:
910 case LY_TYPE_UINT64:
911 case LY_TYPE_STRING:
912 uns = 1;
913 break;
914 case LY_TYPE_DEC64:
915 case LY_TYPE_INT8:
916 case LY_TYPE_INT16:
917 case LY_TYPE_INT32:
918 case LY_TYPE_INT64:
919 uns = 0;
920 break;
921 default:
922 LOGINT(ctx->ctx);
923 ret = LY_EINT;
924 goto cleanup;
925 }
926 for (u = v = 0; u < parts_done && v < LY_ARRAY_SIZE(base_range->parts); ++u) {
927 if ((uns && parts[u].min_u64 < base_range->parts[v].min_u64) || (!uns && parts[u].min_64 < base_range->parts[v].min_64)) {
928 goto baseerror;
929 }
930 /* current lower bound is not lower than the base */
931 if (base_range->parts[v].min_64 == base_range->parts[v].max_64) {
932 /* base has single value */
933 if (base_range->parts[v].min_64 == parts[u].min_64) {
934 /* both lower bounds are the same */
935 if (parts[u].min_64 != parts[u].max_64) {
936 /* current continues with a range */
937 goto baseerror;
938 } else {
939 /* equal single values, move both forward */
940 ++v;
941 continue;
942 }
943 } else {
944 /* base is single value lower than current range, so the
945 * value from base range is removed in the current,
946 * move only base and repeat checking */
947 ++v;
948 --u;
949 continue;
950 }
951 } else {
952 /* base is the range */
953 if (parts[u].min_64 == parts[u].max_64) {
954 /* current is a single value */
955 if ((uns && parts[u].max_u64 > base_range->parts[v].max_u64) || (!uns && parts[u].max_64 > base_range->parts[v].max_64)) {
956 /* current is behind the base range, so base range is omitted,
957 * move the base and keep the current for further check */
958 ++v;
959 --u;
960 } /* else it is within the base range, so move the current, but keep the base */
961 continue;
962 } else {
963 /* both are ranges - check the higher bound, the lower was already checked */
964 if ((uns && parts[u].max_u64 > base_range->parts[v].max_u64) || (!uns && parts[u].max_64 > base_range->parts[v].max_64)) {
965 /* higher bound is higher than the current higher bound */
966 if ((uns && parts[u].min_u64 > base_range->parts[v].max_u64) || (!uns && parts[u].min_64 > base_range->parts[v].max_64)) {
967 /* but the current lower bound is also higher, so the base range is omitted,
968 * continue with the same current, but move the base */
969 --u;
970 ++v;
971 continue;
972 }
973 /* current range starts within the base range but end behind it */
974 goto baseerror;
975 } else {
976 /* current range is smaller than the base,
977 * move current, but stay with the base */
978 continue;
979 }
980 }
981 }
982 }
983 if (u != parts_done) {
984baseerror:
985 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
986 "Invalid %s restriction - the derived restriction (%s) is not equally or more limiting.",
987 length_restr ? "length" : "range", range_p->arg);
988 goto cleanup;
989 }
990 }
991
992 if (!(*range)) {
993 *range = calloc(1, sizeof **range);
994 LY_CHECK_ERR_RET(!(*range), LOGMEM(ctx->ctx), LY_EMEM);
995 }
996
997 if (range_p->eapptag) {
998 lydict_remove(ctx->ctx, (*range)->eapptag);
999 (*range)->eapptag = lydict_insert(ctx->ctx, range_p->eapptag, 0);
1000 }
1001 if (range_p->emsg) {
1002 lydict_remove(ctx->ctx, (*range)->emsg);
1003 (*range)->emsg = lydict_insert(ctx->ctx, range_p->emsg, 0);
1004 }
1005 /* extensions are taken only from the last range by the caller */
1006
1007 (*range)->parts = parts;
1008 parts = NULL;
1009 ret = LY_SUCCESS;
1010cleanup:
1011 /* TODO clean up */
1012 LY_ARRAY_FREE(parts);
1013
1014 return ret;
1015}
1016
1017/**
1018 * @brief Checks pattern syntax.
1019 *
1020 * @param[in] pattern Pattern to check.
1021 * @param[out] pcre_precomp Precompiled PCRE pattern. Can be NULL.
1022 * @return EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
1023 */
1024static LY_ERR
1025lys_compile_type_pattern_check(struct lysc_ctx *ctx, const char *pattern, pcre **pcre_precomp)
1026{
1027 int idx, idx2, start, end, err_offset, count;
1028 char *perl_regex, *ptr;
1029 const char *err_msg, *orig_ptr;
1030 pcre *precomp;
1031#define URANGE_LEN 19
1032 char *ublock2urange[][2] = {
1033 {"BasicLatin", "[\\x{0000}-\\x{007F}]"},
1034 {"Latin-1Supplement", "[\\x{0080}-\\x{00FF}]"},
1035 {"LatinExtended-A", "[\\x{0100}-\\x{017F}]"},
1036 {"LatinExtended-B", "[\\x{0180}-\\x{024F}]"},
1037 {"IPAExtensions", "[\\x{0250}-\\x{02AF}]"},
1038 {"SpacingModifierLetters", "[\\x{02B0}-\\x{02FF}]"},
1039 {"CombiningDiacriticalMarks", "[\\x{0300}-\\x{036F}]"},
1040 {"Greek", "[\\x{0370}-\\x{03FF}]"},
1041 {"Cyrillic", "[\\x{0400}-\\x{04FF}]"},
1042 {"Armenian", "[\\x{0530}-\\x{058F}]"},
1043 {"Hebrew", "[\\x{0590}-\\x{05FF}]"},
1044 {"Arabic", "[\\x{0600}-\\x{06FF}]"},
1045 {"Syriac", "[\\x{0700}-\\x{074F}]"},
1046 {"Thaana", "[\\x{0780}-\\x{07BF}]"},
1047 {"Devanagari", "[\\x{0900}-\\x{097F}]"},
1048 {"Bengali", "[\\x{0980}-\\x{09FF}]"},
1049 {"Gurmukhi", "[\\x{0A00}-\\x{0A7F}]"},
1050 {"Gujarati", "[\\x{0A80}-\\x{0AFF}]"},
1051 {"Oriya", "[\\x{0B00}-\\x{0B7F}]"},
1052 {"Tamil", "[\\x{0B80}-\\x{0BFF}]"},
1053 {"Telugu", "[\\x{0C00}-\\x{0C7F}]"},
1054 {"Kannada", "[\\x{0C80}-\\x{0CFF}]"},
1055 {"Malayalam", "[\\x{0D00}-\\x{0D7F}]"},
1056 {"Sinhala", "[\\x{0D80}-\\x{0DFF}]"},
1057 {"Thai", "[\\x{0E00}-\\x{0E7F}]"},
1058 {"Lao", "[\\x{0E80}-\\x{0EFF}]"},
1059 {"Tibetan", "[\\x{0F00}-\\x{0FFF}]"},
1060 {"Myanmar", "[\\x{1000}-\\x{109F}]"},
1061 {"Georgian", "[\\x{10A0}-\\x{10FF}]"},
1062 {"HangulJamo", "[\\x{1100}-\\x{11FF}]"},
1063 {"Ethiopic", "[\\x{1200}-\\x{137F}]"},
1064 {"Cherokee", "[\\x{13A0}-\\x{13FF}]"},
1065 {"UnifiedCanadianAboriginalSyllabics", "[\\x{1400}-\\x{167F}]"},
1066 {"Ogham", "[\\x{1680}-\\x{169F}]"},
1067 {"Runic", "[\\x{16A0}-\\x{16FF}]"},
1068 {"Khmer", "[\\x{1780}-\\x{17FF}]"},
1069 {"Mongolian", "[\\x{1800}-\\x{18AF}]"},
1070 {"LatinExtendedAdditional", "[\\x{1E00}-\\x{1EFF}]"},
1071 {"GreekExtended", "[\\x{1F00}-\\x{1FFF}]"},
1072 {"GeneralPunctuation", "[\\x{2000}-\\x{206F}]"},
1073 {"SuperscriptsandSubscripts", "[\\x{2070}-\\x{209F}]"},
1074 {"CurrencySymbols", "[\\x{20A0}-\\x{20CF}]"},
1075 {"CombiningMarksforSymbols", "[\\x{20D0}-\\x{20FF}]"},
1076 {"LetterlikeSymbols", "[\\x{2100}-\\x{214F}]"},
1077 {"NumberForms", "[\\x{2150}-\\x{218F}]"},
1078 {"Arrows", "[\\x{2190}-\\x{21FF}]"},
1079 {"MathematicalOperators", "[\\x{2200}-\\x{22FF}]"},
1080 {"MiscellaneousTechnical", "[\\x{2300}-\\x{23FF}]"},
1081 {"ControlPictures", "[\\x{2400}-\\x{243F}]"},
1082 {"OpticalCharacterRecognition", "[\\x{2440}-\\x{245F}]"},
1083 {"EnclosedAlphanumerics", "[\\x{2460}-\\x{24FF}]"},
1084 {"BoxDrawing", "[\\x{2500}-\\x{257F}]"},
1085 {"BlockElements", "[\\x{2580}-\\x{259F}]"},
1086 {"GeometricShapes", "[\\x{25A0}-\\x{25FF}]"},
1087 {"MiscellaneousSymbols", "[\\x{2600}-\\x{26FF}]"},
1088 {"Dingbats", "[\\x{2700}-\\x{27BF}]"},
1089 {"BraillePatterns", "[\\x{2800}-\\x{28FF}]"},
1090 {"CJKRadicalsSupplement", "[\\x{2E80}-\\x{2EFF}]"},
1091 {"KangxiRadicals", "[\\x{2F00}-\\x{2FDF}]"},
1092 {"IdeographicDescriptionCharacters", "[\\x{2FF0}-\\x{2FFF}]"},
1093 {"CJKSymbolsandPunctuation", "[\\x{3000}-\\x{303F}]"},
1094 {"Hiragana", "[\\x{3040}-\\x{309F}]"},
1095 {"Katakana", "[\\x{30A0}-\\x{30FF}]"},
1096 {"Bopomofo", "[\\x{3100}-\\x{312F}]"},
1097 {"HangulCompatibilityJamo", "[\\x{3130}-\\x{318F}]"},
1098 {"Kanbun", "[\\x{3190}-\\x{319F}]"},
1099 {"BopomofoExtended", "[\\x{31A0}-\\x{31BF}]"},
1100 {"EnclosedCJKLettersandMonths", "[\\x{3200}-\\x{32FF}]"},
1101 {"CJKCompatibility", "[\\x{3300}-\\x{33FF}]"},
1102 {"CJKUnifiedIdeographsExtensionA", "[\\x{3400}-\\x{4DB5}]"},
1103 {"CJKUnifiedIdeographs", "[\\x{4E00}-\\x{9FFF}]"},
1104 {"YiSyllables", "[\\x{A000}-\\x{A48F}]"},
1105 {"YiRadicals", "[\\x{A490}-\\x{A4CF}]"},
1106 {"HangulSyllables", "[\\x{AC00}-\\x{D7A3}]"},
1107 {"PrivateUse", "[\\x{E000}-\\x{F8FF}]"},
1108 {"CJKCompatibilityIdeographs", "[\\x{F900}-\\x{FAFF}]"},
1109 {"AlphabeticPresentationForms", "[\\x{FB00}-\\x{FB4F}]"},
1110 {"ArabicPresentationForms-A", "[\\x{FB50}-\\x{FDFF}]"},
1111 {"CombiningHalfMarks", "[\\x{FE20}-\\x{FE2F}]"},
1112 {"CJKCompatibilityForms", "[\\x{FE30}-\\x{FE4F}]"},
1113 {"SmallFormVariants", "[\\x{FE50}-\\x{FE6F}]"},
1114 {"ArabicPresentationForms-B", "[\\x{FE70}-\\x{FEFE}]"},
1115 {"HalfwidthandFullwidthForms", "[\\x{FF00}-\\x{FFEF}]"},
1116 {NULL, NULL}
1117 };
1118
1119 /* adjust the expression to a Perl equivalent
1120 * http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#regexs */
1121
1122 /* we need to replace all "$" with "\$", count them now */
1123 for (count = 0, ptr = strpbrk(pattern, "^$"); ptr; ++count, ptr = strpbrk(ptr + 1, "^$"));
1124
1125 perl_regex = malloc((strlen(pattern) + 4 + count) * sizeof(char));
1126 LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx->ctx), LY_EMEM);
1127 perl_regex[0] = '\0';
1128
1129 ptr = perl_regex;
1130
1131 if (strncmp(pattern + strlen(pattern) - 2, ".*", 2)) {
1132 /* we will add line-end anchoring */
1133 ptr[0] = '(';
1134 ++ptr;
1135 }
1136
1137 for (orig_ptr = pattern; orig_ptr[0]; ++orig_ptr) {
1138 if (orig_ptr[0] == '$') {
1139 ptr += sprintf(ptr, "\\$");
1140 } else if (orig_ptr[0] == '^') {
1141 ptr += sprintf(ptr, "\\^");
1142 } else {
1143 ptr[0] = orig_ptr[0];
1144 ++ptr;
1145 }
1146 }
1147
1148 if (strncmp(pattern + strlen(pattern) - 2, ".*", 2)) {
1149 ptr += sprintf(ptr, ")$");
1150 } else {
1151 ptr[0] = '\0';
1152 ++ptr;
1153 }
1154
1155 /* substitute Unicode Character Blocks with exact Character Ranges */
1156 while ((ptr = strstr(perl_regex, "\\p{Is"))) {
1157 start = ptr - perl_regex;
1158
1159 ptr = strchr(ptr, '}');
1160 if (!ptr) {
1161 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP,
1162 pattern, perl_regex + start + 2, "unterminated character property");
1163 free(perl_regex);
1164 return LY_EVALID;
1165 }
1166 end = (ptr - perl_regex) + 1;
1167
1168 /* need more space */
1169 if (end - start < URANGE_LEN) {
1170 perl_regex = ly_realloc(perl_regex, strlen(perl_regex) + (URANGE_LEN - (end - start)) + 1);
1171 LY_CHECK_ERR_RET(!perl_regex, LOGMEM(ctx->ctx); free(perl_regex), LY_EMEM);
1172 }
1173
1174 /* find our range */
1175 for (idx = 0; ublock2urange[idx][0]; ++idx) {
1176 if (!strncmp(perl_regex + start + 5, ublock2urange[idx][0], strlen(ublock2urange[idx][0]))) {
1177 break;
1178 }
1179 }
1180 if (!ublock2urange[idx][0]) {
1181 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP,
1182 pattern, perl_regex + start + 5, "unknown block name");
1183 free(perl_regex);
1184 return LY_EVALID;
1185 }
1186
1187 /* make the space in the string and replace the block (but we cannot include brackets if it was already enclosed in them) */
1188 for (idx2 = 0, count = 0; idx2 < start; ++idx2) {
1189 if ((perl_regex[idx2] == '[') && (!idx2 || (perl_regex[idx2 - 1] != '\\'))) {
1190 ++count;
1191 }
1192 if ((perl_regex[idx2] == ']') && (!idx2 || (perl_regex[idx2 - 1] != '\\'))) {
1193 --count;
1194 }
1195 }
1196 if (count) {
1197 /* skip brackets */
1198 memmove(perl_regex + start + (URANGE_LEN - 2), perl_regex + end, strlen(perl_regex + end) + 1);
1199 memcpy(perl_regex + start, ublock2urange[idx][1] + 1, URANGE_LEN - 2);
1200 } else {
1201 memmove(perl_regex + start + URANGE_LEN, perl_regex + end, strlen(perl_regex + end) + 1);
1202 memcpy(perl_regex + start, ublock2urange[idx][1], URANGE_LEN);
1203 }
1204 }
1205
1206 /* must return 0, already checked during parsing */
1207 precomp = pcre_compile(perl_regex, PCRE_UTF8 | PCRE_ANCHORED | PCRE_DOLLAR_ENDONLY | PCRE_NO_AUTO_CAPTURE,
1208 &err_msg, &err_offset, NULL);
1209 if (!precomp) {
1210 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_INREGEXP, pattern, perl_regex + err_offset, err_msg);
1211 free(perl_regex);
1212 return LY_EVALID;
1213 }
1214 free(perl_regex);
1215
1216 if (pcre_precomp) {
1217 *pcre_precomp = precomp;
1218 } else {
1219 free(precomp);
1220 }
1221
1222 return LY_SUCCESS;
1223
1224#undef URANGE_LEN
1225}
1226
1227static LY_ERR
1228lys_compile_type_patterns(struct lysc_ctx *ctx, struct lysp_restr *patterns_p, int options,
1229 struct lysc_pattern **base_patterns, struct lysc_pattern ***patterns)
1230{
1231 struct lysc_pattern **pattern;
1232 unsigned int u, v;
1233 const char *err_msg;
1234 LY_ERR ret = LY_SUCCESS;
1235
1236 /* first, copy the patterns from the base type */
1237 if (base_patterns) {
1238 *patterns = lysc_patterns_dup(ctx->ctx, base_patterns);
1239 LY_CHECK_ERR_RET(!(*patterns), LOGMEM(ctx->ctx), LY_EMEM);
1240 }
1241
1242 LY_ARRAY_FOR(patterns_p, u) {
1243 LY_ARRAY_NEW_RET(ctx->ctx, (*patterns), pattern, LY_EMEM);
1244 *pattern = calloc(1, sizeof **pattern);
1245 ++(*pattern)->refcount;
1246
1247 ret = lys_compile_type_pattern_check(ctx, &patterns_p[u].arg[1], &(*pattern)->expr);
1248 LY_CHECK_RET(ret);
1249 (*pattern)->expr_extra = pcre_study((*pattern)->expr, 0, &err_msg);
1250 if (err_msg) {
1251 LOGWRN(ctx->ctx, "Studying pattern \"%s\" failed (%s).", pattern, err_msg);
1252 }
1253
1254 if (patterns_p[u].arg[0] == 0x15) {
1255 (*pattern)->inverted = 1;
1256 }
1257 DUP_STRING(ctx->ctx, patterns_p[u].eapptag, (*pattern)->eapptag);
1258 DUP_STRING(ctx->ctx, patterns_p[u].emsg, (*pattern)->emsg);
1259 COMPILE_ARRAY_GOTO(ctx, patterns_p[u].exts, (*pattern)->exts,
1260 options, v, lys_compile_ext, ret, done);
1261 }
1262done:
1263 return ret;
1264}
1265
1266static uint16_t type_substmt_map[LY_DATA_TYPE_COUNT] = {
1267 0 /* LY_TYPE_UNKNOWN */,
1268 LYS_SET_LENGTH /* LY_TYPE_BINARY */,
1269 LYS_SET_BIT /* LY_TYPE_BITS */,
1270 0 /* LY_TYPE_BOOL */,
1271 LYS_SET_FRDIGITS | LYS_SET_RANGE /* LY_TYPE_DEC64 */,
1272 0 /* LY_TYPE_EMPTY */,
1273 LYS_SET_ENUM /* LY_TYPE_ENUM */,
1274 LYS_SET_BASE /* LY_TYPE_IDENT */,
1275 LYS_SET_REQINST /* LY_TYPE_INST */,
1276 LYS_SET_REQINST | LYS_SET_PATH /* LY_TYPE_LEAFREF */,
1277 LYS_SET_LENGTH | LYS_SET_PATTERN /* LY_TYPE_STRING */,
1278 LYS_SET_TYPE /* LY_TYPE_UNION */,
1279 LYS_SET_RANGE /* LY_TYPE_INT8 */,
1280 LYS_SET_RANGE /* LY_TYPE_UINT8 */,
1281 LYS_SET_RANGE /* LY_TYPE_INT16 */,
1282 LYS_SET_RANGE /* LY_TYPE_UINT16 */,
1283 LYS_SET_RANGE /* LY_TYPE_INT32 */,
1284 LYS_SET_RANGE /* LY_TYPE_UINT32 */,
1285 LYS_SET_RANGE /* LY_TYPE_INT64 */,
1286 LYS_SET_RANGE /* LY_TYPE_UINT64 */
1287};
1288
1289static LY_ERR
1290lys_compile_type_enums(struct lysc_ctx *ctx, struct lysp_type_enum *enums_p, LY_DATA_TYPE basetype, int options,
1291 struct lysc_type_enum_item *base_enums, struct lysc_type_enum_item **enums)
1292{
1293 LY_ERR ret = LY_SUCCESS;
1294 unsigned int u, v, match;
1295 int32_t value = 0;
1296 uint32_t position = 0;
1297 struct lysc_type_enum_item *e, storage;
1298
1299 if (base_enums && ctx->mod->compiled->version < 2) {
1300 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "%s type can be subtyped only in YANG 1.1 modules.",
1301 basetype == LY_TYPE_ENUM ? "Enumeration" : "Bits");
1302 return LY_EVALID;
1303 }
1304
1305 LY_ARRAY_FOR(enums_p, u) {
1306 LY_ARRAY_NEW_RET(ctx->ctx, *enums, e, LY_EMEM);
1307 DUP_STRING(ctx->ctx, enums_p[u].name, e->name);
1308 if (base_enums) {
1309 /* check the enum/bit presence in the base type - the set of enums/bits in the derived type must be a subset */
1310 LY_ARRAY_FOR(base_enums, v) {
1311 if (!strcmp(e->name, base_enums[v].name)) {
1312 break;
1313 }
1314 }
1315 if (v == LY_ARRAY_SIZE(base_enums)) {
1316 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1317 "Invalid %s - derived type adds new item \"%s\".",
1318 basetype == LY_TYPE_ENUM ? "enumeration" : "bits", e->name);
1319 return LY_EVALID;
1320 }
1321 match = v;
1322 }
1323
1324 if (basetype == LY_TYPE_ENUM) {
1325 if (enums_p[u].flags & LYS_SET_VALUE) {
1326 e->value = (int32_t)enums_p[u].value;
1327 if (!u || e->value >= value) {
1328 value = e->value + 1;
1329 }
1330 /* check collision with other values */
1331 for (v = 0; v < LY_ARRAY_SIZE(*enums) - 1; ++v) {
1332 if (e->value == (*enums)[v].value) {
1333 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1334 "Invalid enumeration - value %d collide in items \"%s\" and \"%s\".",
1335 e->value, e->name, (*enums)[v].name);
1336 return LY_EVALID;
1337 }
1338 }
1339 } else if (base_enums) {
1340 /* inherit the assigned value */
1341 e->value = base_enums[match].value;
1342 if (!u || e->value >= value) {
1343 value = e->value + 1;
1344 }
1345 } else {
1346 /* assign value automatically */
1347 if (u && value == INT32_MIN) {
1348 /* counter overflow */
1349 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1350 "Invalid enumeration - it is not possible to auto-assign enum value for "
1351 "\"%s\" since the highest value is already 2147483647.", e->name);
1352 return LY_EVALID;
1353 }
1354 e->value = value++;
1355 }
1356 } else { /* LY_TYPE_BITS */
1357 if (enums_p[u].flags & LYS_SET_VALUE) {
1358 e->value = (int32_t)enums_p[u].value;
1359 if (!u || (uint32_t)e->value >= position) {
1360 position = (uint32_t)e->value + 1;
1361 }
1362 /* check collision with other values */
1363 for (v = 0; v < LY_ARRAY_SIZE(*enums) - 1; ++v) {
1364 if (e->value == (*enums)[v].value) {
1365 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1366 "Invalid bits - position %u collide in items \"%s\" and \"%s\".",
1367 (uint32_t)e->value, e->name, (*enums)[v].name);
1368 return LY_EVALID;
1369 }
1370 }
1371 } else if (base_enums) {
1372 /* inherit the assigned value */
1373 e->value = base_enums[match].value;
1374 if (!u || (uint32_t)e->value >= position) {
1375 position = (uint32_t)e->value + 1;
1376 }
1377 } else {
1378 /* assign value automatically */
1379 if (u && position == 0) {
1380 /* counter overflow */
1381 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1382 "Invalid bits - it is not possible to auto-assign bit position for "
1383 "\"%s\" since the highest value is already 4294967295.", e->name);
1384 return LY_EVALID;
1385 }
1386 e->value = position++;
1387 }
1388 }
1389
1390 if (base_enums) {
1391 /* the assigned values must not change from the derived type */
1392 if (e->value != base_enums[match].value) {
1393 if (basetype == LY_TYPE_ENUM) {
1394 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1395 "Invalid enumeration - value of the item \"%s\" has changed from %d to %d in the derived type.",
1396 e->name, base_enums[match].value, e->value);
1397 } else {
1398 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1399 "Invalid bits - position of the item \"%s\" has changed from %u to %u in the derived type.",
1400 e->name, (uint32_t)base_enums[match].value, (uint32_t)e->value);
1401 }
1402 return LY_EVALID;
1403 }
1404 }
1405
1406 COMPILE_ARRAY_GOTO(ctx, enums_p[u].iffeatures, e->iffeatures, options, v, lys_compile_iffeature, ret, done);
1407 COMPILE_ARRAY_GOTO(ctx, enums_p[u].exts, e->exts, options, v, lys_compile_ext, ret, done);
1408
1409 if (basetype == LY_TYPE_BITS) {
1410 /* keep bits ordered by position */
1411 for (v = u; v && (*enums)[v - 1].value > e->value; --v);
1412 if (v != u) {
1413 memcpy(&storage, e, sizeof *e);
1414 memmove(&(*enums)[v + 1], &(*enums)[v], (u - v) * sizeof **enums);
1415 memcpy(&(*enums)[v], &storage, sizeof storage);
1416 }
1417 }
1418 }
1419
1420done:
1421 return ret;
1422}
1423
1424static LY_ERR
1425lys_compile_type(struct lysc_ctx *ctx, struct lysp_node_leaf *leaf_p, int options, struct lysc_type **type)
1426{
1427 LY_ERR ret = LY_SUCCESS;
1428 unsigned int u;
1429 struct lysp_type *type_p = &leaf_p->type;
1430 struct type_context {
1431 const struct lysp_tpdf *tpdf;
1432 struct lysp_node *node;
1433 struct lysp_module *mod;
1434 } *tctx, *tctx_prev = NULL;
1435 LY_DATA_TYPE basetype = LY_TYPE_UNKNOWN;
1436 struct lysc_type *base = NULL;
1437 struct ly_set tpdf_chain = {0};
1438 struct lysc_type_bin *bin;
1439 struct lysc_type_num *num;
1440 struct lysc_type_str *str;
1441 struct lysc_type_bits *bits;
1442 struct lysc_type_enum *enumeration;
1443
1444 (*type) = NULL;
1445
1446 tctx = calloc(1, sizeof *tctx);
1447 LY_CHECK_ERR_RET(!tctx, LOGMEM(ctx->ctx), LY_EMEM);
1448 for (ret = lysp_type_find(type_p->name, (struct lysp_node*)leaf_p, ctx->mod->parsed,
1449 &basetype, &tctx->tpdf, &tctx->node, &tctx->mod);
1450 ret == LY_SUCCESS;
1451 ret = lysp_type_find(tctx_prev->tpdf->type.name, tctx_prev->node, tctx_prev->mod,
1452 &basetype, &tctx->tpdf, &tctx->node, &tctx->mod)) {
1453 if (basetype) {
1454 break;
1455 }
1456
1457 /* check status */
1458 ret = lysc_check_status(ctx, leaf_p->flags, ctx->mod->parsed, leaf_p->name,
1459 tctx->tpdf->flags, tctx->mod, tctx->node ? tctx->node->name : tctx->mod->name);
1460 LY_CHECK_ERR_GOTO(ret, free(tctx), cleanup);
1461
1462 if (tctx->tpdf->type.compiled) {
1463 /* it is not necessary to continue, the rest of the chain was already compiled */
1464 basetype = tctx->tpdf->type.compiled->basetype;
1465 ly_set_add(&tpdf_chain, tctx, LY_SET_OPT_USEASLIST);
1466 tctx = NULL;
1467 break;
1468 }
1469
1470 /* store information for the following processing */
1471 ly_set_add(&tpdf_chain, tctx, LY_SET_OPT_USEASLIST);
1472
1473 /* prepare next loop */
1474 tctx_prev = tctx;
1475 tctx = calloc(1, sizeof *tctx);
1476 LY_CHECK_ERR_RET(!tctx, LOGMEM(ctx->ctx), LY_EMEM);
1477 }
1478 free(tctx);
1479
1480 /* allocate type according to the basetype */
1481 switch (basetype) {
1482 case LY_TYPE_BINARY:
1483 *type = calloc(1, sizeof(struct lysc_type_bin));
1484 bin = (struct lysc_type_bin*)(*type);
1485 break;
1486 case LY_TYPE_BITS:
1487 *type = calloc(1, sizeof(struct lysc_type_bits));
1488 bits = (struct lysc_type_bits*)(*type);
1489 break;
1490 case LY_TYPE_BOOL:
1491 case LY_TYPE_EMPTY:
1492 *type = calloc(1, sizeof(struct lysc_type));
1493 break;
1494 case LY_TYPE_DEC64:
1495 *type = calloc(1, sizeof(struct lysc_type_dec));
1496 break;
1497 case LY_TYPE_ENUM:
1498 *type = calloc(1, sizeof(struct lysc_type_enum));
1499 enumeration = (struct lysc_type_enum*)(*type);
1500 break;
1501 case LY_TYPE_IDENT:
1502 *type = calloc(1, sizeof(struct lysc_type_identityref));
1503 break;
1504 case LY_TYPE_INST:
1505 *type = calloc(1, sizeof(struct lysc_type_instanceid));
1506 break;
1507 case LY_TYPE_LEAFREF:
1508 *type = calloc(1, sizeof(struct lysc_type_leafref));
1509 break;
1510 case LY_TYPE_STRING:
1511 *type = calloc(1, sizeof(struct lysc_type_str));
1512 str = (struct lysc_type_str*)(*type);
1513 break;
1514 case LY_TYPE_UNION:
1515 *type = calloc(1, sizeof(struct lysc_type_union));
1516 break;
1517 case LY_TYPE_INT8:
1518 case LY_TYPE_UINT8:
1519 case LY_TYPE_INT16:
1520 case LY_TYPE_UINT16:
1521 case LY_TYPE_INT32:
1522 case LY_TYPE_UINT32:
1523 case LY_TYPE_INT64:
1524 case LY_TYPE_UINT64:
1525 *type = calloc(1, sizeof(struct lysc_type_num));
1526 num = (struct lysc_type_num*)(*type);
1527 break;
1528 case LY_TYPE_UNKNOWN:
1529 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
1530 "Referenced type \"%s\" not found.", tctx_prev ? tctx_prev->tpdf->type.name : type_p->name);
1531 ret = LY_EVALID;
1532 goto cleanup;
1533 }
1534 LY_CHECK_ERR_GOTO(!(*type), LOGMEM(ctx->ctx), cleanup);
1535 if (~type_substmt_map[basetype] & leaf_p->type.flags) {
1536 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid type restrictions for %s type.",
1537 ly_data_type2str[basetype]);
1538 free(*type);
1539 (*type) = NULL;
1540 ret = LY_EVALID;
1541 goto cleanup;
1542 }
1543
1544 /* get restrictions from the referred typedefs */
1545 for (u = tpdf_chain.count - 1; u + 1 > 0; --u) {
1546 tctx = (struct type_context*)tpdf_chain.objs[u];
1547 if (~type_substmt_map[basetype] & tctx->tpdf->type.flags) {
1548 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid type \"%s\" restriction(s) for %s type.",
1549 tctx->tpdf->name, ly_data_type2str[basetype]);
1550 ret = LY_EVALID;
1551 goto cleanup;
1552 } else if (tctx->tpdf->type.compiled) {
1553 base = tctx->tpdf->type.compiled;
1554 continue;
1555 } else if ((u != tpdf_chain.count - 1) && !(tctx->tpdf->type.flags)) {
1556 /* no change, just use the type information from the base */
1557 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = ((struct type_context*)tpdf_chain.objs[u + 1])->tpdf->type.compiled;
1558 ++base->refcount;
1559 continue;
1560 }
1561
1562 ++(*type)->refcount;
1563 (*type)->basetype = basetype;
1564 switch (basetype) {
1565 case LY_TYPE_BINARY:
1566 /* RFC 6020 9.8.1, 9.4.4 - length, number of octets it contains */
1567 if (tctx->tpdf->type.length) {
1568 ret = lys_compile_type_range(ctx, tctx->tpdf->type.length, basetype, 1,
1569 base ? ((struct lysc_type_bin*)base)->length : NULL, &bin->length);
1570 LY_CHECK_GOTO(ret, cleanup);
1571 }
1572
1573 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1574 *type = calloc(1, sizeof(struct lysc_type_bin));
1575 bin = (struct lysc_type_bin*)(*type);
1576 break;
1577 case LY_TYPE_BITS:
1578 /* RFC 6020 9.6 - enum */
1579 if (tctx->tpdf->type.bits) {
1580 ret = lys_compile_type_enums(ctx, tctx->tpdf->type.bits, basetype, options,
1581 base ? (struct lysc_type_enum_item*)((struct lysc_type_bits*)base)->bits : NULL,
1582 (struct lysc_type_enum_item**)&bits->bits);
1583 LY_CHECK_GOTO(ret, cleanup);
1584 }
1585
1586 if ((u == tpdf_chain.count - 1) && !(tctx->tpdf->type.flags)) {
1587 /* type derived from bits built-in type must contain at least one bit */
1588 if (!bits->bits) {
1589 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1590 "Missing bit substatement for bits type \"%s\".", tctx->tpdf->name);
1591 ret = LY_EVALID;
1592 goto cleanup;
1593 }
1594 }
1595
1596 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1597 *type = calloc(1, sizeof(struct lysc_type_bits));
1598 bits = (struct lysc_type_bits*)(*type);
1599 break;
1600 case LY_TYPE_STRING:
1601 /* RFC 6020 9.4.4 - length */
1602 if (tctx->tpdf->type.length) {
1603 ret = lys_compile_type_range(ctx, tctx->tpdf->type.length, basetype, 1,
1604 base ? ((struct lysc_type_str*)base)->length : NULL, &str->length);
1605 LY_CHECK_GOTO(ret, cleanup);
1606 } else if (base && ((struct lysc_type_str*)base)->length) {
1607 str->length = lysc_range_dup(ctx->ctx, ((struct lysc_type_str*)base)->length);
1608 }
1609
1610 /* RFC 6020 9.4.6 - pattern */
1611 if (tctx->tpdf->type.patterns) {
1612 ret = lys_compile_type_patterns(ctx, tctx->tpdf->type.patterns, options,
1613 base ? ((struct lysc_type_str*)base)->patterns : NULL, &str->patterns);
1614 LY_CHECK_GOTO(ret, cleanup);
1615 } else if (base && ((struct lysc_type_str*)base)->patterns) {
1616 str->patterns = lysc_patterns_dup(ctx->ctx, ((struct lysc_type_str*)base)->patterns);
1617 }
1618
1619 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1620 *type = calloc(1, sizeof(struct lysc_type_str));
1621 str = (struct lysc_type_str*)(*type);
1622 break;
1623 case LY_TYPE_ENUM:
1624 /* RFC 6020 9.6 - enum */
1625 if (tctx->tpdf->type.enums) {
1626 ret = lys_compile_type_enums(ctx, tctx->tpdf->type.enums, basetype, options,
1627 base ? ((struct lysc_type_enum*)base)->enums : NULL, &enumeration->enums);
1628 LY_CHECK_GOTO(ret, cleanup);
1629 }
1630
1631 if ((u == tpdf_chain.count - 1) && !(tctx->tpdf->type.flags)) {
1632 /* type derived from enumerations built-in type must contain at least one enum */
1633 if (!enumeration->enums) {
1634 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1635 "Missing enum substatement for enumeration type \"%s\".", tctx->tpdf->name);
1636 ret = LY_EVALID;
1637 goto cleanup;
1638 }
1639 }
1640
1641 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1642 *type = calloc(1, sizeof(struct lysc_type_enum));
1643 enumeration = (struct lysc_type_enum*)(*type);
1644 break;
1645 case LY_TYPE_INT8:
1646 case LY_TYPE_UINT8:
1647 case LY_TYPE_INT16:
1648 case LY_TYPE_UINT16:
1649 case LY_TYPE_INT32:
1650 case LY_TYPE_UINT32:
1651 case LY_TYPE_INT64:
1652 case LY_TYPE_UINT64:
1653 /* RFC 6020 9.2.4 - range */
1654 if (tctx->tpdf->type.range) {
1655 ret = lys_compile_type_range(ctx, tctx->tpdf->type.range, basetype, 1,
1656 base ? ((struct lysc_type_num*)base)->range : NULL, &num->range);
1657 LY_CHECK_GOTO(ret, cleanup);
1658 }
1659
1660 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1661 *type = calloc(1, sizeof(struct lysc_type_num));
1662 num = (struct lysc_type_num*)(*type);
1663 break;
1664 case LY_TYPE_BOOL:
1665 case LY_TYPE_EMPTY:
1666 case LY_TYPE_UNKNOWN: /* just to complete switch */
1667 base = ((struct lysp_tpdf*)tctx->tpdf)->type.compiled = *type;
1668 *type = calloc(1, sizeof(struct lysc_type));
1669 break;
1670 }
1671 LY_CHECK_ERR_GOTO(!(*type), LOGMEM(ctx->ctx); ret = LY_EMEM, cleanup);
1672
1673 }
1674
1675 if (leaf_p->type.flags) {
1676 /* get restrictions from the node itself, finalize the type structure */
1677 (*type)->basetype = basetype;
1678 ++(*type)->refcount;
1679 switch (basetype) {
1680 case LY_TYPE_BINARY:
1681 if (leaf_p->type.length) {
1682 ret = lys_compile_type_range(ctx, leaf_p->type.length, basetype, 1,
1683 base ? ((struct lysc_type_bin*)base)->length : NULL, &bin->length);
1684 LY_CHECK_GOTO(ret, cleanup);
1685 COMPILE_ARRAY_GOTO(ctx, leaf_p->type.length->exts, bin->length->exts,
1686 options, u, lys_compile_ext, ret, cleanup);
1687 }
1688 break;
1689 case LY_TYPE_BITS:
1690 if (leaf_p->type.bits) {
1691 ret = lys_compile_type_enums(ctx, leaf_p->type.bits, basetype, options,
1692 base ? (struct lysc_type_enum_item*)((struct lysc_type_bits*)base)->bits : NULL,
1693 (struct lysc_type_enum_item**)&bits->bits);
1694 LY_CHECK_GOTO(ret, cleanup);
1695 }
1696 break;
1697 case LY_TYPE_STRING:
1698 if (leaf_p->type.length) {
1699 ret = lys_compile_type_range(ctx, leaf_p->type.length, basetype, 1,
1700 base ? ((struct lysc_type_str*)base)->length : NULL, &str->length);
1701 LY_CHECK_GOTO(ret, cleanup);
1702 COMPILE_ARRAY_GOTO(ctx, leaf_p->type.length->exts, str->length->exts,
1703 options, u, lys_compile_ext, ret, cleanup);
1704 } else if (base && ((struct lysc_type_str*)base)->length) {
1705 str->length = lysc_range_dup(ctx->ctx, ((struct lysc_type_str*)base)->length);
1706 }
1707
1708 if (leaf_p->type.patterns) {
1709 ret = lys_compile_type_patterns(ctx, leaf_p->type.patterns, options,
1710 base ? ((struct lysc_type_str*)base)->patterns : NULL, &str->patterns);
1711 LY_CHECK_GOTO(ret, cleanup);
1712 } else if (base && ((struct lysc_type_str*)base)->patterns) {
1713 str->patterns = lysc_patterns_dup(ctx->ctx, ((struct lysc_type_str*)base)->patterns);
1714 }
1715 break;
1716 case LY_TYPE_ENUM:
1717 if (leaf_p->type.enums) {
1718 ret = lys_compile_type_enums(ctx, leaf_p->type.enums, basetype, options,
1719 base ? ((struct lysc_type_enum*)base)->enums : NULL, &enumeration->enums);
1720 LY_CHECK_GOTO(ret, cleanup);
1721 }
1722 break;
1723 case LY_TYPE_INT8:
1724 case LY_TYPE_UINT8:
1725 case LY_TYPE_INT16:
1726 case LY_TYPE_UINT16:
1727 case LY_TYPE_INT32:
1728 case LY_TYPE_UINT32:
1729 case LY_TYPE_INT64:
1730 case LY_TYPE_UINT64:
1731 if (leaf_p->type.range) {
1732 ret = lys_compile_type_range(ctx, leaf_p->type.range, basetype, 0,
1733 base ? ((struct lysc_type_num*)base)->range : NULL, &num->range);
1734 LY_CHECK_GOTO(ret, cleanup);
1735 COMPILE_ARRAY_GOTO(ctx, leaf_p->type.range->exts, num->range->exts,
1736 options, u, lys_compile_ext, ret, cleanup);
1737 }
1738 break;
1739 case LY_TYPE_BOOL:
1740 case LY_TYPE_EMPTY:
1741 case LY_TYPE_UNKNOWN: /* just to complete switch */
1742 /* nothing to do */
1743 break;
1744 }
1745 } else if (base) {
1746 /* no specific restriction in leaf's type definition, copy from the base */
1747 free(*type);
1748 (*type) = base;
1749 ++(*type)->refcount;
1750 } else {
1751 /* there are some limitations on types derived directly from built-in types */
1752 if (basetype == LY_TYPE_BITS) {
1753 if (!bits->bits) {
1754 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1755 "Missing bit substatement for bits type.");
1756 free(*type);
1757 *type = NULL;
1758 ret = LY_EVALID;
1759 goto cleanup;
1760 }
1761 } else if (basetype == LY_TYPE_ENUM) {
1762 if (!enumeration->enums) {
1763 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
1764 "Missing enum substatement for enumeration type.");
1765 free(*type);
1766 *type = NULL;
1767 ret = LY_EVALID;
1768 goto cleanup;
1769 }
1770 }
1771 }
1772
1773 COMPILE_ARRAY_GOTO(ctx, type_p->exts, (*type)->exts, options, u, lys_compile_ext, ret, cleanup);
1774
1775cleanup:
1776 ly_set_erase(&tpdf_chain, free);
1777 return ret;
1778}
1779
1780static LY_ERR lys_compile_node(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *parent);
1781
1782static LY_ERR
1783lys_compile_node_container(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *node)
1784{
1785 struct lysp_node_container *cont_p = (struct lysp_node_container*)node_p;
1786 struct lysc_node_container *cont = (struct lysc_node_container*)node;
1787 struct lysp_node *child_p;
1788 unsigned int u;
1789 LY_ERR ret = LY_SUCCESS;
1790
1791 COMPILE_MEMBER_GOTO(ctx, cont_p->when, cont->when, options, lys_compile_when, ret, done);
1792 COMPILE_ARRAY_GOTO(ctx, cont_p->iffeatures, cont->iffeatures, options, u, lys_compile_iffeature, ret, done);
1793
1794 LY_LIST_FOR(cont_p->child, child_p) {
1795 LY_CHECK_RET(lys_compile_node(ctx, child_p, options, node));
1796 }
1797
1798 COMPILE_ARRAY_GOTO(ctx, cont_p->musts, cont->musts, options, u, lys_compile_must, ret, done);
1799 //COMPILE_ARRAY_GOTO(ctx, cont_p->actions, cont->actions, options, u, lys_compile_action, ret, done);
1800 //COMPILE_ARRAY_GOTO(ctx, cont_p->notifs, cont->notifs, options, u, lys_compile_notif, ret, done);
1801
1802done:
1803 return ret;
1804}
1805
1806static LY_ERR
1807lys_compile_node_leaf(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *node)
1808{
1809 struct lysp_node_leaf *leaf_p = (struct lysp_node_leaf*)node_p;
1810 struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)node;
1811 unsigned int u;
1812 LY_ERR ret = LY_SUCCESS;
1813
1814 COMPILE_MEMBER_GOTO(ctx, leaf_p->when, leaf->when, options, lys_compile_when, ret, done);
1815 COMPILE_ARRAY_GOTO(ctx, leaf_p->iffeatures, leaf->iffeatures, options, u, lys_compile_iffeature, ret, done);
1816
1817 COMPILE_ARRAY_GOTO(ctx, leaf_p->musts, leaf->musts, options, u, lys_compile_must, ret, done);
1818 ret = lys_compile_type(ctx, leaf_p, options, &leaf->type);
1819 LY_CHECK_GOTO(ret, done);
1820
1821 DUP_STRING(ctx->ctx, leaf_p->units, leaf->units);
1822 DUP_STRING(ctx->ctx, leaf_p->dflt, leaf->dflt);
1823done:
1824 return ret;
1825}
1826
1827static LY_ERR
1828lys_compile_node(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *parent)
1829{
1830 LY_ERR ret = LY_EVALID;
1831 struct lysc_node *node, **children;
1832 unsigned int u;
1833 LY_ERR (*node_compile_spec)(struct lysc_ctx*, struct lysp_node*, int, struct lysc_node*);
1834
1835 switch (node_p->nodetype) {
1836 case LYS_CONTAINER:
1837 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_container));
1838 node_compile_spec = lys_compile_node_container;
1839 break;
1840 case LYS_LEAF:
1841 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_leaf));
1842 node_compile_spec = lys_compile_node_leaf;
1843 break;
1844 case LYS_LIST:
1845 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_list));
1846 break;
1847 case LYS_LEAFLIST:
1848 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_leaflist));
1849 break;
1850 case LYS_CASE:
1851 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_case));
1852 break;
1853 case LYS_CHOICE:
1854 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_choice));
1855 break;
1856 case LYS_USES:
1857 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_uses));
1858 break;
1859 case LYS_ANYXML:
1860 case LYS_ANYDATA:
1861 node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_anydata));
1862 break;
1863 default:
1864 LOGINT(ctx->ctx);
1865 return LY_EINT;
1866 }
1867 LY_CHECK_ERR_RET(!node, LOGMEM(ctx->ctx), LY_EMEM);
1868 node->nodetype = node_p->nodetype;
1869 node->module = ctx->mod;
1870 node->prev = node;
1871 node->flags = node_p->flags;
1872
1873 /* config */
1874 if (!(node->flags & LYS_CONFIG_MASK)) {
1875 /* config not explicitely set, inherit it from parent */
1876 if (parent) {
1877 node->flags |= parent->flags & LYS_CONFIG_MASK;
1878 } else {
1879 /* default is config true */
1880 node->flags |= LYS_CONFIG_W;
1881 }
1882 }
1883
1884 /* status - it is not inherited by specification, but it does not make sense to have
1885 * current in deprecated or deprecated in obsolete, so we do print warning and inherit status */
1886 if (!(node->flags & LYS_STATUS_MASK)) {
1887 if (parent && (parent->flags & (LYS_STATUS_DEPRC | LYS_STATUS_OBSLT))) {
1888 LOGWRN(ctx->ctx, "Missing explicit \"%s\" status that was already specified in parent, inheriting.",
1889 (parent->flags & LYS_STATUS_DEPRC) ? "deprecated" : "obsolete");
1890 node->flags |= parent->flags & LYS_STATUS_MASK;
1891 } else {
1892 node->flags |= LYS_STATUS_CURR;
1893 }
1894 } else if (parent) {
1895 /* check status compatibility with the parent */
1896 if ((parent->flags & LYS_STATUS_MASK) > (node->flags & LYS_STATUS_MASK)) {
1897 if (node->flags & LYS_STATUS_CURR) {
1898 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
1899 "A \"current\" status is in conflict with the parent's \"%s\" status.",
1900 (parent->flags & LYS_STATUS_DEPRC) ? "deprecated" : "obsolete");
1901 } else { /* LYS_STATUS_DEPRC */
1902 LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
1903 "A \"deprecated\" status is in conflict with the parent's \"obsolete\" status.");
1904 }
1905 goto error;
1906 }
1907 }
1908
1909 if (!(options & LYSC_OPT_FREE_SP)) {
1910 node->sp = node_p;
1911 }
1912 DUP_STRING(ctx->ctx, node_p->name, node->name);
1913 COMPILE_ARRAY_GOTO(ctx, node_p->exts, node->exts, options, u, lys_compile_ext, ret, error);
1914
1915 /* nodetype-specific part */
1916 LY_CHECK_GOTO(node_compile_spec(ctx, node_p, options, node), error);
1917
1918 /* insert into parent's children */
1919 if (parent && (children = lysc_node_children(parent))) {
1920 if (!(*children)) {
1921 /* first child */
1922 *children = node;
1923 } else {
1924 /* insert at the end of the parent's children list */
1925 (*children)->prev->next = node;
1926 node->prev = (*children)->prev;
1927 (*children)->prev = node;
1928 }
1929 } else {
1930 /* top-level element */
1931 if (!ctx->mod->compiled->data) {
1932 ctx->mod->compiled->data = node;
1933 } else {
1934 /* insert at the end of the module's top-level nodes list */
1935 ctx->mod->compiled->data->prev->next = node;
1936 node->prev = ctx->mod->compiled->data->prev;
1937 ctx->mod->compiled->data->prev = node;
1938 }
1939 }
1940
1941 return LY_SUCCESS;
1942
1943error:
1944 lysc_node_free(ctx->ctx, node);
1945 return ret;
1946}
1947
1948LY_ERR
1949lys_compile(struct lys_module *mod, int options)
1950{
1951 struct lysc_ctx ctx = {0};
1952 struct lysc_module *mod_c;
1953 struct lysp_module *sp;
1954 struct lysp_node *node_p;
1955 unsigned int u;
1956 LY_ERR ret;
1957
1958 LY_CHECK_ARG_RET(NULL, mod, mod->parsed, mod->parsed->ctx, LY_EINVAL);
1959 sp = mod->parsed;
1960
1961 if (sp->submodule) {
1962 LOGERR(sp->ctx, LY_EINVAL, "Submodules (%s) are not supposed to be compiled, compile only the main modules.", sp->name);
1963 return LY_EINVAL;
1964 }
1965
1966 ctx.ctx = sp->ctx;
1967 ctx.mod = mod;
1968
1969 mod->compiled = mod_c = calloc(1, sizeof *mod_c);
1970 LY_CHECK_ERR_RET(!mod_c, LOGMEM(sp->ctx), LY_EMEM);
1971 mod_c->ctx = sp->ctx;
1972 mod_c->implemented = sp->implemented;
1973 mod_c->latest_revision = sp->latest_revision;
1974 mod_c->version = sp->version;
1975
1976 DUP_STRING(sp->ctx, sp->name, mod_c->name);
1977 DUP_STRING(sp->ctx, sp->ns, mod_c->ns);
1978 DUP_STRING(sp->ctx, sp->prefix, mod_c->prefix);
1979 if (sp->revs) {
1980 DUP_STRING(sp->ctx, sp->revs[0].date, mod_c->revision);
1981 }
1982 COMPILE_ARRAY_GOTO(&ctx, sp->imports, mod_c->imports, options, u, lys_compile_import, ret, error);
1983 COMPILE_ARRAY_GOTO(&ctx, sp->features, mod_c->features, options, u, lys_compile_feature, ret, error);
1984 COMPILE_ARRAY_GOTO(&ctx, sp->identities, mod_c->identities, options, u, lys_compile_identity, ret, error);
1985 if (sp->identities) {
1986 LY_CHECK_RET(lys_compile_identities_derived(&ctx, sp->identities, mod_c->identities));
1987 }
1988
1989 LY_LIST_FOR(sp->data, node_p) {
1990 ret = lys_compile_node(&ctx, node_p, options, NULL);
1991 LY_CHECK_GOTO(ret, error);
1992 }
1993 //COMPILE_ARRAY_GOTO(ctx, sp->rpcs, mod_c->rpcs, options, u, lys_compile_action, ret, error);
1994 //COMPILE_ARRAY_GOTO(ctx, sp->notifs, mod_c->notifs, options, u, lys_compile_notif, ret, error);
1995
1996 COMPILE_ARRAY_GOTO(&ctx, sp->exts, mod_c->exts, options, u, lys_compile_ext, ret, error);
1997
1998 if (options & LYSC_OPT_FREE_SP) {
1999 lysp_module_free(mod->parsed);
2000 ((struct lys_module*)mod)->parsed = NULL;
2001 }
2002
2003 ((struct lys_module*)mod)->compiled = mod_c;
2004 return LY_SUCCESS;
2005
2006error:
2007 lysc_module_free(mod_c, NULL);
2008 ((struct lys_module*)mod)->compiled = NULL;
2009 return ret;
2010}