extension instances CHANGE access to the extension instance's substatements
Provide libyang a transparent access to the substatements of a specific
extension instances for various generic processing.
The patch introduces lysc_ext_substmt() to simplify work with the newly
added lysc_ext_instance.substmts sized array providing the extension
instance's substatements.
diff --git a/src/schema_compile.c b/src/schema_compile.c
index d0c2976..07133d7 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -205,6 +205,37 @@
return orig;
}
+LY_ERR
+lysc_ext_substmt(const struct lysc_ext_instance *ext, enum ly_stmt substmt, void **instance_p, enum ly_stmt_cardinality *cardinality_p)
+{
+ LY_ARRAY_COUNT_TYPE u;
+
+ LY_ARRAY_FOR(ext->substmts, u) {
+ if (LY_STMT_IS_NODE(substmt)) {
+ if (!LY_STMT_IS_NODE(ext->substmts[u].stmt)) {
+ continue;
+ }
+ } else if (LY_STMT_IS_OP(substmt)) {
+ if (!LY_STMT_IS_OP(ext->substmts[u].stmt)) {
+ continue;
+ }
+ } else if (ext->substmts[u].stmt != substmt) {
+ continue;
+ }
+
+ /* match */
+ if (cardinality_p) {
+ *cardinality_p = ext->substmts[u].cardinality;
+ }
+ if (instance_p) {
+ *instance_p = ext->substmts[u].storage;
+ }
+ return LY_SUCCESS;
+ }
+
+ return LY_ENOT;
+}
+
static void
lysc_unres_dflt_free(const struct ly_ctx *ctx, struct lysc_unres_dflt *r)
{
@@ -602,12 +633,12 @@
if (stmt->flags & (LYS_YIN_ATTR | LYS_YIN_ARGUMENT)) {
continue;
}
- for (u = 0; substmts[u].stmt; ++u) {
+ LY_ARRAY_FOR(substmts, u) {
if (substmts[u].stmt == stmt->kw) {
break;
}
}
- if (!substmts[u].stmt) {
+ if (u == LY_ARRAY_COUNT(substmts)) {
LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s%s%s\" extension instance.",
stmt->stmt, ext->name, ext->argument ? " " : "", ext->argument ? ext->argument : "");
goto cleanup;
@@ -618,7 +649,7 @@
/* keep order of the processing the same as the order in the defined substmts,
* the order is important for some of the statements depending on others (e.g. type needs status and units) */
- for (u = 0; substmts[u].stmt; ++u) {
+ LY_ARRAY_FOR(substmts, u) {
ly_bool stmt_present = 0;
for (stmt = ext->child; stmt; stmt = stmt->next) {
@@ -633,6 +664,8 @@
assert(substmts[u].cardinality < LY_STMT_CARD_SOME);
LY_CHECK_ERR_GOTO(r = lysp_stmt_parse(ctx, stmt, &substmts[u].storage, /* TODO */ NULL), ret = r, cleanup);
break;
+ case LY_STMT_DESCRIPTION:
+ case LY_STMT_REFERENCE:
case LY_STMT_UNITS: {
const char **units;