schema compilation CHANGE partial support for types
- resolving types
- support for binary type
- support for range/length restriction of the type, but missing checking
that the derived type strictly narrows the defined range/length
diff --git a/src/common.c b/src/common.c
index dab8288..f21c97c 100644
--- a/src/common.c
+++ b/src/common.c
@@ -303,3 +303,59 @@
}
return LY_SUCCESS;
}
+
+LY_ERR
+ly_parse_int(const char *val_str, int64_t min, int64_t max, int base, int64_t *ret)
+{
+ char *strptr;
+
+ LY_CHECK_ARG_RET(NULL, val_str, val_str[0], LY_EINVAL);
+
+ /* convert to 64-bit integer, all the redundant characters are handled */
+ errno = 0;
+ strptr = NULL;
+
+ /* parse the value */
+ *ret = strtoll(val_str, &strptr, base);
+ if (errno) {
+ return LY_EVALID;
+ } else if ((*ret < min) || (*ret > max)) {
+ return LY_EDENIED;
+ } else if (strptr && *strptr) {
+ while (isspace(*strptr)) {
+ ++strptr;
+ }
+ if (*strptr) {
+ return LY_EVALID;
+ }
+ }
+ return LY_SUCCESS;
+}
+
+LY_ERR
+ly_parse_uint(const char *val_str, uint64_t max, int base, uint64_t *ret)
+{
+ char *strptr;
+ uint64_t u;
+
+ LY_CHECK_ARG_RET(NULL, val_str, val_str[0], LY_EINVAL);
+
+ errno = 0;
+ strptr = NULL;
+ u = strtoull(val_str, &strptr, base);
+ if (errno) {
+ return LY_EVALID;
+ } else if ((u > max) || (u && val_str[0] == '-')) {
+ return LY_EDENIED;
+ } else if (strptr && *strptr) {
+ while (isspace(*strptr)) {
+ ++strptr;
+ }
+ if (*strptr) {
+ return LY_EVALID;
+ }
+ }
+
+ *ret = u;
+ return LY_SUCCESS;
+}
diff --git a/src/common.h b/src/common.h
index ca1c29d..cd42451 100644
--- a/src/common.h
+++ b/src/common.h
@@ -294,6 +294,39 @@
LY_ERR ly_getutf8(const char **input, unsigned int *utf8_char, size_t *bytes_read);
/**
+ * @brief Parse signed integer with possible limitation.
+ * @param[in] val_str String value containing signed integer, note that
+ * nothing else than whitespaces are expected after the value itself.
+ * @param[in] min Limitation for the value which must not be lower than min.
+ * @param[in] max Limitation for the value which must not be higher than max.
+ * @param[in] base Numeric base for parsing:
+ * 0 - to accept decimal, octal, hexadecimal (e.g. in default value)
+ * 10 - to accept only decimal (e.g. data instance value)
+ * @param[out] ret Resulting value.
+ * @return LY_ERR value:
+ * LY_EDENIED - the value breaks the limits,
+ * LY_EVALID - string contains invalid value,
+ * LY_SUCCESS - successful parsing.
+ */
+LY_ERR ly_parse_int(const char *val_str, int64_t min, int64_t max, int base, int64_t *ret);
+
+/**
+ * @brief Parse unsigned integer with possible limitation.
+ * @param[in] val_str String value containing unsigned integer, note that
+ * nothing else than whitespaces are expected after the value itself.
+ * @param[in] max Limitation for the value which must not be higher than max.
+ * @param[in] base Numeric base for parsing:
+ * 0 - to accept decimal, octal, hexadecimal (e.g. in default value)
+ * 10 - to accept only decimal (e.g. data instance value)
+ * @param[out] ret Resulting value.
+ * @return LY_ERR value:
+ * LY_EDENIED - the value breaks the limits,
+ * LY_EVALID - string contains invalid value,
+ * LY_SUCCESS - successful parsing.
+ */
+LY_ERR ly_parse_uint(const char *val_str, uint64_t max, int base, uint64_t *ret);
+
+/**
* @brief mmap(2) wrapper to map input files into memory to unify parsing.
*
* The address space is allocate only for reading.
@@ -340,6 +373,31 @@
memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
/**
+ * @brief (Re-)Allocation of a ([sized array](@ref sizedarrays)).
+ *
+ * Increases the size information.
+ *
+ * @param[in] CTX libyang context for logging.
+ * @param[in,out] ARRAY Pointer to the array to allocate/resize. The size of the allocated
+ * space is counted from the type of the ARRAY, so do not provide placeholder void pointers.
+ * @param[out] NEW_ITEM Returning pointer to the newly allocated record in the ARRAY.
+ * @param[out] RET Variable to store error code.
+ * @param[in] GOTO Label to go in case of error (memory allocation failure).
+ */
+#define LY_ARRAY_NEW_GOTO(CTX, ARRAY, NEW_ITEM, RET, GOTO) \
+ if (!(ARRAY)) { \
+ ARRAY = malloc(sizeof(uint32_t) + sizeof *(ARRAY)); \
+ *((uint32_t*)(ARRAY)) = 1; \
+ } else { \
+ ++(*((uint32_t*)(ARRAY) - 1)); \
+ ARRAY = ly_realloc(((uint32_t*)(ARRAY) - 1), sizeof(uint32_t) + (*((uint32_t*)(ARRAY) - 1) * sizeof *(ARRAY))); \
+ LY_CHECK_ERR_GOTO(!(ARRAY), LOGMEM(CTX); RET = LY_EMEM, GOTO); \
+ } \
+ ARRAY = (void*)((uint32_t*)(ARRAY) + 1); \
+ (NEW_ITEM) = &(ARRAY)[*((uint32_t*)(ARRAY) - 1) - 1]; \
+ memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
+
+/**
* @brief Allocate a ([sized array](@ref sizedarrays)) for the specified number of items.
*
* Does not set the size information, it is supposed to be incremented via ::LY_ARRAY_INCREMENT
diff --git a/src/parser_yang.c b/src/parser_yang.c
index f755d29..e9878f8 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -2231,6 +2231,10 @@
LOGVAL_YANG(ctx, LY_VCODE_INCHILDSTMT, ly_stmt2str(kw), "when");
return LY_EVALID;
}
+
+ if (kw != YANG_CUSTOM) {
+ type->flags |= LYS_TYPE_MODIFIED;
+ }
}
return ret;
}
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 7301326..5daa7a4 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -28,11 +28,12 @@
#include "libyang.h"
#include "context.h"
#include "tree_schema_internal.h"
+#include "xpath.h"
-#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, &ARRAY[c__], dict);}LY_ARRAY_FREE(ARRAY);}
-#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER, dict);free(MEMBER);}
-#define FREE_STRING(CTX, STRING, DICT) if (DICT && STRING) {lydict_remove(CTX, STRING);}
-#define FREE_STRINGS(CTX, ARRAY, DICT) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__], DICT);}LY_ARRAY_FREE(ARRAY);}
+#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, &ARRAY[c__]);}LY_ARRAY_FREE(ARRAY);}
+#define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER);free(MEMBER);}
+#define FREE_STRING(CTX, STRING) if (STRING) {lydict_remove(CTX, STRING);}
+#define FREE_STRINGS(CTX, ARRAY) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__]);}LY_ARRAY_FREE(ARRAY);}
#define COMPILE_ARRAY_GOTO(CTX, ARRAY_P, ARRAY_C, OPTIONS, ITER, FUNC, RET, GOTO) \
if (ARRAY_P) { \
@@ -44,158 +45,157 @@
} \
}
-static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp, int dict);
-static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node, int dict);
+#define COMPILE_MEMBER_GOTO(CTX, MEMBER_P, MEMBER_C, OPTIONS, FUNC, RET, GOTO) \
+ if (MEMBER_P) { \
+ MEMBER_C = calloc(1, sizeof *(MEMBER_C)); \
+ LY_CHECK_ERR_GOTO(!(MEMBER_C), LOGMEM((CTX)->ctx); RET = LY_EMEM, GOTO); \
+ RET = FUNC(CTX, MEMBER_P, OPTIONS, MEMBER_C); \
+ LY_CHECK_GOTO(RET != LY_SUCCESS, GOTO); \
+ }
-#define LYSC_CTX_BUFSIZE 4078
-struct lysc_ctx {
- struct ly_ctx *ctx;
- struct lys_module *mod;
- uint16_t path_len;
- char path[LYSC_CTX_BUFSIZE];
-};
+static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
+static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
static void
-lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt, int dict)
+lysp_stmt_free(struct ly_ctx *ctx, struct lysp_stmt *stmt)
{
struct lysp_stmt *child, *next;
- FREE_STRING(ctx, stmt->stmt, dict);
- FREE_STRING(ctx, stmt->arg, dict);
+ FREE_STRING(ctx, stmt->stmt);
+ FREE_STRING(ctx, stmt->arg);
LY_LIST_FOR_SAFE(stmt->child, next, child) {
- lysp_stmt_free(ctx, child, dict);
+ lysp_stmt_free(ctx, child);
}
free(stmt);
}
static void
-lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext, int dict)
+lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext)
{
struct lysp_stmt *stmt, *next;
- FREE_STRING(ctx, ext->name, dict);
- FREE_STRING(ctx, ext->argument, dict);
+ FREE_STRING(ctx, ext->name);
+ FREE_STRING(ctx, ext->argument);
LY_LIST_FOR_SAFE(ext->child, next, stmt) {
- lysp_stmt_free(ctx, stmt, dict);
+ lysp_stmt_free(ctx, stmt);
}
}
static void
-lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import, int dict)
+lysp_import_free(struct ly_ctx *ctx, struct lysp_import *import)
{
/* imported module is freed directly from the context's list */
- FREE_STRING(ctx, import->name, dict);
- FREE_STRING(ctx, import->prefix, dict);
- FREE_STRING(ctx, import->dsc, dict);
- FREE_STRING(ctx, import->ref, dict);
+ FREE_STRING(ctx, import->name);
+ FREE_STRING(ctx, import->prefix);
+ FREE_STRING(ctx, import->dsc);
+ FREE_STRING(ctx, import->ref);
FREE_ARRAY(ctx, import->exts, lysp_ext_instance_free);
}
static void
-lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include, int dict)
+lysp_include_free(struct ly_ctx *ctx, struct lysp_include *include)
{
if (include->submodule) {
lysp_module_free(include->submodule);
}
- dict = 1; /* includes not present in compiled tree, so the data are not reused there in anyway */
- FREE_STRING(ctx, include->name, dict);
- FREE_STRING(ctx, include->dsc, dict);
- FREE_STRING(ctx, include->ref, dict);
+ FREE_STRING(ctx, include->name);
+ FREE_STRING(ctx, include->dsc);
+ FREE_STRING(ctx, include->ref);
FREE_ARRAY(ctx, include->exts, lysp_ext_instance_free);
}
static void
-lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev, int dict)
+lysp_revision_free(struct ly_ctx *ctx, struct lysp_revision *rev)
{
- FREE_STRING(ctx, rev->dsc, dict);
- FREE_STRING(ctx, rev->ref, dict);
+ FREE_STRING(ctx, rev->dsc);
+ FREE_STRING(ctx, rev->ref);
FREE_ARRAY(ctx, rev->exts, lysp_ext_instance_free);
}
static void
-lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext, int dict)
+lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext)
{
- FREE_STRING(ctx, ext->name, dict);
- FREE_STRING(ctx, ext->argument, dict);
- FREE_STRING(ctx, ext->dsc, dict);
- FREE_STRING(ctx, ext->ref, dict);
+ FREE_STRING(ctx, ext->name);
+ FREE_STRING(ctx, ext->argument);
+ FREE_STRING(ctx, ext->dsc);
+ FREE_STRING(ctx, ext->ref);
FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
}
static void
-lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat, int dict)
+lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat)
{
- FREE_STRING(ctx, feat->name, dict);
- FREE_STRINGS(ctx, feat->iffeatures, 1);
- FREE_STRING(ctx, feat->dsc, dict);
- FREE_STRING(ctx, feat->ref, dict);
+ FREE_STRING(ctx, feat->name);
+ FREE_STRINGS(ctx, feat->iffeatures);
+ FREE_STRING(ctx, feat->dsc);
+ FREE_STRING(ctx, feat->ref);
FREE_ARRAY(ctx, feat->exts, lysp_ext_instance_free);
}
static void
-lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident, int dict)
+lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident)
{
- FREE_STRING(ctx, ident->name, dict);
- FREE_STRINGS(ctx, ident->iffeatures, 1);
- FREE_STRINGS(ctx, ident->bases, dict);
- FREE_STRING(ctx, ident->dsc, dict);
- FREE_STRING(ctx, ident->ref, dict);
+ FREE_STRING(ctx, ident->name);
+ FREE_STRINGS(ctx, ident->iffeatures);
+ FREE_STRINGS(ctx, ident->bases);
+ FREE_STRING(ctx, ident->dsc);
+ FREE_STRING(ctx, ident->ref);
FREE_ARRAY(ctx, ident->exts, lysp_ext_instance_free);
}
static void
-lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr, int dict)
+lysp_restr_free(struct ly_ctx *ctx, struct lysp_restr *restr)
{
- FREE_STRING(ctx, restr->arg, dict);
- FREE_STRING(ctx, restr->emsg, dict);
- FREE_STRING(ctx, restr->eapptag, dict);
- FREE_STRING(ctx, restr->dsc, dict);
- FREE_STRING(ctx, restr->ref, dict);
+ FREE_STRING(ctx, restr->arg);
+ FREE_STRING(ctx, restr->emsg);
+ FREE_STRING(ctx, restr->eapptag);
+ FREE_STRING(ctx, restr->dsc);
+ FREE_STRING(ctx, restr->ref);
FREE_ARRAY(ctx, restr->exts, lysp_ext_instance_free);
}
static void
-lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item, int dict)
+lysp_type_enum_free(struct ly_ctx *ctx, struct lysp_type_enum *item)
{
- FREE_STRING(ctx, item->name, dict);
- FREE_STRING(ctx, item->dsc, dict);
- FREE_STRING(ctx, item->ref, dict);
- FREE_STRINGS(ctx, item->iffeatures, 1);
+ FREE_STRING(ctx, item->name);
+ FREE_STRING(ctx, item->dsc);
+ FREE_STRING(ctx, item->ref);
+ FREE_STRINGS(ctx, item->iffeatures);
FREE_ARRAY(ctx, item->exts, lysp_ext_instance_free);
}
static void
-lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type, int dict)
+lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type)
{
- FREE_STRING(ctx, type->name, dict);
+ FREE_STRING(ctx, type->name);
FREE_MEMBER(ctx, type->range, lysp_restr_free);
FREE_MEMBER(ctx, type->length, lysp_restr_free);
FREE_ARRAY(ctx, type->patterns, lysp_restr_free);
FREE_ARRAY(ctx, type->enums, lysp_type_enum_free);
FREE_ARRAY(ctx, type->bits, lysp_type_enum_free);
- FREE_STRING(ctx, type->path, dict);
- FREE_STRINGS(ctx, type->bases, dict);
+ FREE_STRING(ctx, type->path);
+ FREE_STRINGS(ctx, type->bases);
FREE_ARRAY(ctx, type->types, lysp_type_free);
FREE_ARRAY(ctx, type->exts, lysp_ext_instance_free);
}
static void
-lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf, int dict)
+lysp_tpdf_free(struct ly_ctx *ctx, struct lysp_tpdf *tpdf)
{
- FREE_STRING(ctx, tpdf->name, dict);
- FREE_STRING(ctx, tpdf->units, dict);
- FREE_STRING(ctx, tpdf->dflt, dict);
- FREE_STRING(ctx, tpdf->dsc, dict);
- FREE_STRING(ctx, tpdf->ref, dict);
+ FREE_STRING(ctx, tpdf->name);
+ FREE_STRING(ctx, tpdf->units);
+ FREE_STRING(ctx, tpdf->dflt);
+ FREE_STRING(ctx, tpdf->dsc);
+ FREE_STRING(ctx, tpdf->ref);
FREE_ARRAY(ctx, tpdf->exts, lysp_ext_instance_free);
- lysp_type_free(ctx, &tpdf->type, dict);
+ lysp_type_free(ctx, &tpdf->type);
}
static void
-lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout, int dict)
+lysp_action_inout_free(struct ly_ctx *ctx, struct lysp_action_inout *inout)
{
struct lysp_node *node, *next;
@@ -203,19 +203,19 @@
FREE_ARRAY(ctx, inout->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, inout->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(inout->data, next, node) {
- lysp_node_free(ctx, node, dict);
+ lysp_node_free(ctx, node);
}
FREE_ARRAY(ctx, inout->exts, lysp_ext_instance_free);
}
static void
-lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action, int dict)
+lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action)
{
- FREE_STRING(ctx, action->name, dict);
- FREE_STRING(ctx, action->dsc, dict);
- FREE_STRING(ctx, action->ref, dict);
- FREE_STRINGS(ctx, action->iffeatures, 1);
+ FREE_STRING(ctx, action->name);
+ FREE_STRING(ctx, action->dsc);
+ FREE_STRING(ctx, action->ref);
+ FREE_STRINGS(ctx, action->iffeatures);
FREE_ARRAY(ctx, action->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, action->groupings, lysp_grp_free);
FREE_MEMBER(ctx, action->input, lysp_action_inout_free);
@@ -224,35 +224,35 @@
}
static void
-lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif, int dict)
+lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif)
{
struct lysp_node *node, *next;
- FREE_STRING(ctx, notif->name, dict);
- FREE_STRING(ctx, notif->dsc, dict);
- FREE_STRING(ctx, notif->ref, dict);
- FREE_STRINGS(ctx, notif->iffeatures, 1);
+ FREE_STRING(ctx, notif->name);
+ FREE_STRING(ctx, notif->dsc);
+ FREE_STRING(ctx, notif->ref);
+ FREE_STRINGS(ctx, notif->iffeatures);
FREE_ARRAY(ctx, notif->musts, lysp_restr_free);
FREE_ARRAY(ctx, notif->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, notif->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(notif->data, next, node) {
- lysp_node_free(ctx, node, dict);
+ lysp_node_free(ctx, node);
}
FREE_ARRAY(ctx, notif->exts, lysp_ext_instance_free);
}
static void
-lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp, int dict)
+lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp)
{
struct lysp_node *node, *next;
- FREE_STRING(ctx, grp->name, dict);
- FREE_STRING(ctx, grp->dsc, dict);
- FREE_STRING(ctx, grp->ref, dict);
+ FREE_STRING(ctx, grp->name);
+ FREE_STRING(ctx, grp->dsc);
+ FREE_STRING(ctx, grp->ref);
FREE_ARRAY(ctx, grp->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, grp->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(grp->data, next, node) {
- lysp_node_free(ctx, node, dict);
+ lysp_node_free(ctx, node);
}
FREE_ARRAY(ctx, grp->actions, lysp_action_free);
FREE_ARRAY(ctx, grp->notifs, lysp_notif_free);
@@ -260,26 +260,26 @@
}
static void
-lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when, int dict)
+lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when)
{
- FREE_STRING(ctx, when->cond, dict);
- FREE_STRING(ctx, when->dsc, dict);
- FREE_STRING(ctx, when->ref, dict);
+ FREE_STRING(ctx, when->cond);
+ FREE_STRING(ctx, when->dsc);
+ FREE_STRING(ctx, when->ref);
FREE_ARRAY(ctx, when->exts, lysp_ext_instance_free);
}
static void
-lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment, int dict)
+lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment)
{
struct lysp_node *node, *next;
- FREE_STRING(ctx, augment->nodeid, dict);
- FREE_STRING(ctx, augment->dsc, dict);
- FREE_STRING(ctx, augment->ref, dict);
+ FREE_STRING(ctx, augment->nodeid);
+ FREE_STRING(ctx, augment->dsc);
+ FREE_STRING(ctx, augment->ref);
FREE_MEMBER(ctx, augment->when, lysp_when_free);
- FREE_STRINGS(ctx, augment->iffeatures, 1);
+ FREE_STRINGS(ctx, augment->iffeatures);
LY_LIST_FOR_SAFE(augment->child, next, node) {
- lysp_node_free(ctx, node, dict);
+ lysp_node_free(ctx, node);
}
FREE_ARRAY(ctx, augment->actions, lysp_action_free);
FREE_ARRAY(ctx, augment->notifs, lysp_notif_free);
@@ -287,7 +287,7 @@
}
static void
-lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d, int dict)
+lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d)
{
struct lysp_deviate_add *add = (struct lysp_deviate_add*)d;
struct lysp_deviate_rpl *rpl = (struct lysp_deviate_rpl*)d;
@@ -299,15 +299,15 @@
break;
case LYS_DEV_ADD:
case LYS_DEV_DELETE: /* compatible for dynamically allocated data */
- FREE_STRING(ctx, add->units, dict);
+ FREE_STRING(ctx, add->units);
FREE_ARRAY(ctx, add->musts, lysp_restr_free);
- FREE_STRINGS(ctx, add->uniques, dict);
- FREE_STRINGS(ctx, add->dflts, dict);
+ FREE_STRINGS(ctx, add->uniques);
+ FREE_STRINGS(ctx, add->dflts);
break;
case LYS_DEV_REPLACE:
FREE_MEMBER(ctx, rpl->type, lysp_type_free);
- FREE_STRING(ctx, rpl->units, dict);
- FREE_STRING(ctx, rpl->dflt, dict);
+ FREE_STRING(ctx, rpl->units);
+ FREE_STRING(ctx, rpl->dflt);
break;
default:
LOGINT(ctx);
@@ -316,90 +316,90 @@
}
static void
-lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev, int dict)
+lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev)
{
struct lysp_deviate *next, *iter;
- FREE_STRING(ctx, dev->nodeid, dict);
- FREE_STRING(ctx, dev->dsc, dict);
- FREE_STRING(ctx, dev->ref, dict);
+ FREE_STRING(ctx, dev->nodeid);
+ FREE_STRING(ctx, dev->dsc);
+ FREE_STRING(ctx, dev->ref);
LY_LIST_FOR_SAFE(dev->deviates, next, iter) {
- lysp_deviate_free(ctx, iter, dict);
+ lysp_deviate_free(ctx, iter);
free(iter);
}
FREE_ARRAY(ctx, dev->exts, lysp_ext_instance_free);
}
static void
-lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref, int dict)
+lysp_refine_free(struct ly_ctx *ctx, struct lysp_refine *ref)
{
- FREE_STRING(ctx, ref->nodeid, dict);
- FREE_STRING(ctx, ref->dsc, dict);
- FREE_STRING(ctx, ref->ref, dict);
- FREE_STRINGS(ctx, ref->iffeatures, 1);
+ FREE_STRING(ctx, ref->nodeid);
+ FREE_STRING(ctx, ref->dsc);
+ FREE_STRING(ctx, ref->ref);
+ FREE_STRINGS(ctx, ref->iffeatures);
FREE_ARRAY(ctx, ref->musts, lysp_restr_free);
- FREE_STRING(ctx, ref->presence, dict);
- FREE_STRINGS(ctx, ref->dflts, dict);
+ FREE_STRING(ctx, ref->presence);
+ FREE_STRINGS(ctx, ref->dflts);
FREE_ARRAY(ctx, ref->exts, lysp_ext_instance_free);
}
static void
-lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node, int dict)
+lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node)
{
struct lysp_node *child, *next;
- FREE_STRING(ctx, node->name, dict);
- FREE_STRING(ctx, node->dsc, dict);
- FREE_STRING(ctx, node->ref, dict);
+ FREE_STRING(ctx, node->name);
+ FREE_STRING(ctx, node->dsc);
+ FREE_STRING(ctx, node->ref);
FREE_MEMBER(ctx, node->when, lysp_when_free);
- FREE_STRINGS(ctx, node->iffeatures, dict);
+ FREE_STRINGS(ctx, node->iffeatures);
FREE_ARRAY(ctx, node->exts, lysp_ext_instance_free);
switch(node->nodetype) {
case LYS_CONTAINER:
FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->musts, lysp_restr_free);
- FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence, dict);
+ FREE_STRING(ctx, ((struct lysp_node_container*)node)->presence);
FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(((struct lysp_node_container*)node)->child, next, child) {
- lysp_node_free(ctx, child, dict);
+ lysp_node_free(ctx, child);
}
FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->actions, lysp_action_free);
FREE_ARRAY(ctx, ((struct lysp_node_container*)node)->notifs, lysp_notif_free);
break;
case LYS_LEAF:
FREE_ARRAY(ctx, ((struct lysp_node_leaf*)node)->musts, lysp_restr_free);
- lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type, dict);
- FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units, dict);
- FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt, dict);
+ lysp_type_free(ctx, &((struct lysp_node_leaf*)node)->type);
+ FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->units);
+ FREE_STRING(ctx, ((struct lysp_node_leaf*)node)->dflt);
break;
case LYS_LEAFLIST:
FREE_ARRAY(ctx, ((struct lysp_node_leaflist*)node)->musts, lysp_restr_free);
- lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type, dict);
- FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units, dict);
- FREE_STRINGS(ctx, ((struct lysp_node_leaflist*)node)->dflts, dict);
+ lysp_type_free(ctx, &((struct lysp_node_leaflist*)node)->type);
+ FREE_STRING(ctx, ((struct lysp_node_leaflist*)node)->units);
+ FREE_STRINGS(ctx, ((struct lysp_node_leaflist*)node)->dflts);
break;
case LYS_LIST:
FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->musts, lysp_restr_free);
- FREE_STRING(ctx, ((struct lysp_node_list*)node)->key, dict);
+ FREE_STRING(ctx, ((struct lysp_node_list*)node)->key);
FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(((struct lysp_node_list*)node)->child, next, child) {
- lysp_node_free(ctx, child, dict);
+ lysp_node_free(ctx, child);
}
FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->actions, lysp_action_free);
FREE_ARRAY(ctx, ((struct lysp_node_list*)node)->notifs, lysp_notif_free);
- FREE_STRINGS(ctx, ((struct lysp_node_list*)node)->uniques, dict);
+ FREE_STRINGS(ctx, ((struct lysp_node_list*)node)->uniques);
break;
case LYS_CHOICE:
LY_LIST_FOR_SAFE(((struct lysp_node_choice*)node)->child, next, child) {
- lysp_node_free(ctx, child, dict);
+ lysp_node_free(ctx, child);
}
- FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt, dict);
+ FREE_STRING(ctx, ((struct lysp_node_choice*)node)->dflt);
break;
case LYS_CASE:
LY_LIST_FOR_SAFE(((struct lysp_node_case*)node)->child, next, child) {
- lysp_node_free(ctx, child, dict);
+ lysp_node_free(ctx, child);
}
break;
case LYS_ANYDATA:
@@ -417,8 +417,8 @@
free(node);
}
-static void
-lysp_module_free_(struct lysp_module *module, int dict)
+API void
+lysp_module_free(struct lysp_module *module)
{
struct ly_ctx *ctx;
struct lysp_node *node, *next;
@@ -426,18 +426,18 @@
LY_CHECK_ARG_RET(NULL, module,);
ctx = module->ctx;
- FREE_STRING(ctx, module->name, dict);
- FREE_STRING(ctx, module->filepath, dict);
- FREE_STRING(ctx, module->ns, dict); /* or belongs-to */
- FREE_STRING(ctx, module->prefix, dict);
+ FREE_STRING(ctx, module->name);
+ FREE_STRING(ctx, module->filepath);
+ FREE_STRING(ctx, module->ns); /* or belongs-to */
+ FREE_STRING(ctx, module->prefix);
FREE_ARRAY(ctx, module->imports, lysp_import_free);
FREE_ARRAY(ctx, module->includes, lysp_include_free);
- FREE_STRING(ctx, module->org, dict);
- FREE_STRING(ctx, module->contact, dict);
- FREE_STRING(ctx, module->dsc, dict);
- FREE_STRING(ctx, module->ref, dict);
+ FREE_STRING(ctx, module->org);
+ FREE_STRING(ctx, module->contact);
+ FREE_STRING(ctx, module->dsc);
+ FREE_STRING(ctx, module->ref);
FREE_ARRAY(ctx, module->revs, lysp_revision_free);
FREE_ARRAY(ctx, module->extensions, lysp_ext_free);
@@ -446,7 +446,7 @@
FREE_ARRAY(ctx, module->typedefs, lysp_tpdf_free);
FREE_ARRAY(ctx, module->groupings, lysp_grp_free);
LY_LIST_FOR_SAFE(module->data, next, node) {
- lysp_node_free(ctx, node, dict);
+ lysp_node_free(ctx, node);
}
FREE_ARRAY(ctx, module->augments, lysp_augment_free);
FREE_ARRAY(ctx, module->rpcs, lysp_action_free);
@@ -457,76 +457,97 @@
free(module);
}
-API void
-lysp_module_free(struct lysp_module *module)
-{
- if (module) {
- lysp_module_free_(module, 1);
- }
-}
-
static void
-lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext, int dict)
+lysc_ext_instance_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
{
- FREE_STRING(ctx, ext->argument, dict);
+ FREE_STRING(ctx, ext->argument);
FREE_ARRAY(ctx, ext->exts, lysc_ext_instance_free);
}
static void
-lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff, int UNUSED(dict))
+lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff)
{
LY_ARRAY_FREE(iff->features);
free(iff->expr);
}
static void
-lysc_import_free(struct ly_ctx *ctx, struct lysc_import *import, int dict)
+lysc_import_free(struct ly_ctx *ctx, struct lysc_import *import)
{
/* imported module is freed directly from the context's list */
- FREE_STRING(ctx, import->prefix, dict);
+ FREE_STRING(ctx, import->prefix);
FREE_ARRAY(ctx, import->exts, lysc_ext_instance_free);
}
static void
-lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident, int dict)
+lysc_ident_free(struct ly_ctx *ctx, struct lysc_ident *ident)
{
- FREE_STRING(ctx, ident->name, dict);
+ FREE_STRING(ctx, ident->name);
FREE_ARRAY(ctx, ident->iffeatures, lysc_iffeature_free);
LY_ARRAY_FREE(ident->derived);
FREE_ARRAY(ctx, ident->exts, lysc_ext_instance_free);
}
static void
-lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat, int dict)
+lysc_feature_free(struct ly_ctx *ctx, struct lysc_feature *feat)
{
- FREE_STRING(ctx, feat->name, dict);
+ FREE_STRING(ctx, feat->name);
FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
LY_ARRAY_FREE(feat->depfeatures);
FREE_ARRAY(ctx, feat->exts, lysc_ext_instance_free);
}
-static void lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node, int dict);
+static void
+lysc_range_free(struct ly_ctx *ctx, struct lysc_range *range)
+{
+ LY_ARRAY_FREE(range->parts);
+ FREE_STRING(ctx, range->eapptag);
+ FREE_STRING(ctx, range->emsg);
+ FREE_ARRAY(ctx, range->exts, lysc_ext_instance_free);
+}
static void
-lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node, int dict)
+lysc_type_free(struct ly_ctx *ctx, struct lysc_type *type)
+{
+ switch(type->basetype) {
+ case LY_TYPE_BINARY:
+ FREE_MEMBER(ctx, ((struct lysc_type_bin*)type)->length, lysc_range_free);
+ break;
+ }
+ FREE_ARRAY(ctx, type->exts, lysc_ext_instance_free);
+}
+
+static void lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node);
+
+static void
+lysc_node_container_free(struct ly_ctx *ctx, struct lysc_node_container *node)
{
struct lysc_node *child, *child_next;
LY_LIST_FOR_SAFE(node->child, child_next, child) {
- lysc_node_free(ctx, child, dict);
+ lysc_node_free(ctx, child);
}
}
static void
-lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node, int dict)
+lysc_node_leaf_free(struct ly_ctx *ctx, struct lysc_node_leaf *node)
+{
+ FREE_MEMBER(ctx, node->type, lysc_type_free);
+}
+
+static void
+lysc_node_free(struct ly_ctx *ctx, struct lysc_node *node)
{
/* common part */
- FREE_STRING(ctx, node->name, dict);
+ FREE_STRING(ctx, node->name);
/* nodetype-specific part */
switch(node->nodetype) {
case LYS_CONTAINER:
- lysc_node_container_free(ctx, (struct lysc_node_container*)node, dict);
+ lysc_node_container_free(ctx, (struct lysc_node_container*)node);
+ break;
+ case LYS_LEAF:
+ lysc_node_leaf_free(ctx, (struct lysc_node_leaf*)node);
break;
default:
LOGINT(ctx);
@@ -536,7 +557,7 @@
}
static void
-lysc_module_free_(struct lysc_module *module, int dict)
+lysc_module_free_(struct lysc_module *module)
{
struct ly_ctx *ctx;
struct lysc_node *node, *node_next;
@@ -544,17 +565,17 @@
LY_CHECK_ARG_RET(NULL, module,);
ctx = module->ctx;
- FREE_STRING(ctx, module->name, dict);
- FREE_STRING(ctx, module->ns, dict);
- FREE_STRING(ctx, module->prefix, dict);
- FREE_STRING(ctx, module->revision, 1);
+ FREE_STRING(ctx, module->name);
+ FREE_STRING(ctx, module->ns);
+ FREE_STRING(ctx, module->prefix);
+ FREE_STRING(ctx, module->revision);
FREE_ARRAY(ctx, module->imports, lysc_import_free);
FREE_ARRAY(ctx, module->features, lysc_feature_free);
FREE_ARRAY(ctx, module->identities, lysc_ident_free);
LY_LIST_FOR_SAFE(module->data, node_next, node) {
- lysc_node_free(ctx, node, dict);
+ lysc_node_free(ctx, node);
}
FREE_ARRAY(ctx, module->exts, lysc_ext_instance_free);
@@ -566,7 +587,7 @@
lysc_module_free(struct lysc_module *module, void (*private_destructor)(const struct lysc_node *node, void *priv))
{
if (module) {
- lysc_module_free_(module, 1);
+ lysc_module_free_(module);
}
}
@@ -916,20 +937,14 @@
}
static LY_ERR
-lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, int options, struct lysc_ext_instance *ext)
+lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *ext_p, int UNUSED(options), struct lysc_ext_instance *ext)
{
const char *name;
unsigned int u;
const struct lys_module *mod;
- struct lysp_ext *edef;
+ struct lysp_ext *edef = NULL;
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- ext->argument = ext_p->argument;
- } else {
- /* keep refcounts correct for lysp_module_free() */
- ext->argument = lydict_insert(ctx->ctx, ext_p->argument, 0);
- }
+ ext->argument = lydict_insert(ctx->ctx, ext_p->argument, 0);
ext->insubstmt = ext_p->insubstmt;
ext->insubstmt_index = ext_p->insubstmt_index;
@@ -960,9 +975,6 @@
return LY_SUCCESS;
}
-/**
- * @param[in] parent Provided only in case the if-feature is inside
- */
static LY_ERR
lys_compile_iffeature(struct lysc_ctx *ctx, const char **value, int UNUSED(options), struct lysc_iffeature *iff)
{
@@ -1137,6 +1149,37 @@
}
static LY_ERR
+lys_compile_when(struct lysc_ctx *ctx, struct lysp_when *when_p, int options, struct lysc_when *when)
+{
+ unsigned int u;
+ LY_ERR ret = LY_SUCCESS;
+
+ when->cond = lyxp_expr_parse(ctx->ctx, when_p->cond);
+ LY_CHECK_ERR_GOTO(!when->cond, ret = ly_errcode(ctx->ctx), done);
+ COMPILE_ARRAY_GOTO(ctx, when_p->exts, when->exts, options, u, lys_compile_ext, ret, done);
+
+done:
+ return ret;
+}
+
+static LY_ERR
+lys_compile_must(struct lysc_ctx *ctx, struct lysp_restr *must_p, int options, struct lysc_must *must)
+{
+ unsigned int u;
+ LY_ERR ret = LY_SUCCESS;
+
+ must->cond = lyxp_expr_parse(ctx->ctx, must_p->arg);
+ LY_CHECK_ERR_GOTO(!must->cond, ret = ly_errcode(ctx->ctx), done);
+
+ must->eapptag = lydict_insert(ctx->ctx, must_p->eapptag, 0);
+ must->emsg = lydict_insert(ctx->ctx, must_p->emsg, 0);
+ COMPILE_ARRAY_GOTO(ctx, must_p->exts, must->exts, options, u, lys_compile_ext, ret, done);
+
+done:
+ return ret;
+}
+
+static LY_ERR
lys_compile_import(struct lysc_ctx *ctx, struct lysp_import *imp_p, int options, struct lysc_import *imp)
{
unsigned int u;
@@ -1144,13 +1187,7 @@
struct lysc_module *comp;
LY_ERR ret = LY_SUCCESS;
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- imp->prefix = imp_p->prefix;
- } else {
- /* keep refcounts correct for lysp_module_free() */
- imp->prefix = lydict_insert(ctx->ctx, imp_p->prefix, 0);
- }
+ imp->prefix = lydict_insert(ctx->ctx, imp_p->prefix, 0);
COMPILE_ARRAY_GOTO(ctx, imp_p->exts, imp->exts, options, u, lys_compile_ext, ret, done);
imp->module = imp_p->module;
@@ -1189,13 +1226,7 @@
unsigned int u;
LY_ERR ret = LY_SUCCESS;
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- ident->name = ident_p->name;
- } else {
- /* keep refcounts correct for lysp_module_free() */
- ident->name = lydict_insert(ctx->ctx, ident_p->name, 0);
- }
+ ident->name = lydict_insert(ctx->ctx, ident_p->name, 0);
COMPILE_ARRAY_GOTO(ctx, ident_p->iffeatures, ident->iffeatures, options, u, lys_compile_iffeature, ret, done);
/* backlings (derived) can be added no sooner than when all the identities in the current module are present */
COMPILE_ARRAY_GOTO(ctx, ident_p->exts, ident->exts, options, u, lys_compile_ext, ret, done);
@@ -1255,13 +1286,7 @@
LY_ERR ret = LY_SUCCESS;
struct lysc_feature **df;
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- feature->name = feature_p->name;
- } else {
- /* keep refcounts correct for lysp_module_free() */
- feature->name = lydict_insert(ctx->ctx, feature_p->name, 0);
- }
+ feature->name = lydict_insert(ctx->ctx, feature_p->name, 0);
feature->flags = feature_p->flags;
COMPILE_ARRAY_GOTO(ctx, feature_p->exts, feature->exts, options, u, lys_compile_ext, ret, done);
@@ -1282,27 +1307,551 @@
return ret;
}
+static LY_ERR
+range_part_check_value_syntax(struct lysc_ctx *ctx, LY_DATA_TYPE basetype, const char *value, size_t *len, char **valcopy)
+{
+ size_t fraction = 0;
+ *len = 0;
+
+ assert(value);
+ /* parse value */
+ if (!isdigit(value[*len]) && (value[*len] != '-') && (value[*len] != '+')) {
+ return LY_EVALID;
+ }
+
+ if ((value[*len] == '-') || (value[*len] == '+')) {
+ ++(*len);
+ }
+
+ while (isdigit(value[*len])) {
+ ++(*len);
+ }
+
+ if ((basetype != LY_TYPE_DEC64) || (value[*len] != '.') || !isdigit(value[*len + 1])) {
+ *valcopy = strndup(value, *len);
+ return LY_SUCCESS;
+ }
+ fraction = *len;
+
+ ++(*len);
+ while (isdigit(value[*len])) {
+ ++(*len);
+ }
+
+ if (fraction) {
+ *valcopy = malloc(((*len) - 1) * sizeof **valcopy);
+ LY_CHECK_ERR_RET(!(*valcopy), LOGMEM(ctx->ctx), LY_EMEM);
+
+ *valcopy[(*len) - 1] = '\0';
+ memcpy(&(*valcopy)[0], &value[0], fraction);
+ memcpy(&(*valcopy)[fraction], &value[fraction + 1], (*len) - 1 - (fraction + 1));
+ }
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+range_part_check_ascendance(int unsigned_value, int64_t value, int64_t prev_value)
+{
+ if (unsigned_value) {
+ if ((uint64_t)prev_value >= (uint64_t)value) {
+ return LY_EEXIST;
+ }
+ } else {
+ if (prev_value >= value) {
+ return LY_EEXIST;
+ }
+ }
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+range_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,
+ const char **value)
+{
+ LY_ERR ret = LY_SUCCESS;
+ char *valcopy = NULL;
+ size_t len;
+
+ if (value) {
+ ret = range_part_check_value_syntax(ctx, basetype, *value, &len, &valcopy);
+ LY_CHECK_GOTO(ret, error);
+ }
+
+ switch (basetype) {
+ case LY_TYPE_BINARY: /* length */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(18446744073709551615);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_DEC64: /* range */
+ if (valcopy) {
+ ret = ly_parse_int(valcopy, __INT64_C(-9223372036854775807) - __INT64_C(1), __INT64_C(9223372036854775807), 10,
+ max ? &part->max_64 : &part->min_64);
+ } else if (max) {
+ part->max_64 = __INT64_C(9223372036854775807);
+ } else {
+ part->min_64 = __INT64_C(-9223372036854775807) - __INT64_C(1);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_INT8: /* range */
+ if (valcopy) {
+ ret = ly_parse_int(valcopy, __INT64_C(-128), INT64_C(127), 10, max ? &part->max_64 : &part->min_64);
+ } else if (max) {
+ part->max_64 = __INT64_C(127);
+ } else {
+ part->min_64 = __INT64_C(-128);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_INT16: /* range */
+ if (valcopy) {
+ ret = ly_parse_int(valcopy, __INT64_C(-32768), INT64_C(32767), 10, max ? &part->max_64 : &part->min_64);
+ } else if (max) {
+ part->max_64 = __INT64_C(32767);
+ } else {
+ part->min_64 = __INT64_C(-32768);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_INT32: /* range */
+ if (valcopy) {
+ ret = ly_parse_int(valcopy, __INT64_C(-2147483648), INT64_C(2147483647), 10, max ? &part->max_64 : &part->min_64);
+ } else if (max) {
+ part->max_64 = __INT64_C(2147483647);
+ } else {
+ part->min_64 = __INT64_C(-2147483648);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_INT64: /* range */
+ if (valcopy) {
+ ret = ly_parse_int(valcopy, __INT64_C(-9223372036854775807) - __INT64_C(1), INT64_C(9223372036854775807), 10,
+ max ? &part->max_64 : &part->min_64);
+ } else if (max) {
+ part->max_64 = __INT64_C(9223372036854775807);
+ } else {
+ part->min_64 = __INT64_C(-9223372036854775807) - __INT64_C(1);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(0, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_UINT8: /* range */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(255), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(255);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_UINT16: /* range */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(65535), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(65535);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_UINT32: /* range */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(4294967295), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(4294967295);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_UINT64: /* range */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(18446744073709551615);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ case LY_TYPE_STRING: /* length */
+ if (valcopy) {
+ ret = ly_parse_uint(valcopy, __UINT64_C(18446744073709551615), 10, max ? &part->max_u64 : &part->min_u64);
+ } else if (max) {
+ part->max_u64 = __UINT64_C(18446744073709551615);
+ } else {
+ part->min_u64 = __UINT64_C(0);
+ }
+ if (!first) {
+ ret = range_part_check_ascendance(1, max ? part->max_64 : part->min_64, prev);
+ }
+ break;
+ default:
+ LOGINT(ctx->ctx);
+ ret = LY_EINT;
+ }
+
+error:
+ if (ret == LY_EDENIED) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - value \"%s\" does not fit the type limitations.",
+ length_restr ? "length" : "range", valcopy ? valcopy : *value);
+ } else if (ret == LY_EVALID) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - invalid value \"%s\".",
+ length_restr ? "length" : "range", valcopy ? valcopy : *value);
+ } else if (ret == LY_EEXIST) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - values are not in ascending order (%s).",
+ length_restr ? "length" : "range", valcopy ? valcopy : *value);
+ } else if (!ret && value) {
+ *value = *value + len;
+ }
+ free(valcopy);
+ return ret;
+}
+
+static LY_ERR
+lys_compile_type_range(struct lysc_ctx *ctx, struct lysp_restr *range_p, LY_DATA_TYPE basetype, int length_restr,
+ struct lysc_range **range)
+{
+ LY_ERR ret = LY_EVALID;
+ const char *expr;
+ struct lysc_range_part *parts = NULL, *part;
+ size_t parts_done = 0;
+ int range_expected = 0;
+
+ assert(range);
+ assert(range_p);
+
+ if (!(*range)) {
+ *range = calloc(1, sizeof **range);
+ LY_CHECK_ERR_RET(!(*range), LOGMEM(ctx->ctx), LY_EMEM);
+ }
+
+ if (range_p->eapptag) {
+ lydict_remove(ctx->ctx, (*range)->eapptag);
+ lydict_insert(ctx->ctx, range_p->eapptag, 0);
+ }
+ if (range_p->emsg) {
+ lydict_remove(ctx->ctx, (*range)->emsg);
+ lydict_insert(ctx->ctx, range_p->emsg, 0);
+ }
+ /* extensions are taken only from the last range by the caller */
+
+ expr = range_p->arg;
+ while(1) {
+ if (isspace(*expr)) {
+ ++expr;
+ continue;
+ } else if (*expr == '\0') {
+ parts_done++;
+ break;
+ } else if (!strncmp(expr, "min", 3)) {
+ if (parts) {
+ /* min cannot be used elsewhere than in the first part */
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - unexpected data before min keyword (%.*s).", length_restr ? "length" : "range",
+ expr - range_p->arg, range_p->arg);
+ goto cleanup;
+ }
+ expr += 3;
+
+ LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
+ LY_CHECK_GOTO(range_part_minmax(ctx, part, 0, 0, basetype, 1, length_restr, NULL), cleanup);
+ part->max_64 = part->min_64;
+ } else if (*expr == '|') {
+ if (!parts || range_expected) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - unexpected beginning of the expression (%s).", length_restr ? "length" : "range", expr);
+ goto cleanup;
+ }
+ expr++;
+ parts_done++;
+ /* process next part of the expression */
+ continue;
+ } else if (!strncmp(expr, "..", 2)) {
+ expr += 2;
+ while (isspace(*expr)) {
+ expr++;
+ }
+ if (*expr == '\0') {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - unexpected end of the expression after \"..\".", length_restr ? "length" : "range");
+ goto cleanup;
+ } else if (!parts || LY_ARRAY_SIZE(parts) == parts_done) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+ "Invalid %s restriction - unexpected \"..\" without a lower bound.", length_restr ? "length" : "range");
+ goto cleanup;
+ }
+ /* continue expecting the upper boundary */
+ range_expected = 1;
+ } else if (isdigit(*expr) || (*expr == '-') || (*expr == '+')) {
+ /* number */
+ if (range_expected) {
+ part = &parts[LY_ARRAY_SIZE(parts) - 1];
+ LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, part->min_64, basetype, 0, length_restr, &expr), cleanup);
+ } else {
+ LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
+ LY_CHECK_GOTO(range_part_minmax(ctx, part, 0, parts_done ? parts[LY_ARRAY_SIZE(parts) - 2].max_64 : 0,
+ basetype, parts_done ? 0 : 1, length_restr, &expr), cleanup);
+ part->max_64 = part->min_64;
+ }
+
+ /* continue with possible another expression part */
+ range_expected = 0;
+ continue;
+ } else if (!strncmp(expr, "max", 3)) {
+ expr += 3;
+ while (isspace(*expr)) {
+ expr++;
+ }
+ if (*expr != '\0') {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data after max keyword (%s).",
+ length_restr ? "length" : "range", expr);
+ goto cleanup;
+ }
+ if (range_expected) {
+ part = &parts[LY_ARRAY_SIZE(parts) - 1];
+ LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, part->min_64, basetype, 0, length_restr, NULL), cleanup);
+ parts_done++;
+ } else {
+ LY_ARRAY_NEW_GOTO(ctx->ctx, parts, part, ret, cleanup);
+ LY_CHECK_GOTO(range_part_minmax(ctx, part, 1, parts_done ? parts[LY_ARRAY_SIZE(parts) - 2].max_64 : 0,
+ basetype, parts_done ? 0 : 1, length_restr, NULL), cleanup);
+ part->min_64 = part->max_64;
+ }
+ /* done */
+ break;
+ } else {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data (%s).",
+ length_restr ? "length" : "range", expr);
+ goto cleanup;
+ }
+ }
+
+ (*range)->parts = parts;
+ parts = NULL;
+ ret = LY_SUCCESS;
+cleanup:
+ /* TODO clean up */
+ LY_ARRAY_FREE(parts);
+
+ return ret;
+}
+
+static LY_ERR
+lys_compile_type(struct lysc_ctx *ctx, struct lysp_node_leaf *leaf_p, int options, struct lysc_type **type)
+{
+ LY_ERR ret = LY_SUCCESS;
+ unsigned int u;
+ struct lysp_type *type_p = &leaf_p->type;
+ struct type_context {
+ const struct lysp_tpdf *tpdf;
+ struct lysp_node *node;
+ struct lysp_module *mod;
+ } *tctx, *tctx_prev = NULL;
+ LY_DATA_TYPE basetype = LY_TYPE_UNKNOWN;
+ struct ly_set tpdf_chain = {0};
+ struct lysc_type_bin* bin;
+
+
+ tctx = calloc(1, sizeof *tctx);
+ LY_CHECK_ERR_RET(!tctx, LOGMEM(ctx->ctx), LY_EMEM);
+ for (ret = lysp_type_find(type_p->name, (struct lysp_node*)leaf_p, ctx->mod->parsed,
+ &basetype, &tctx->tpdf, &tctx->node, &tctx->mod);
+ ret;
+ ret = lysp_type_find(tctx_prev->tpdf->type.name, tctx_prev->node, tctx_prev->mod,
+ &basetype, &tctx->tpdf, &tctx->node, &tctx->mod)) {
+ if (basetype) {
+ break;
+ }
+
+ /* check status */
+ if (lysc_check_status(ctx, leaf_p->flags, ctx->mod->parsed, leaf_p->name,
+ tctx->tpdf->flags, tctx->mod, tctx->node ? tctx->node->name : tctx->mod->name)) {
+ free(tctx);
+ goto cleanup;
+ }
+
+ if (!(tctx->tpdf->flags & LYS_TYPE_MODIFIED)) {
+ /* no change in comparison to the following (actually preceding in the chain of type derivations) type */
+ memset(tctx, 0, sizeof *tctx);
+ continue;
+ }
+
+ /* store information for the following processing */
+ ly_set_add(&tpdf_chain, tctx, LY_SET_OPT_USEASLIST);
+
+ /* prepare next loop */
+ tctx = calloc(1, sizeof *tctx);
+ LY_CHECK_ERR_RET(!tctx, LOGMEM(ctx->ctx), LY_EMEM);
+ }
+ free(tctx);
+
+ /* allocate type according to the basetype */
+ switch (basetype) {
+ case LY_TYPE_BINARY:
+ *type = calloc(1, sizeof(struct lysc_type_bin));
+ bin = (struct lysc_type_bin*)(*type);
+ break;
+ case LY_TYPE_BITS:
+ *type = calloc(1, sizeof(struct lysc_type_bits));
+ break;
+ case LY_TYPE_BOOL:
+ case LY_TYPE_EMPTY:
+ *type = calloc(1, sizeof(struct lysc_type));
+ break;
+ case LY_TYPE_DEC64:
+ *type = calloc(1, sizeof(struct lysc_type_dec));
+ break;
+ case LY_TYPE_ENUM:
+ *type = calloc(1, sizeof(struct lysc_type_enum));
+ break;
+ case LY_TYPE_IDENT:
+ *type = calloc(1, sizeof(struct lysc_type_identityref));
+ break;
+ case LY_TYPE_INST:
+ *type = calloc(1, sizeof(struct lysc_type_instanceid));
+ break;
+ case LY_TYPE_LEAFREF:
+ *type = calloc(1, sizeof(struct lysc_type_leafref));
+ break;
+ case LY_TYPE_STRING:
+ *type = calloc(1, sizeof(struct lysc_type_str));
+ break;
+ case LY_TYPE_UNION:
+ *type = calloc(1, sizeof(struct lysc_type_union));
+ break;
+ case LY_TYPE_INT8:
+ case LY_TYPE_UINT8:
+ case LY_TYPE_INT16:
+ case LY_TYPE_UINT16:
+ case LY_TYPE_INT32:
+ case LY_TYPE_UINT32:
+ case LY_TYPE_INT64:
+ case LY_TYPE_UINT64:
+ *type = calloc(1, sizeof(struct lysc_type_num));
+ break;
+ default:
+ LOGINT(ctx->ctx);
+ }
+ LY_CHECK_ERR_GOTO(!(*type), LOGMEM(ctx->ctx), cleanup);
+ (*type)->basetype = basetype;
+ COMPILE_ARRAY_GOTO(ctx, type_p->exts, (*type)->exts, options, u, lys_compile_ext, ret, cleanup);
+
+
+ /* get restrictions from the referred typedefs */
+ for (u = tpdf_chain.count - 1; u + 1 > 0; --u) {
+ tctx = (struct type_context*)tpdf_chain.objs[u];
+
+ switch (basetype) {
+ case LY_TYPE_BINARY:
+ /* RFC 6020 9.8.1, 9.4.4 - length, number of octets it contains */
+ if (tctx->tpdf->type.length) {
+ ret = lys_compile_type_range(ctx, tctx->tpdf->type.length, basetype, 1, &bin->length);
+ LY_CHECK_GOTO(ret, cleanup);
+ }
+ break;
+ }
+ }
+
+ /* get restrictions from the node itself, finalize the type structure */
+ switch ((*type)->basetype) {
+ case LY_TYPE_BINARY:
+ if (leaf_p->type.length) {
+ ret = lys_compile_type_range(ctx, leaf_p->type.length, basetype, 1, &bin->length);
+ LY_CHECK_GOTO(ret, cleanup);
+ COMPILE_ARRAY_GOTO(ctx, leaf_p->type.length->exts, bin->length->exts,
+ options, u, lys_compile_ext, ret, cleanup);
+ }
+ break;
+ }
+
+cleanup:
+ ly_set_erase(&tpdf_chain, free);
+
+ return ret;
+}
+
static LY_ERR lys_compile_node(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *parent);
static LY_ERR
lys_compile_node_container(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *node)
{
struct lysp_node_container *cont_p = (struct lysp_node_container*)node_p;
- //struct lysc_node_container *cont = (struct lysc_node_container*)node;
+ struct lysc_node_container *cont = (struct lysc_node_container*)node;
struct lysp_node *child_p;
+ unsigned int u;
+ LY_ERR ret = LY_SUCCESS;
+
+ COMPILE_MEMBER_GOTO(ctx, cont_p->when, cont->when, options, lys_compile_when, ret, done);
+ COMPILE_ARRAY_GOTO(ctx, cont_p->iffeatures, cont->iffeatures, options, u, lys_compile_iffeature, ret, done);
LY_LIST_FOR(cont_p->child, child_p) {
LY_CHECK_RET(lys_compile_node(ctx, child_p, options, node));
}
- return LY_SUCCESS;
+ COMPILE_ARRAY_GOTO(ctx, cont_p->musts, cont->musts, options, u, lys_compile_must, ret, done);
+ //COMPILE_ARRAY_GOTO(ctx, cont_p->actions, cont->actions, options, u, lys_compile_action, ret, done);
+ //COMPILE_ARRAY_GOTO(ctx, cont_p->notifs, cont->notifs, options, u, lys_compile_notif, ret, done);
+
+done:
+ return ret;
+}
+
+static LY_ERR
+lys_compile_node_leaf(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *node)
+{
+ struct lysp_node_leaf *leaf_p = (struct lysp_node_leaf*)node_p;
+ struct lysc_node_leaf *leaf = (struct lysc_node_leaf*)node;
+ unsigned int u;
+ LY_ERR ret = LY_SUCCESS;
+
+ COMPILE_MEMBER_GOTO(ctx, leaf_p->when, leaf->when, options, lys_compile_when, ret, done);
+ COMPILE_ARRAY_GOTO(ctx, leaf_p->iffeatures, leaf->iffeatures, options, u, lys_compile_iffeature, ret, done);
+
+ COMPILE_ARRAY_GOTO(ctx, leaf_p->musts, leaf->musts, options, u, lys_compile_must, ret, done);
+ ret = lys_compile_type(ctx, leaf_p, options, &leaf->type);
+ LY_CHECK_GOTO(ret, done);
+
+ leaf->units = lydict_insert(ctx->ctx, leaf_p->units, 0);
+ leaf->dflt = lydict_insert(ctx->ctx, leaf_p->dflt, 0);
+done:
+ return ret;
}
static LY_ERR
lys_compile_node(struct lysc_ctx *ctx, struct lysp_node *node_p, int options, struct lysc_node *parent)
{
LY_ERR ret = LY_EVALID;
- struct lysc_node *node;
+ struct lysc_node *node, **children;
unsigned int u;
LY_ERR (*node_compile_spec)(struct lysc_ctx*, struct lysp_node*, int, struct lysc_node*);
@@ -1313,6 +1862,7 @@
break;
case LYS_LEAF:
node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_leaf));
+ node_compile_spec = lys_compile_node_leaf;
break;
case LYS_LIST:
node = (struct lysc_node*)calloc(1, sizeof(struct lysc_node_list));
@@ -1379,29 +1929,25 @@
}
}
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- node->name = node_p->name;
- } else {
+ if (!(options & LYSC_OPT_FREE_SP)) {
node->sp = node_p;
- /* keep refcounts correct for lysp_module_free() */
- node->name = lydict_insert(ctx->ctx, node_p->name, 0);
}
+ node->name = lydict_insert(ctx->ctx, node_p->name, 0);
COMPILE_ARRAY_GOTO(ctx, node_p->exts, node->exts, options, u, lys_compile_ext, ret, error);
/* nodetype-specific part */
LY_CHECK_GOTO(node_compile_spec(ctx, node_p, options, node), error);
/* insert into parent's children */
- if (parent) {
- if (!((struct lysc_node_case*)parent)->child) {
+ if (parent && (children = lysc_node_children(parent))) {
+ if (!(*children)) {
/* first child */
- ((struct lysc_node_case*)parent)->child = node;
+ *children = node;
} else {
/* insert at the end of the parent's children list */
- ((struct lysc_node_case*)parent)->child->prev->next = node;
- node->prev = ((struct lysc_node_case*)parent)->child->prev;
- ((struct lysc_node_case*)parent)->child->prev = node;
+ (*children)->prev->next = node;
+ node->prev = (*children)->prev;
+ (*children)->prev = node;
}
} else {
/* top-level element */
@@ -1418,7 +1964,7 @@
return LY_SUCCESS;
error:
- lysc_node_free(ctx->ctx, node, (options & LYSC_OPT_FREE_SP) ? 0 : 1);
+ lysc_node_free(ctx->ctx, node);
return ret;
}
@@ -1450,17 +1996,9 @@
mod_c->latest_revision = sp->latest_revision;
mod_c->version = sp->version;
- if (options & LYSC_OPT_FREE_SP) {
- /* just switch the pointers */
- mod_c->name = sp->name;
- mod_c->ns = sp->ns;
- mod_c->prefix = sp->prefix;
- } else {
- /* keep refcounts correct for lysp_module_free() */
- mod_c->name = lydict_insert(sp->ctx, sp->name, 0);
- mod_c->ns = lydict_insert(sp->ctx, sp->ns, 0);
- mod_c->prefix = lydict_insert(sp->ctx, sp->prefix, 0);
- }
+ mod_c->name = lydict_insert(sp->ctx, sp->name, 0);
+ mod_c->ns = lydict_insert(sp->ctx, sp->ns, 0);
+ mod_c->prefix = lydict_insert(sp->ctx, sp->prefix, 0);
if (sp->revs) {
mod_c->revision = lydict_insert(sp->ctx, sp->revs[0].date, 10);
}
@@ -1471,15 +2009,17 @@
LY_CHECK_RET(lys_compile_identities_derived(&ctx, sp->identities, mod_c->identities));
}
- COMPILE_ARRAY_GOTO(&ctx, sp->exts, mod_c->exts, options, u, lys_compile_ext, ret, error);
-
LY_LIST_FOR(sp->data, node_p) {
ret = lys_compile_node(&ctx, node_p, options, NULL);
LY_CHECK_GOTO(ret, error);
}
+ //COMPILE_ARRAY_GOTO(ctx, sp->rpcs, mod_c->rpcs, options, u, lys_compile_action, ret, error);
+ //COMPILE_ARRAY_GOTO(ctx, sp->notifs, mod_c->notifs, options, u, lys_compile_notif, ret, error);
+
+ COMPILE_ARRAY_GOTO(&ctx, sp->exts, mod_c->exts, options, u, lys_compile_ext, ret, error);
if (options & LYSC_OPT_FREE_SP) {
- lysp_module_free_(mod->parsed, 0);
+ lysp_module_free(mod->parsed);
((struct lys_module*)mod)->parsed = NULL;
}
@@ -1487,7 +2027,7 @@
return LY_SUCCESS;
error:
- lysc_module_free_(mod_c, (options & LYSC_OPT_FREE_SP) ? 0 : 1);
+ lysc_module_free(mod_c, NULL);
((struct lys_module*)mod)->compiled = NULL;
return ret;
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index d6aa6c0..e685f8c 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -338,7 +338,7 @@
uint8_t fraction_digits; /**< number of fraction digits - decimal64 */
uint8_t require_instance; /**< require-instance flag - leafref, instance */
- uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_SET_REQINST allowed */
+ uint16_t flags; /**< [schema node flags](@ref spnodeflags) */
};
/**
@@ -352,7 +352,7 @@
const char *ref; /**< reference statement */
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
struct lysp_type type; /**< base type from which the typedef is derived (mandatory) */
- uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_* values allowed */
+ uint16_t flags; /**< [schema node flags](@ref spnodeflags) */
};
/**
@@ -481,35 +481,118 @@
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
};
+/**
+ * @defgroup spnodeflags Parsed schema nodes flags
+ * @ingroup snodeflags
+ *
+ * Various flags for parsed schema nodes.
+ *
+ * 1 - container 6 - anydata/anyxml 11 - output 16 - grouping 21 - enum
+ * 2 - choice 7 - case 12 - feature 17 - uses 22 - type
+ * 3 - leaf 8 - notification 13 - identity 18 - refine
+ * 4 - leaflist 9 - rpc 14 - extension 19 - augment
+ * 5 - list 10 - input 15 - typedef 20 - deviate
+ *
+ * 1 1 1 1 1 1 1 1 1 1 2 2 2
+ * bit name 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 1 LYS_CONFIG_W |x|x|x|x|x|x|x| | | | | | | | | | |x| |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 2 LYS_CONFIG_R |x|x|x|x|x|x|x| | | | | | | | | | |x| |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 3 LYS_STATUS_CURR |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 6 LYS_MAND_TRUE | |x|x| | |x| | | | | | | | | | | |x| |x| | |
+ * LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 7 LYS_MAND_FALSE | |x|x| | |x| | | | | | | | | | | |x| |x| | |
+ * LYS_ORDBY_USER | | | |x|x| | | | | | | | | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 8 LYS_YINELEM_TRUE | | | | | | | | | | | | | |x| | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 9 LYS_YINELEM_FALSE| | | | | | | | | | | | | |x| | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 10 LYS_SET_VALUE | | | | | | | | | | | | | | | | | | | | |x| |
+ * LYS_SET_REQINST | | | | | | | | | | | | | | | | | | | | | |x|
+ * LYS_SET_MIN | | | |x|x| | | | | | | | | | | | |x| |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 11 LYS_SET_MAX | | | |x|x| | | | | | | | | | | | |x| |x| | |
+ * LYS_TYPE_MODIFIED| | | | | | | | | | | | | | | | | | | | | |x|
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+/**
+ * @defgroup scnodeflags Compiled schema nodes flags
+ * @ingroup snodeflags
+ *
+ * Various flags for compiled schema nodes.
+ *
+ * 1 - container 6 - anydata/anyxml 11 - output
+ * 2 - choice 7 - case 12 - feature
+ * 3 - leaf 8 - notification 13 - identity
+ * 4 - leaflist 9 - rpc 14 - extension
+ * 5 - list 10 - input
+ *
+ * 1 1 1 1 1
+ * bit name 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 1 LYS_CONFIG_W |x|x|x|x|x|x|x| | |x| | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 2 LYS_CONFIG_R |x|x|x|x|x|x|x| | | |x| | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 3 LYS_PRESENCE |x| | | | | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 4 LYS_UNIQUE | | |x| | | | | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 5 LYS_FENABLED | | | | | | | | | | | |x| | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 6 LYS_MAND_TRUE | |x|x| | |x| | | | | | | | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 7 LYS_ORDBY_USER | | | |x|x| | | | | | | | | |
+ * ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+/**
+ * @defgroup snodeflags Schema nodes flags
+ * @ingroup schematree
+ * @{
+ */
#define LYS_CONFIG_W 0x01 /**< config true; */
#define LYS_CONFIG_R 0x02 /**< config false; */
#define LYS_CONFIG_MASK 0x03 /**< mask for config value */
-#define LYS_STATUS_CURR 0x08 /**< status current; */
-#define LYS_STATUS_DEPRC 0x10 /**< status deprecated; */
-#define LYS_STATUS_OBSLT 0x20 /**< status obsolete; */
-#define LYS_STATUS_MASK 0x38 /**< mask for status value */
-#define LYS_MAND_TRUE 0x40 /**< mandatory true; applicable only to
+#define LYS_STATUS_CURR 0x04 /**< status current; */
+#define LYS_STATUS_DEPRC 0x08 /**< status deprecated; */
+#define LYS_STATUS_OBSLT 0x10 /**< status obsolete; */
+#define LYS_STATUS_MASK 0x1C /**< mask for status value */
+#define LYS_MAND_TRUE 0x20 /**< mandatory true; applicable only to ::lysp_node_choice/::lysc_node_choice,
+ ::lysp_node_leaf/::lysc_node_leaf and ::lysp_node_anydata/::lysc_node_anydata */
+#define LYS_MAND_FALSE 0x40 /**< mandatory false; applicable only to
::lysp_node_choice/::lysc_node_choice, ::lysp_node_leaf/::lysc_node_leaf
and ::lysp_node_anydata/::lysc_node_anydata */
-#define LYS_MAND_FALSE 0x80 /**< mandatory false; applicable only to
- ::lysp_node_choice/::lysc_node_choice, ::lysp_node_leaf/::lysc_node_leaf
- and ::lysp_node_anydata/::lysc_node_anydata */
-#define LYS_MAND_MASK 0xc0 /**< mask for mandatory values */
-#define LYS_ORDBY_SYSTEM 0x100 /**< ordered-by system lists, applicable only to
- ::lysp_node_list/lysc_node_list and ::lysp_node_leaflist/::lysc_node_list */
-#define LYS_ORDBY_USER 0x200 /**< ordered-by user lists, applicable only to
- ::lysp_node_list/lysc_node_list and ::lysp_node_leaflist/::lysc_node_list */
-#define LYS_ORDBY_MASK 0x300 /**< mask for ordered-by flags */
-#define LYS_FENABLED 0x100 /**< feature enabled flag, applicable only to ::lysp_feature/::lysc_feature */
-#define LYS_AUTOASSIGNED 0x01 /**< value was auto-assigned, applicable only to
- ::lysp_type/::lysc_type enum and bits flags */
-#define LYS_YINELEM_TRUE 0x01 /**< yin-element true for extension's argument */
-#define LYS_YINELEM_FALSE 0x02 /**< yin-element false for extension's argument */
-#define LYS_YINELEM_MASK 0x03 /**< mask for yin-element value */
-#define LYS_SET_VALUE 0x01 /**< value attribute is set */
+#define LYS_MAND_MASK 0x60 /**< mask for mandatory values */
+#define LYS_PRESENCE 0x04 /**< flag for presence property of a container, applicable only to ::lysc_node_container */
+#define LYS_UNIQUE 0x08 /**< flag for leafs being part of a unique set, applicable only to ::lysc_node_leaf */
+#define LYS_FENABLED 0x10 /**< feature enabled flag, applicable only to ::lysc_feature */
+#define LYS_ORDBY_SYSTEM 0x20 /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
+ ::lysc_node_list/::lysp_node_list */
+#define LYS_ORDBY_USER 0x40 /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
+ ::lysc_node_list/::lysp_node_list */
+#define LYS_ORDBY_MASK 0x60 /**< mask for ordered-by values */
+#define LYS_YINELEM_TRUE 0x80 /**< yin-element true for extension's argument */
+#define LYS_YINELEM_FALSE 0x100 /**< yin-element false for extension's argument */
+#define LYS_YINELEM_MASK 0x180 /**< mask for yin-element value */
+#define LYS_SET_VALUE 0x200 /**< value attribute is set */
+#define LYS_SET_REQINST 0x200 /**< require_instance attribute is set */
+#define LYS_SET_MIN 0x200 /**< min attribute is set */
#define LYS_SET_MAX 0x400 /**< max attribute is set */
-#define LYS_SET_MIN 0x800 /**< min attribute is set */
-#define LYS_SET_REQINST 0x01 /**< require_instance attribute is set */
+#define LYS_TYPE_MODIFIED 0x400 /**< referenced type has been modified by a restriction */
+/** @} */
/**
* @brief Generic YANG data node
@@ -892,7 +975,7 @@
};
struct lysc_range {
- struct {
+ struct lysc_range_part {
union { /**< min boundary TODO decimal */
int64_t min_64; /**< for int8, int16, int32 and int64 */
uint64_t min_u64; /**< for uint8, uint16, uint32 and uint64 */
@@ -901,7 +984,7 @@
int64_t max_64; /**< for int8, int16, int32 and int64 */
uint64_t max_u64; /**< for uint8, uint16, uint32 and uint64 */
};
- } *parts; /**< compiled range expression */
+ } *parts; /**< compiled range expression ([sized array](@ref sizedarrays)) */
const char *emsg; /**< error-message */
const char *eapptag; /**< error-app-tag value */
struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
@@ -925,20 +1008,20 @@
};
struct lysc_type {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
};
struct lysc_type_num {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_range *range; /**< Optional range limitation */
};
struct lysc_type_dec {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
uint64_t fraction_digits:1; /**< fraction digits specification */
@@ -947,7 +1030,7 @@
};
struct lysc_type_str {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_range *length; /**< Optional length limitation */
@@ -955,7 +1038,7 @@
};
struct lysc_type_enum {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct {
@@ -966,7 +1049,7 @@
};
struct lysc_type_leafref {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_node* target; /**< Target schema node */
@@ -974,7 +1057,7 @@
};
struct lysc_type_identityref {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_ident **base; /**< list of pointers to the base identities ([sized array](@ref sizedarrays)),
@@ -982,14 +1065,14 @@
};
struct lysc_type_instanceid {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
uint8_t require_instance; /**< require-instance flag */
};
struct lysc_type_bits {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct {
@@ -1000,14 +1083,14 @@
};
struct lysc_type_union {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_type **types; /**< list of types in the union ([sized array](@ref sizedarrays)), mandatory (at least 1 item) */
};
struct lysc_type_bin {
- struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
LY_DATA_TYPE basetype; /**< Base type of the type */
uint32_t refcount; /**< reference counter for type sharing */
struct lysc_range *length; /**< Optional length limitation */
@@ -1045,7 +1128,13 @@
const char *name; /**< node name (mandatory) */
struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
- struct lysc_node *child;
+ struct lysc_when *when; /**< when statement */
+ struct lysc_iffeature *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
+
+ struct lysc_node *child; /**< first child node (linked list) */
+ struct lysc_must *musts; /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+ struct lysc_action *actions; /**< list of actions ([sized array](@ref sizedarrays)) */
+ struct lysc_notif *notifs; /**< list of notifications ([sized array](@ref sizedarrays)) */
};
struct lysc_node_choice {
@@ -1079,6 +1168,13 @@
const char *name; /**< node name (mandatory) */
struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_when *when; /**< when statement */
+ struct lysc_iffeature *iffeatures; /**< list of if-feature expressions ([sized array](@ref sizedarrays)) */
+
+ struct lysc_must *musts; /**< list of must restrictions ([sized array](@ref sizedarrays)) */
+ struct lysc_type *type; /**< type of the leaf node (mandatory) */
+ const char *units; /**< units of the leaf's type */
+ const char *dflt; /**< default value */
};
struct lysc_node_leaflist {
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index df72591..52b6f61 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -50,6 +50,29 @@
}
LY_ERR
+lysc_check_status(struct lysc_ctx *ctx,
+ uint16_t flags1, void *mod1, const char *name1,
+ uint16_t flags2, void *mod2, const char *name2)
+{
+ uint16_t flg1, flg2;
+
+ flg1 = (flags1 & LYS_STATUS_MASK) ? (flags1 & LYS_STATUS_MASK) : LYS_STATUS_CURR;
+ flg2 = (flags2 & LYS_STATUS_MASK) ? (flags2 & LYS_STATUS_MASK) : LYS_STATUS_CURR;
+
+ if ((flg1 < flg2) && (mod1 == mod2)) {
+ if (ctx) {
+ LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+ "A %s definition \"%s\" is not allowed to reference %s definition \"%s\".",
+ flg1 == LYS_STATUS_CURR ? "current" : "deprecated", name1,
+ flg2 == LYS_STATUS_OBSLT ? "obsolete" : "deprecated", name2);
+ }
+ return LY_EVALID;
+ }
+
+ return LY_SUCCESS;
+}
+
+LY_ERR
lysp_check_date(struct ly_parser_ctx *ctx, const char *date, int date_len, const char *stmt)
{
int i;
@@ -136,9 +159,83 @@
return NULL;
}
+static LY_DATA_TYPE
+lysp_type_str2builtin(const char *name, size_t len)
+{
+ if (len >= 4) { /* otherwise it does not match any built-in type */
+ if (name[0] == 'b') {
+ if (name[1] == 'i') {
+ if (len == 6 && !strncmp(&name[2], "nary", 4)) {
+ return LY_TYPE_BINARY;
+ } else if (len == 4 && !strncmp(&name[2], "ts", 2)) {
+ return LY_TYPE_BITS;
+ }
+ } else if (len == 7 && !strncmp(&name[1], "oolean", 6)) {
+ return LY_TYPE_BOOL;
+ }
+ } else if (name[0] == 'd') {
+ if (len == 9 && !strncmp(&name[1], "ecimal64", 8)) {
+ return LY_TYPE_DEC64;
+ }
+ } else if (name[0] == 'e') {
+ if (len == 5 && !strncmp(&name[1], "mpty", 4)) {
+ return LY_TYPE_EMPTY;
+ } else if (len == 11 && !strncmp(&name[1], "numeration", 10)) {
+ return LY_TYPE_ENUM;
+ }
+ } else if (name[0] == 'i') {
+ if (name[1] == 'n') {
+ if (len == 4 && !strncmp(&name[2], "t8", 2)) {
+ return LY_TYPE_INT8;
+ } else if (len == 5) {
+ if (!strncmp(&name[2], "t16", 3)) {
+ return LY_TYPE_INT16;
+ } else if (!strncmp(&name[2], "t32", 3)) {
+ return LY_TYPE_INT32;
+ } else if (!strncmp(&name[2], "t64", 3)) {
+ return LY_TYPE_INT64;
+ }
+ } else if (len == 19 && !strncmp(&name[2], "stance-identifier", 17)) {
+ return LY_TYPE_INST;
+ }
+ } else if (len == 11 && !strncmp(&name[1], "dentityref", 10)) {
+ return LY_TYPE_IDENT;
+ }
+ } else if (name[0] == 'l') {
+ if (len == 7 && !strncmp(&name[1], "eafref", 6)) {
+ return LY_TYPE_LEAFREF;
+ }
+ } else if (name[0] == 's') {
+ if (len == 6 && !strncmp(&name[1], "tring", 5)) {
+ return LY_TYPE_STRING;
+ }
+ } else if (name[0] == 'u') {
+ if (name[1] == 'n') {
+ if (len == 5 && !strncmp(&name[2], "ion", 3)) {
+ return LY_TYPE_UNION;
+ }
+ } else if (name[1] == 'i' && name[2] == 'n' && name[3] == 't') {
+ if (len == 5 && name[4] == '8') {
+ return LY_TYPE_UINT8;
+ } else if (len == 6) {
+ if (!strncmp(&name[4], "16", 2)) {
+ return LY_TYPE_UINT16;
+ } else if (!strncmp(&name[4], "32", 2)) {
+ return LY_TYPE_UINT32;
+ } else if (!strncmp(&name[4], "64", 2)) {
+ return LY_TYPE_UINT64;
+ }
+ }
+ }
+ }
+ }
+
+ return LY_TYPE_UNKNOWN;
+}
+
LY_ERR
lysp_type_find(const char *id, struct lysp_node *start_node, struct lysp_module *start_module,
- const struct lysp_tpdf **tpdf, struct lysp_node **node, struct lysp_module **module)
+ LY_DATA_TYPE *type, const struct lysp_tpdf **tpdf, struct lysp_node **node, struct lysp_module **module)
{
const char *str, *name;
struct lysp_tpdf *typedefs;
@@ -150,13 +247,22 @@
assert(node);
assert(module);
+ *node = NULL;
str = strchr(id, ':');
if (str) {
*module = lysp_module_find_prefix(start_module, id, str - id);
name = str + 1;
+ *type = LY_TYPE_UNKNOWN;
} else {
*module = start_module;
name = id;
+
+ /* check for built-in types */
+ *type = lysp_type_str2builtin(name, strlen(name));
+ if (*type) {
+ *tpdf = NULL;
+ return LY_SUCCESS;
+ }
}
LY_CHECK_RET(!(*module), LY_ENOTFOUND);
@@ -230,57 +336,10 @@
name = tpdf->name;
name_len = strlen(name);
- if (name_len >= 4) {
- /* otherwise it does not match any built-in type,
- * check collision with the built-in types */
- if (name[0] == 'b') {
- if (name[1] == 'i') {
- if ((name_len == 6 && !strcmp(&name[2], "nary")) || (name_len == 4 && !strcmp(&name[2], "ts"))) {
-collision:
- LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
- "Invalid name \"%s\" of typedef - name collision with a built-in type.", name);
- return LY_EEXIST;
- }
- } else if (name_len == 7 && !strcmp(&name[1], "oolean")) {
- goto collision;
- }
- } else if (name[0] == 'd') {
- if (name_len == 9 && !strcmp(&name[1], "ecimal64")) {
- goto collision;
- }
- } else if (name[0] == 'e') {
- if ((name_len == 5 && !strcmp(&name[1], "mpty")) || (name_len == 11 && !strcmp(&name[1], "numeration"))) {
- goto collision;
- }
- } else if (name[0] == 'i') {
- if (name[1] == 'n') {
- if ((name_len == 4 && !strcmp(&name[2], "t8")) ||
- (name_len == 5 && (!strcmp(&name[2], "t16") || !strcmp(&name[2], "t32") || !strcmp(&name[2], "t64"))) ||
- (name_len == 19 && !strcmp(&name[2], "stance-identifier"))) {
- goto collision;
- }
- } else if (name_len == 11 && !strcmp(&name[1], "dentityref")) {
- goto collision;
- }
- } else if (name[0] == 'l') {
- if (name_len == 7 && !strcmp(&name[1], "eafref")) {
- goto collision;
- }
- } else if (name[0] == 's') {
- if (name_len == 6 && !strcmp(&name[1], "tring")) {
- goto collision;
- }
- } else if (name[0] == 'u') {
- if (name[1] == 'n') {
- if (name_len == 5 && !strcmp(&name[2], "ion")) {
- goto collision;
- }
- } else if (name[1] == 'i' && name[2] == 'n' && name[3] == 't' &&
- ((name_len == 5 && !strcmp(&name[4], "8")) ||
- (name_len == 6 && (!strcmp(&name[4], "16") || !strcmp(&name[4], "32") || !strcmp(&name[4], "64"))))) {
- goto collision;
- }
- }
+ if (lysp_type_str2builtin(name, name_len)) {
+ LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_SYNTAX_YANG,
+ "Invalid name \"%s\" of typedef - name collision with a built-in type.", name);
+ return LY_EEXIST;
}
/* check locally scoped typedefs (avoid name shadowing) */
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index a73fb0a..24fbc9b 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -51,6 +51,17 @@
};
/**
+ * @brief internal context for compilation
+ */
+struct lysc_ctx {
+ struct ly_ctx *ctx;
+ struct lys_module *mod;
+ uint16_t path_len;
+#define LYSC_CTX_BUFSIZE 4078
+ char path[LYSC_CTX_BUFSIZE];
+};
+
+/**
* @brief Check the currently present prefixes in the module for collision with the new one.
*
* @param[in] ctx Context for logging.
@@ -91,12 +102,13 @@
* @param[in] id Name of the type including possible prefix. Module where the prefix is being searched is start_module.
* @param[in] start_node Context node where the type is being instantiated to be able to search typedefs in parents.
* @param[in] start_module Module where the type is being instantiated for search for typedefs.
+ * @param[out] type Built-in type identifier of the id. If #LY_TYPE_UNKNOWN, tpdf is expected to contain found YANG schema typedef statement.
* @param[out] tpdf Found type definition.
* @param[out] node Node where the found typedef is defined, NULL in case of a top-level typedef.
* @param[out] module Module where the found typedef is being defined, NULL in case of built-in YANG types.
*/
LY_ERR lysp_type_find(const char *id, struct lysp_node *start_node, struct lysp_module *start_module,
- const struct lysp_tpdf **tpdf, struct lysp_node **node, struct lysp_module **module);
+ LY_DATA_TYPE *type, const struct lysp_tpdf **tpdf, struct lysp_node **node, struct lysp_module **module);
/**
* @brief Find and parse module of the given name.
@@ -189,6 +201,26 @@
struct lysc_module *lysc_module_find_prefix(struct lysc_module *mod, const char *prefix, size_t len);
/**
+ * @brief Check statement's status for invalid combination.
+ *
+ * The modX parameters are used just to determine if both flags are in the same module,
+ * so any of the schema module structure can be used, but both modules must be provided
+ * in the same type.
+ *
+ * @param[in] ctx Compile context for logging.
+ * @param[in] flags1 Flags of the referencing node.
+ * @param[in] mod1 Module of the referencing node,
+ * @param[in] name1 Schema node name of the referencing node.
+ * @param[in] flags2 Flags of the referenced node.
+ * @param[in] mod2 Module of the referenced node,
+ * @param[in] name2 Schema node name of the referenced node.
+ * @return LY_ERR value
+ */
+LY_ERR lysc_check_status(struct lysc_ctx *ctx,
+ uint16_t flags1, void *mod1, const char *name1,
+ uint16_t flags2, void *mod2, const char *name2);
+
+/**
* @brief Find the module referenced by prefix in the provided mod.
*
* @param[in] mod Schema module where the prefix was used.