schema CHANGE redesign Sized arrays to be usable in a more simple way
diff --git a/src/common.h b/src/common.h
index 380ec6e..c704ca8 100644
--- a/src/common.h
+++ b/src/common.h
@@ -276,21 +276,53 @@
/**
* @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.
+ * @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[in] RETVAL Return value for the case of error (memory allocation failure).
*/
-#define LYSP_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
+#define LY_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
if (!(ARRAY)) { \
ARRAY = malloc(sizeof(uint32_t) + sizeof *(ARRAY)); \
*((uint32_t*)(ARRAY)) = 1; \
} else { \
- ++(*((uint32_t*)(ARRAY))); \
- ARRAY = ly_realloc(ARRAY, sizeof(uint32_t) + (*((uint32_t*)(ARRAY)) * sizeof *(ARRAY))); \
+ ++(*((uint32_t*)(ARRAY) - 1)); \
+ ARRAY = ly_realloc(((uint32_t*)(ARRAY) - 1), sizeof(uint32_t) + (*((uint32_t*)(ARRAY) - 1) * sizeof *(ARRAY))); \
LY_CHECK_ERR_RET(!(ARRAY), LOGMEM(CTX), RETVAL); \
} \
- (NEW_ITEM) = (void*)((uint32_t*)((ARRAY) + *((uint32_t*)(ARRAY)) - 1) + 1); \
- memset(NEW_ITEM, 0, sizeof *(NEW_ITEM));
+ 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
+ * when the items are filled.
+ *
+ * @param[in] CTX libyang context for logging.
+ * @param[in,out] ARRAY Pointer to the array to create.
+ * @param[in] SIZE Number of items the array is supposed to hold. The size of the allocated
+ * space is then counted from the type of the ARRAY, so do not provide placeholder void pointers.
+ * @param[in] RETVAL Return value for the case of error (memory allocation failure).
+ */
+#define LY_ARRAY_CREATE_RET(CTX, ARRAY, SIZE, RETVAL) \
+ ARRAY = calloc(1, sizeof(uint32_t) + SIZE * sizeof *(ARRAY)); \
+ LY_CHECK_ERR_RET(!(ARRAY), LOGMEM(CTX), RETVAL); \
+ ARRAY = (void*)((uint32_t*)(ARRAY) + 1)
+
+#define LY_ARRAY_INCREMENT(ARRAY) \
+ ++(*((uint32_t*)(ARRAY) - 1))
+/**
+ * @brief Free the space allocated for the ([sized array](@ref sizedarrays)).
+ *
+ * The items inside the array are not freed.
+ *
+ * @param[in] ARRAY A ([sized array](@ref sizedarrays)) to be freed.
+ */
+#define LY_ARRAY_FREE(ARRAY) \
+ if (ARRAY){free((uint32_t*)(ARRAY) - 1);}
#endif /* LY_COMMON_H_ */
diff --git a/src/libyang.h b/src/libyang.h
index bb93a74..060d49a 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -81,15 +81,15 @@
* @section sizedarrays Sized Arrays
*
* The structure starts with 32bit number storing size of the array - the number of the items inside. The size is part of the
- * array to allocate it together with the array itself only when it is needed. This way the memory demands are decreased with
- * possibility to have "infinite" (32bit) array of items. Because of a known size, it is not terminated by any special byte
- * (sequence), so there is also no limit for specific content of the stored records (e.g. that first byte must not be NULL).
+ * array to have it allocated together with the array itself only when it is needed. However, the pointers to the array always
+ * points after the 32b number, so items can be accessed directly as for standard C arrays. Because of a known size (available
+ * via ::LY_ARRAY_SIZE macro), it is not terminated by any special byte (sequence), so there is also no limitation for specific
+ * content of the stored records (e.g. that first byte must not be NULL).
*
- * Due to the structure, the records in the array cannot be accessed directly. There is a set of macros supposed to make
- * work with the arrays more easy.
+ * The sized arrays must be carefully freed (which should be done anyway only internally), since pointers to the sized arrays used
+ * in libyang structures, does not point to the beginning of the allocated space.
*
* - ::LY_ARRAY_SIZE
- * - ::LY_ARRAY_INDEX
* - ::LY_ARRAY_FOR
*
* @section struct_lists Lists
diff --git a/src/parser_yang.c b/src/parser_yang.c
index f46b901..434073d 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -1036,7 +1036,7 @@
struct lysp_ext_instance *e;
enum yang_keyword kw;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
/* store name and insubstmt info */
e->name = lydict_insert(ctx->ctx, ext_name, ext_name_len);
@@ -1299,7 +1299,7 @@
enum yang_keyword kw;
struct lysp_include *inc;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *includes, inc, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *includes, inc, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -1351,7 +1351,7 @@
enum yang_keyword kw;
struct lysp_import *imp;
- LYSP_ARRAY_NEW_RET(ctx->ctx, module->imports, imp, LY_EVALID);
+ LY_ARRAY_NEW_RET(ctx->ctx, module->imports, imp, LY_EVALID);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -1413,7 +1413,7 @@
enum yang_keyword kw;
struct lysp_revision *rev;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *revs, rev, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *revs, rev, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -1474,7 +1474,7 @@
enum yang_keyword kw;
/* allocate new pointer */
- LYSP_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, arg, &word, &buf, &word_len);
@@ -1679,7 +1679,7 @@
{
struct lysp_restr *restr;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
return parse_restr(ctx, data, restr_kw, restr);
}
@@ -1980,7 +1980,7 @@
enum yang_keyword kw;
struct lysp_type_enum *enm;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2226,7 +2226,7 @@
enum yang_keyword kw;
struct lysp_restr *restr;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2353,7 +2353,7 @@
break;
case YANG_TYPE:
{
- LYSP_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
}
ret = parse_type(ctx, data, nest_type);
break;
@@ -2786,7 +2786,7 @@
enum yang_keyword kw;
struct lysp_refine *rf;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *refines, rf, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *refines, rf, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2859,7 +2859,7 @@
enum yang_keyword kw;
struct lysp_tpdf *tpdf;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *typedefs, tpdf, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *typedefs, tpdf, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3006,7 +3006,7 @@
enum yang_keyword kw;
struct lysp_action *act;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *actions, act, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *actions, act, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3075,7 +3075,7 @@
enum yang_keyword kw;
struct lysp_notif *notif;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *notifs, notif, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *notifs, notif, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3163,7 +3163,7 @@
enum yang_keyword kw;
struct lysp_grp *grp;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *groupings, grp, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *groupings, grp, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3252,7 +3252,7 @@
enum yang_keyword kw;
struct lysp_augment *aug;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *augments, aug, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *augments, aug, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -3973,7 +3973,7 @@
enum yang_keyword kw;
struct lysp_ext *ex;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *extensions, ex, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *extensions, ex, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -4248,7 +4248,7 @@
enum yang_keyword kw;
struct lysp_deviation *dev;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *deviations, dev, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *deviations, dev, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -4306,7 +4306,7 @@
enum yang_keyword kw;
struct lysp_feature *feat;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *features, feat, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *features, feat, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -4361,7 +4361,7 @@
enum yang_keyword kw;
struct lysp_ident *ident;
- LYSP_ARRAY_NEW_RET(ctx->ctx, *identities, ident, LY_EMEM);
+ LY_ARRAY_NEW_RET(ctx->ctx, *identities, ident, LY_EMEM);
/* get value */
ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 73c4fad..3960bb3 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -28,10 +28,10 @@
#include "context.h"
#include "tree_schema_internal.h"
-#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, LY_ARRAY_INDEX(ARRAY, c__), dict);}free(ARRAY);}
+#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, *(LY_ARRAY_INDEX(ARRAY, c__, const char*)), DICT);}free(ARRAY);}
+#define FREE_STRINGS(CTX, ARRAY, DICT) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__], DICT);}LY_ARRAY_FREE(ARRAY);}
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);
@@ -122,16 +122,7 @@
lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident, int dict)
{
FREE_STRING(ctx, ident->name, dict);
- //FREE_STRINGS(ctx, ident->iffeatures, 1);
- {
- uint64_t c__;
- for (c__ = 0; ident->iffeatures && c__ < (*((uint32_t*)(ident->iffeatures))); ++c__) {
- if (1 && ((void*)((uint32_t*)((ident->iffeatures) + c__) + 1))) {
- lydict_remove(ctx, *((char**)((uint32_t*)((ident->iffeatures) + c__) + 1)));
- };
- }
- free(ident->iffeatures);
- }
+ FREE_STRINGS(ctx, ident->iffeatures, 1);
FREE_STRINGS(ctx, ident->bases, dict);
FREE_STRING(ctx, ident->dsc, dict);
FREE_STRING(ctx, ident->ref, dict);
@@ -460,7 +451,7 @@
static void
lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff, int UNUSED(dict))
{
- free(iff->features);
+ LY_ARRAY_FREE(iff->features);
free(iff->expr);
}
@@ -469,7 +460,7 @@
{
FREE_STRING(ctx, feat->name, dict);
FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
- free(feat->depfeatures);
+ LY_ARRAY_FREE(feat->depfeatures);
}
static void
@@ -600,7 +591,7 @@
/* we have the correct module, get the feature */
LY_ARRAY_FOR(mod->features, i) {
- f = LY_ARRAY_INDEX(mod->features, i);
+ f = &mod->features[i];
if (!strncmp(f->name, name, len) && f->name[len] == '\0') {
return f;
}
@@ -621,7 +612,7 @@
switch (op) {
case LYS_IFF_F:
/* resolve feature */
- return lysc_feature_value(*LY_ARRAY_INDEX(iff->features, (*index_f)++, struct lysc_feature*));
+ return lysc_feature_value(iff->features[(*index_f)++]);
case LYS_IFF_NOT:
/* invert result */
return lysc_iffeature_value_(iff, index_e, index_f) ? 0 : 1;
@@ -690,7 +681,7 @@
changed = ly_set_new();
for (u = 0; u < LY_ARRAY_SIZE(mod->features); ++u) {
- f = LY_ARRAY_INDEX(mod->features, u);
+ f = &mod->features[u];
if (all || !strcmp(f->name, name)) {
if ((value && (f->flags & LYS_FENABLED)) || (!value && !(f->flags & LYS_FENABLED))) {
if (all) {
@@ -802,7 +793,7 @@
/* search for the specified feature */
for (u = 0; u < LY_ARRAY_SIZE(mod->features); ++u) {
- f = LY_ARRAY_INDEX(mod->features, u);
+ f = &mod->features[u];
if (!strcmp(f->name, feature)) {
if (f->flags & LYS_FENABLED) {
return 1;
@@ -897,12 +888,11 @@
}
/* allocate the memory */
+ LY_ARRAY_CREATE_RET(ctx->mod->ctx, iff->features, f_size, LY_EMEM);
iff->expr = calloc((j = (expr_size / 4) + ((expr_size % 4) ? 1 : 0)), sizeof *iff->expr);
- iff->features = malloc(sizeof(uint32_t) + (f_size * sizeof *iff->features));
stack.stack = malloc(expr_size * sizeof *stack.stack);
- LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr || !iff->features, LOGMEM(ctx->mod->ctx), error);
+ LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr, LOGMEM(ctx->mod->ctx), error);
- *((uint32_t*)iff->features) = f_size;
stack.size = expr_size;
f_size--; expr_size--; /* used as indexes from now */
@@ -964,25 +954,11 @@
"Invalid value \"%s\" of if-feature - unable to find feature \"%.*s\".", value, j - i, &c[i]);
rc = LY_EINVAL,
error)
- *(LY_ARRAY_INDEX(iff->features, f_size, struct lysc_feature*)) = f;
+ iff->features[f_size] = f;
+ LY_ARRAY_INCREMENT(iff->features);
if (parent) {
/* and add itself into the dependants list */
- //LYSP_ARRAY_NEW_RET(ctx->mod->ctx, f->depfeatures, df, LY_EMEM);
- if (!(f->depfeatures)) {
- f->depfeatures = malloc(sizeof(uint32_t) + sizeof *(f->depfeatures));
- *((uint32_t*)(f->depfeatures)) = 1;
- } else {
- ++(*((uint32_t*)(f->depfeatures)));
- f->depfeatures = ly_realloc(f->depfeatures,
- sizeof(uint32_t) + (*((uint32_t*)(f->depfeatures)) * sizeof *(f->depfeatures)));
- if (!(f->depfeatures)) {
- ly_log(ctx->mod->ctx, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
- return LY_EMEM;
- };
- }
- (df) = (void*)((uint32_t*)((f->depfeatures) + *((uint32_t*)(f->depfeatures)) - 1) + 1);
- memset(df, 0, sizeof *(df));
-
+ LY_ARRAY_NEW_RET(ctx->mod->ctx, f->depfeatures, df, LY_EMEM);
*df = parent;
/* TODO check for circular dependency */
@@ -1028,13 +1004,12 @@
if (feature_p->iffeatures) {
/* allocate everything now */
- feature->iffeatures = calloc(1, sizeof(uint32_t) + (*((uint32_t*)(feature_p->iffeatures)) * sizeof *feature->iffeatures));
- *((uint32_t*)(feature->iffeatures)) = 0;
+ LY_ARRAY_CREATE_RET(ctx->mod->ctx, feature->iffeatures, LY_ARRAY_SIZE(feature_p->iffeatures), LY_EMEM);
for (u = 0; u < LY_ARRAY_SIZE(feature_p->iffeatures); ++u) {
- ret = lys_compile_iffeature(ctx, *LY_ARRAY_INDEX(feature_p->iffeatures, u, const char *), options, LY_ARRAY_INDEX(feature->iffeatures, u), feature);
+ ret = lys_compile_iffeature(ctx, feature_p->iffeatures[u], options, &feature->iffeatures[u], feature);
LY_CHECK_RET(ret);
- ++(*((uint32_t*)(feature->iffeatures)));
+ LY_ARRAY_INCREMENT(feature->iffeatures);
}
}
@@ -1075,13 +1050,12 @@
if (sp->features) {
/* allocate everything now */
- mod_c->features = calloc(1, sizeof(uint32_t) + (*((uint32_t*)(sp->features)) * sizeof *mod_c->features));
- *((uint32_t*)(mod_c->features)) = 0;
+ LY_ARRAY_CREATE_RET(ctx.mod->ctx, mod_c->features, LY_ARRAY_SIZE(sp->features), LY_EMEM);
for (u = 0; u < LY_ARRAY_SIZE(sp->features); ++u) {
- ret = lys_compile_feature(&ctx, LY_ARRAY_INDEX(sp->features, u), options, LY_ARRAY_INDEX(mod_c->features, u));
+ ret = lys_compile_feature(&ctx, &sp->features[u], options, &mod_c->features[u]);
LY_CHECK_GOTO(ret != LY_SUCCESS, error);
- ++(*((uint32_t*)(mod_c->features)));
+ LY_ARRAY_INCREMENT(mod_c->features);
}
}
@@ -1134,9 +1108,9 @@
if (revision) {
/* check revision of the parsed model */
- if (!mod->parsed->revs || strcmp(revision, LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev)) {
+ if (!mod->parsed->revs || strcmp(revision, mod->parsed->revs[0].rev)) {
LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
- mod->parsed->name, LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev, revision);
+ mod->parsed->name, mod->parsed->revs[0].rev, revision);
lysp_module_free(mod->parsed);
free(mod);
return NULL;
@@ -1264,9 +1238,9 @@
}
if (rev) {
len = dot - ++rev;
- if (!mod->parsed->revs || len != 10 || strncmp(LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev, rev, len)) {
+ if (!mod->parsed->revs || len != 10 || strncmp(mod->parsed->revs[0].rev, rev, len)) {
LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
- mod->parsed->revs ? LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev : "none");
+ mod->parsed->revs ? mod->parsed->revs[0].rev : "none");
}
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 2f23541..12394eb 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -32,16 +32,6 @@
#define LY_ARRAY_SELECT(_1, _2, NAME, ...) NAME
/**
- * @brief Get void pointer to the item on the INDEX in the ARRAY
- */
-#define LY_ARRAY_INDEX1(ARRAY, INDEX) ((void*)((uint32_t*)((ARRAY) + INDEX) + 1))
-
-/**
- * @brief Get the TYPE pointer to the item on the INDEX in the ARRAY
- */
-#define LY_ARRAY_INDEX2(ARRAY, INDEX, TYPE) ((TYPE*)((uint32_t*)((ARRAY) + INDEX) + 1))
-
-/**
* @brief Helper macro to go through sized-arrays with a pointer iterator.
*
* Use with opening curly bracket (`{`).
@@ -51,8 +41,8 @@
* @param[out] ITER Iterating pointer to the item being processed in each loop
*/
#define LY_ARRAY_FOR_ITER(ARRAY, TYPE, ITER) \
- for (ITER = LY_ARRAY_INDEX1(ARRAY, 0); \
- (ARRAY) && ((void*)ITER - (void*)ARRAY - sizeof(uint32_t))/(sizeof(TYPE)) < (*(uint32_t*)(ARRAY)); \
+ for (ITER = ARRAY; \
+ (ARRAY) && ((void*)ITER - (void*)ARRAY)/(sizeof(TYPE)) < (*((uint32_t*)(ARRAY) - 1)); \
ITER = (void*)((TYPE*)ITER + 1))
/**
@@ -67,7 +57,7 @@
*/
#define LY_ARRAY_FOR_INDEX(ARRAY, INDEX) \
for (INDEX = 0; \
- ARRAY && INDEX < (*((uint32_t*)(ARRAY))); \
+ ARRAY && INDEX < (*((uint32_t*)(ARRAY) - 1)); \
++INDEX)
/**
@@ -78,18 +68,11 @@
*/
/**
- * @brief Get (optionally TYPEd) pointer to the item on the INDEX in the ARRAY
- *
- * LY_ARRAY_INDEX(ARRAY, INDEX [, TYPE])
- */
-#define LY_ARRAY_INDEX(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_INDEX2, LY_ARRAY_INDEX1)(ARRAY, __VA_ARGS__)
-
-/**
* @brief Get a number of records in the ARRAY.
*
* Does not check if array exists!
*/
-#define LY_ARRAY_SIZE(ARRAY) (*((uint32_t*)(ARRAY)))
+#define LY_ARRAY_SIZE(ARRAY) (*((uint32_t*)(ARRAY) - 1))
/**
* @brief Sized-array iterator (for-loop).
@@ -106,8 +89,7 @@
* LY_ARRAY_FOR(ARRAY, INDEX)
*
* The ARRAY is again a sized-array to go through, the INDEX is a variable (unsigned integer) for storing iterating ARRAY's index
- * to access the items of ARRAY in the loops. The INDEX is supposed to be used via LY_ARRAY_INDEX macro which can provide the item
- * in the loop body. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
+ * to access the items of ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
*/
#define LY_ARRAY_FOR(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_FOR_ITER, LY_ARRAY_FOR_INDEX)(ARRAY, __VA_ARGS__)
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index c08068a..0d0620c 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -92,17 +92,16 @@
struct lysp_revision rev;
for (i = 1, r = 0; revs && i < LY_ARRAY_SIZE(revs); i++) {
- if (strcmp(LY_ARRAY_INDEX(revs, i, struct lysp_revision)->rev,
- LY_ARRAY_INDEX(revs, r, struct lysp_revision)->rev) > 0) {
+ if (strcmp(revs[i].rev, revs[r].rev) > 0) {
r = i;
}
}
if (r) {
/* the newest revision is not on position 0, switch them */
- memcpy(&rev, LY_ARRAY_INDEX(revs, 0), sizeof rev);
- memcpy(LY_ARRAY_INDEX(revs, 0), LY_ARRAY_INDEX(revs, r), sizeof rev);
- memcpy(LY_ARRAY_INDEX(revs, r), &rev, sizeof rev);
+ memcpy(&rev, &revs[0], sizeof rev);
+ memcpy(&revs[0], &revs[r], sizeof rev);
+ memcpy(&revs[r], &rev, sizeof rev);
}
}
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index e6fec3c..db73f63 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -725,7 +725,7 @@
TEST_NODE(LYS_ANYXML, "anyxml test;}", "test");
/* augment */
TEST_GENERIC("augment /somepath;}", mod->augments,
- assert_string_equal("/somepath", LY_ARRAY_INDEX(mod->augments, 0, struct lysp_augment)->nodeid));
+ assert_string_equal("/somepath", mod->augments[0].nodeid));
/* choice */
TEST_NODE(LYS_CHOICE, "choice test;}", "test");
/* contact 0..1 */
@@ -738,22 +738,22 @@
assert_string_equal("some description", mod->dsc));
/* deviation */
TEST_GENERIC("deviation /somepath {deviate not-supported;}}", mod->deviations,
- assert_string_equal("/somepath", LY_ARRAY_INDEX(mod->deviations, 0, struct lysp_deviation)->nodeid));
+ assert_string_equal("/somepath", mod->deviations[0].nodeid));
/* extension */
TEST_GENERIC("extension test;}", mod->extensions,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->extensions, 0, struct lysp_ext)->name));
+ assert_string_equal("test", mod->extensions[0].name));
/* feature */
TEST_GENERIC("feature test;}", mod->features,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->features, 0, struct lysp_feature)->name));
+ assert_string_equal("test", mod->features[0].name));
/* grouping */
TEST_GENERIC("grouping grp;}", mod->groupings,
- assert_string_equal("grp", LY_ARRAY_INDEX(mod->groupings, 0, struct lysp_grp)->name));
+ assert_string_equal("grp", mod->groupings[0].name));
/* identity */
TEST_GENERIC("identity test;}", mod->identities,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->identities, 0, struct lysp_ident)->name));
+ assert_string_equal("test", mod->identities[0].name));
/* import */
TEST_GENERIC("import test {prefix z;}}", mod->imports,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->imports, 0, struct lysp_import)->name));
+ assert_string_equal("test", mod->imports[0].name));
/* import - prefix collision */
str = SCHEMA_BEGINNING "import test {prefix x;}}";
@@ -767,7 +767,7 @@
/* include */
TEST_GENERIC("include test;}", mod->includes,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->includes, 0, struct lysp_include)->name));
+ assert_string_equal("test", mod->includes[0].name));
/* leaf */
TEST_NODE(LYS_LEAF, "leaf test {type string;}}", "test");
/* leaf-list */
@@ -776,7 +776,7 @@
TEST_NODE(LYS_LIST, "list test {key a;leaf a {type string;}}}", "test");
/* notification */
TEST_GENERIC("notification test;}", mod->notifs,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->notifs, 0, struct lysp_notif)->name));
+ assert_string_equal("test", mod->notifs[0].name));
/* organization 0..1 */
TEST_GENERIC("organization \"CESNET a.l.e.\";}", mod->org,
assert_string_equal("CESNET a.l.e.", mod->org));
@@ -785,13 +785,13 @@
assert_string_equal("RFC7950", mod->ref));
/* revision */
TEST_GENERIC("revision 2018-10-12;}", mod->revs,
- assert_string_equal("2018-10-12", LY_ARRAY_INDEX(mod->revs, 0, struct lysp_revision)->rev));
+ assert_string_equal("2018-10-12", mod->revs[0].rev));
/* rpc */
TEST_GENERIC("rpc test;}", mod->rpcs,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->rpcs, 0, struct lysp_action)->name));
+ assert_string_equal("test", mod->rpcs[0].name));
/* typedef */
TEST_GENERIC("typedef test{type string;}}", mod->typedefs,
- assert_string_equal("test", LY_ARRAY_INDEX(mod->typedefs, 0, struct lysp_tpdf)->name));
+ assert_string_equal("test", mod->typedefs[0].name));
/* uses */
TEST_NODE(LYS_USES, "uses test;}", "test");
/* yang-version */
@@ -814,8 +814,8 @@
/* extensions */
TEST_GENERIC("prefix:test;}", mod->exts,
- assert_string_equal("prefix:test", LY_ARRAY_INDEX(mod->exts, 0, struct lysp_ext_instance)->name);
- assert_int_equal(LYEXT_SUBSTMT_SELF, LY_ARRAY_INDEX(mod->exts, 0, struct lysp_ext_instance)->insubstmt));
+ assert_string_equal("prefix:test", mod->exts[0].name);
+ assert_int_equal(LYEXT_SUBSTMT_SELF, mod->exts[0].insubstmt));
mod = mod_renew(&ctx, mod, 0);
/* invalid substatement */
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 8e72276..79c7c42 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -94,14 +94,14 @@
/* features */
assert_non_null(mod.compiled->features);
assert_int_equal(2, LY_ARRAY_SIZE(mod.compiled->features));
- f = LY_ARRAY_INDEX(mod.compiled->features, 1);
+ f = &mod.compiled->features[1];
assert_non_null(f->iffeatures);
assert_int_equal(1, LY_ARRAY_SIZE(f->iffeatures));
- iff = LY_ARRAY_INDEX(f->iffeatures, 0);
+ iff = &f->iffeatures[0];
assert_non_null(iff->expr);
assert_non_null(iff->features);
assert_int_equal(1, LY_ARRAY_SIZE(iff->features));
- assert_ptr_equal(LY_ARRAY_INDEX(mod.compiled->features, 0), *LY_ARRAY_INDEX(iff->features, 0, struct lysc_feature*));
+ assert_ptr_equal(&mod.compiled->features[0], iff->features[0]);
lysc_module_free(mod.compiled, NULL);
@@ -153,17 +153,17 @@
}
/* enable f1 */
assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f1"));
- f1 = LY_ARRAY_INDEX(mod.compiled->features, 0);
+ f1 = &mod.compiled->features[0];
assert_int_equal(1, lysc_feature_value(f1));
/* enable f4 */
- f = LY_ARRAY_INDEX(mod.compiled->features, 3);
+ f = &mod.compiled->features[3];
assert_int_equal(0, lysc_feature_value(f));
assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f4"));
assert_int_equal(1, lysc_feature_value(f));
/* enable f5 - no possible since f2 is disabled */
- f = LY_ARRAY_INDEX(mod.compiled->features, 4);
+ f = &mod.compiled->features[4];
assert_int_equal(0, lysc_feature_value(f));
assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "f5"));
logbuf_assert("Feature \"f5\" cannot be enabled since it is disabled by its if-feature condition(s).");
@@ -175,7 +175,7 @@
assert_int_equal(1, lysc_feature_value(f));
/* f1 is enabled, so f6 cannot be enabled */
- f = LY_ARRAY_INDEX(mod.compiled->features, 5);
+ f = &mod.compiled->features[5];
assert_int_equal(0, lysc_feature_value(f));
assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "f6"));
logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
@@ -183,19 +183,17 @@
/* so disable f1 - f5 will became also disabled */
assert_int_equal(1, lysc_feature_value(f1));
- f = LY_ARRAY_INDEX(mod.compiled->features, 4);
assert_int_equal(LY_SUCCESS, lys_feature_disable(&mod, "f1"));
assert_int_equal(0, lysc_feature_value(f1));
- assert_int_equal(0, lysc_feature_value(f));
+ assert_int_equal(0, lysc_feature_value(&mod.compiled->features[4]));
/* while f4 is stille enabled */
- assert_int_equal(1, lysc_feature_value(LY_ARRAY_INDEX(mod.compiled->features, 3)));
+ assert_int_equal(1, lysc_feature_value(&mod.compiled->features[3]));
/* and finally f6 can be enabled */
- f = LY_ARRAY_INDEX(mod.compiled->features, 5);
assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f6"));
- assert_int_equal(1, lysc_feature_value(f));
+ assert_int_equal(1, lysc_feature_value(&mod.compiled->features[5]));
/* complex evaluation of f7: f1 and f3 are disabled, while f2 is enabled */
- assert_int_equal(1, lysc_iffeature_value(LY_ARRAY_INDEX(LY_ARRAY_INDEX(mod.compiled->features, 6, struct lysc_feature)->iffeatures, 0)));
+ assert_int_equal(1, lysc_iffeature_value(&mod.compiled->features[6].iffeatures[0]));
lysc_module_free(mod.compiled, NULL);
lysp_module_free(mod.parsed);
diff --git a/tests/src/test_tree_schema_helpers.c b/tests/src/test_tree_schema_helpers.c
index 67f4138..3dc7d7c 100644
--- a/tests/src/test_tree_schema_helpers.c
+++ b/tests/src/test_tree_schema_helpers.c
@@ -90,20 +90,20 @@
logbuf_assert("");
/* revisions are stored in wrong order - the newest is the last */
- LYSP_ARRAY_NEW_RET(NULL, revs, rev,);
+ LY_ARRAY_NEW_RET(NULL, revs, rev,);
strcpy(rev->rev, "2018-01-01");
- LYSP_ARRAY_NEW_RET(NULL, revs, rev,);
+ LY_ARRAY_NEW_RET(NULL, revs, rev,);
strcpy(rev->rev, "2018-12-31");
assert_int_equal(2, LY_ARRAY_SIZE(revs));
- assert_string_equal("2018-01-01", LY_ARRAY_INDEX(revs, 0));
- assert_string_equal("2018-12-31", LY_ARRAY_INDEX(revs, 1));
+ assert_string_equal("2018-01-01", &revs[0]);
+ assert_string_equal("2018-12-31", &revs[1]);
/* the order should be fixed, so the newest revision will be the first in the array */
lysp_sort_revisions(revs);
- assert_string_equal("2018-12-31", LY_ARRAY_INDEX(revs, 0));
- assert_string_equal("2018-01-01", LY_ARRAY_INDEX(revs, 1));
+ assert_string_equal("2018-12-31", &revs[0]);
+ assert_string_equal("2018-01-01", &revs[1]);
- free(revs);
+ LY_ARRAY_FREE(revs);
}
int main(void)