xpath RFEACTOR expr_dup LY_ERR return (#1206)
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 720351a..d7f0872 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -2521,9 +2521,8 @@
*/
static LY_ERR
lys_compile_type_(struct lysc_ctx *ctx, struct lysp_node *context_node_p, uint16_t context_flags,
- struct lysp_module *context_mod, const char *context_name, struct lysp_type *type_p,
- struct lys_module *module, LY_DATA_TYPE basetype, const char *tpdfname, struct lysc_type *base,
- struct lysc_type **type)
+ struct lysp_module *context_mod, const char *context_name, struct lysp_type *type_p, struct lys_module *module,
+ LY_DATA_TYPE basetype, const char *tpdfname, struct lysc_type *base, struct lysc_type **type)
{
LY_ERR ret = LY_SUCCESS;
struct lysc_type_bin *bin;
@@ -2545,14 +2544,9 @@
LY_CHECK_RET(lys_compile_type_range(ctx, type_p->length, basetype, 1, 0,
base ? ((struct lysc_type_bin *)base)->length : NULL, &bin->length));
if (!tpdfname) {
- COMPILE_EXTS_GOTO(ctx, type_p->length->exts, bin->length->exts, bin->length, LYEXT_PAR_LENGTH, ret, done);
+ COMPILE_EXTS_GOTO(ctx, type_p->length->exts, bin->length->exts, bin->length, LYEXT_PAR_LENGTH, ret, cleanup);
}
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_bin));
- }
break;
case LY_TYPE_BITS:
/* RFC 7950 9.7 - bits */
@@ -2569,16 +2563,9 @@
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "bit", "bits type ", tpdfname);
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "bit", "bits type", "");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_bits));
- }
break;
case LY_TYPE_DEC64:
dec = (struct lysc_type_dec *)(*type);
@@ -2590,8 +2577,6 @@
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type ", tpdfname);
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type", "");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
@@ -2606,8 +2591,6 @@
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
"Invalid fraction-digits substatement for type not directly derived from decimal64 built-in type.");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
@@ -2619,14 +2602,9 @@
LY_CHECK_RET(lys_compile_type_range(ctx, type_p->range, basetype, 0, dec->fraction_digits,
base ? ((struct lysc_type_dec *)base)->range : NULL, &dec->range));
if (!tpdfname) {
- COMPILE_EXTS_GOTO(ctx, type_p->range->exts, dec->range->exts, dec->range, LYEXT_PAR_RANGE, ret, done);
+ COMPILE_EXTS_GOTO(ctx, type_p->range->exts, dec->range->exts, dec->range, LYEXT_PAR_RANGE, ret, cleanup);
}
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_dec));
- }
break;
case LY_TYPE_STRING:
str = (struct lysc_type_str *)(*type);
@@ -2636,7 +2614,7 @@
LY_CHECK_RET(lys_compile_type_range(ctx, type_p->length, basetype, 1, 0,
base ? ((struct lysc_type_str *)base)->length : NULL, &str->length));
if (!tpdfname) {
- COMPILE_EXTS_GOTO(ctx, type_p->length->exts, str->length->exts, str->length, LYEXT_PAR_LENGTH, ret, done);
+ COMPILE_EXTS_GOTO(ctx, type_p->length->exts, str->length->exts, str->length, LYEXT_PAR_LENGTH, ret, cleanup);
}
} else if (base && ((struct lysc_type_str *)base)->length) {
str->length = lysc_range_dup(ctx->ctx, ((struct lysc_type_str *)base)->length);
@@ -2649,11 +2627,6 @@
} else if (base && ((struct lysc_type_str *)base)->patterns) {
str->patterns = lysc_patterns_dup(ctx->ctx, ((struct lysc_type_str *)base)->patterns);
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_str));
- }
break;
case LY_TYPE_ENUM:
enumeration = (struct lysc_type_enum *)(*type);
@@ -2670,16 +2643,9 @@
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type ", tpdfname);
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type", "");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_enum));
- }
break;
case LY_TYPE_INT8:
case LY_TYPE_UINT8:
@@ -2696,14 +2662,9 @@
LY_CHECK_RET(lys_compile_type_range(ctx, type_p->range, basetype, 0, 0,
base ? ((struct lysc_type_num *)base)->range : NULL, &num->range));
if (!tpdfname) {
- COMPILE_EXTS_GOTO(ctx, type_p->range->exts, num->range->exts, num->range, LYEXT_PAR_RANGE, ret, done);
+ COMPILE_EXTS_GOTO(ctx, type_p->range->exts, num->range->exts, num->range, LYEXT_PAR_RANGE, ret, cleanup);
}
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_num));
- }
break;
case LY_TYPE_IDENT:
idref = (struct lysc_type_identityref *)(*type);
@@ -2719,8 +2680,6 @@
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
"Invalid base substatement for the type not directly derived from identityref built-in type.");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
@@ -2733,16 +2692,9 @@
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "base", "identityref type ", tpdfname);
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "base", "identityref type", "");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_identityref));
- }
break;
case LY_TYPE_LEAFREF:
lref = (struct lysc_type_leafref *)*type;
@@ -2756,8 +2708,6 @@
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
"Leafref type can be restricted by require-instance statement only in YANG 1.1 modules.");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
@@ -2770,24 +2720,18 @@
lref->require_instance = 1;
}
if (type_p->path) {
- lref->path = lyxp_expr_dup(ctx->ctx, type_p->path);
+ LY_CHECK_RET(lyxp_expr_dup(ctx->ctx, type_p->path, &lref->path));
lref->path_context = module;
} else if (base) {
- lref->path = lyxp_expr_dup(ctx->ctx, ((struct lysc_type_leafref *)base)->path);
+ LY_CHECK_RET(lyxp_expr_dup(ctx->ctx, ((struct lysc_type_leafref *)base)->path, &lref->path));
lref->path_context = ((struct lysc_type_leafref *)base)->path_context;
} else if (tpdfname) {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "path", "leafref type ", tpdfname);
return LY_EVALID;
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "path", "leafref type", "");
- free(*type);
- *type = NULL;
return LY_EVALID;
}
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_leafref));
- }
break;
case LY_TYPE_INST:
/* RFC 7950 9.9.3 - require-instance */
@@ -2797,11 +2741,6 @@
/* default is true */
((struct lysc_type_instanceid *)(*type))->require_instance = 1;
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_instanceid));
- }
break;
case LY_TYPE_UNION:
un = (struct lysc_type_union *)(*type);
@@ -2817,8 +2756,6 @@
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
"Invalid type substatement for the type not directly derived from union built-in type.");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
@@ -2842,7 +2779,7 @@
lref = (struct lysc_type_leafref *)un->types[u + additional];
lref->basetype = LY_TYPE_LEAFREF;
- lref->path = lyxp_expr_dup(ctx->ctx, ((struct lysc_type_leafref *)un_aux->types[v])->path);
+ LY_CHECK_RET(lyxp_expr_dup(ctx->ctx, ((struct lysc_type_leafref *)un_aux->types[v])->path, &lref->path));
lref->refcount = 1;
lref->require_instance = ((struct lysc_type_leafref *)un_aux->types[v])->require_instance;
lref->path_context = ((struct lysc_type_leafref *)un_aux->types[v])->path_context;
@@ -2872,24 +2809,74 @@
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "type", "union type ", tpdfname);
} else {
LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "type", "union type", "");
- free(*type);
- *type = NULL;
}
return LY_EVALID;
}
-
- if (tpdfname) {
- type_p->compiled = *type;
- *type = calloc(1, sizeof(struct lysc_type_union));
- }
break;
case LY_TYPE_BOOL:
case LY_TYPE_EMPTY:
case LY_TYPE_UNKNOWN: /* just to complete switch */
break;
}
+
+ if (tpdfname) {
+ switch (basetype) {
+ case LY_TYPE_BINARY:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_bin));
+ break;
+ case LY_TYPE_BITS:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_bits));
+ break;
+ case LY_TYPE_DEC64:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_dec));
+ break;
+ case LY_TYPE_STRING:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_str));
+ break;
+ case LY_TYPE_ENUM:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_enum));
+ 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_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_num));
+ break;
+ case LY_TYPE_IDENT:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_identityref));
+ break;
+ case LY_TYPE_LEAFREF:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_leafref));
+ break;
+ case LY_TYPE_INST:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_instanceid));
+ break;
+ case LY_TYPE_UNION:
+ type_p->compiled = *type;
+ *type = calloc(1, sizeof(struct lysc_type_union));
+ break;
+ case LY_TYPE_BOOL:
+ case LY_TYPE_EMPTY:
+ case LY_TYPE_UNKNOWN: /* just to complete switch */
+ break;
+ }
+ }
LY_CHECK_ERR_RET(!(*type), LOGMEM(ctx->ctx), LY_EMEM);
-done:
+
+cleanup:
return ret;
}
diff --git a/src/xpath.c b/src/xpath.c
index 4691984..0648706 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -2949,29 +2949,30 @@
return ret;
}
-struct lyxp_expr *
-lyxp_expr_dup(const struct ly_ctx *ctx, const struct lyxp_expr *exp)
+LY_ERR
+lyxp_expr_dup(const struct ly_ctx *ctx, const struct lyxp_expr *exp, struct lyxp_expr **dup_p)
{
- struct lyxp_expr *dup;
+ LY_ERR ret = LY_SUCCESS;
+ struct lyxp_expr *dup = NULL;
uint32_t i, j;
dup = calloc(1, sizeof *dup);
- LY_CHECK_ERR_GOTO(!dup, LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup, LOGMEM(ctx); ret = LY_EMEM, cleanup);
dup->tokens = malloc(exp->used * sizeof *dup->tokens);
- LY_CHECK_ERR_GOTO(!dup->tokens, LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup->tokens, LOGMEM(ctx); ret = LY_EMEM, cleanup);
memcpy(dup->tokens, exp->tokens, exp->used * sizeof *dup->tokens);
dup->tok_pos = malloc(exp->used * sizeof *dup->tok_pos);
- LY_CHECK_ERR_GOTO(!dup->tok_pos, LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup->tok_pos, LOGMEM(ctx); ret = LY_EMEM, cleanup);
memcpy(dup->tok_pos, exp->tok_pos, exp->used * sizeof *dup->tok_pos);
dup->tok_len = malloc(exp->used * sizeof *dup->tok_len);
- LY_CHECK_ERR_GOTO(!dup->tok_len, LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup->tok_len, LOGMEM(ctx); ret = LY_EMEM, cleanup);
memcpy(dup->tok_len, exp->tok_len, exp->used * sizeof *dup->tok_len);
dup->repeat = malloc(exp->used * sizeof *dup->repeat);
- LY_CHECK_ERR_GOTO(!dup->repeat, LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup->repeat, LOGMEM(ctx); ret = LY_EMEM, cleanup);
for (i = 0; i < exp->used; ++i) {
if (!exp->repeat[i]) {
dup->repeat[i] = NULL;
@@ -2981,7 +2982,7 @@
++j;
dup->repeat[i] = malloc(j * sizeof **dup->repeat);
- LY_CHECK_ERR_GOTO(!dup->repeat[i], LOGMEM(ctx), error);
+ LY_CHECK_ERR_GOTO(!dup->repeat[i], LOGMEM(ctx); ret = LY_EMEM, cleanup);
memcpy(dup->repeat[i], exp->repeat[i], j * sizeof **dup->repeat);
dup->repeat[i][j - 1] = 0;
}
@@ -2989,13 +2990,15 @@
dup->used = exp->used;
dup->size = exp->used;
- LY_CHECK_GOTO(lydict_insert(ctx, exp->expr, 0, &dup->expr), error);
+ LY_CHECK_GOTO(ret = lydict_insert(ctx, exp->expr, 0, &dup->expr), cleanup);
- return dup;
-
-error:
- lyxp_expr_free(ctx, dup);
- return NULL;
+cleanup:
+ if (ret) {
+ lyxp_expr_free(ctx, dup);
+ } else {
+ *dup_p = dup;
+ }
+ return ret;
}
/*
diff --git a/src/xpath.h b/src/xpath.h
index 20498cd..099f810 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -390,9 +390,10 @@
*
* @param[in] ctx Context with a dictionary.
* @param[in] exp Parsed expression.
- * @return Duplicated structure, NULL on error.
+ * @param[out] dup Duplicated structure.
+ * @return LY_ERR value.
*/
-struct lyxp_expr *lyxp_expr_dup(const struct ly_ctx *ctx, const struct lyxp_expr *exp);
+LY_ERR lyxp_expr_dup(const struct ly_ctx *ctx, const struct lyxp_expr *exp, struct lyxp_expr **dup);
/**
* @brief Look at the next token and check its kind.