#ifndef LY_SCHEMA_COMPILE_H_
#define LY_SCHEMA_COMPILE_H_
#include <stddef.h>
#include <stdint.h>
#include "log.h"
#include "plugins_exts.h"
#include "set.h"
#include "tree.h"
#include "tree_schema.h"
#include "tree_schema_free.h"
struct lyxp_expr;
struct lysc_ctx {
struct ly_ctx *ctx;
struct lys_module *cur_mod;
struct lysp_module *pmod;
struct lysc_ext_instance *ext;
struct ly_set groupings;
struct ly_set tpdf_chain;
struct ly_set augs;
struct ly_set devs;
struct ly_set uses_augs;
struct ly_set uses_rfns;
struct lys_depset_unres *unres;
uint32_t path_len;
uint32_t compile_opts;
#define LYSC_CTX_BUFSIZE 4078
char path[LYSC_CTX_BUFSIZE];
};
#define LYSC_CTX_INIT_CTX(CCTX, CTX) \
(CCTX).ctx = (CTX); \
(CCTX).path_len = 1; \
(CCTX).path[0] = '/'
#define LYSC_CTX_INIT_PMOD(CCTX, PMOD, EXT) \
(CCTX).ctx = (PMOD)->mod->ctx; \
(CCTX).cur_mod = (PMOD)->mod; \
(CCTX).pmod = (PMOD); \
(CCTX).ext = (EXT); \
(CCTX).path_len = 1; \
(CCTX).path[0] = '/'
struct lys_depset_unres {
struct ly_set whens;
struct ly_set musts;
struct ly_set leafrefs;
struct ly_set dflts;
struct ly_set disabled;
struct ly_set disabled_leafrefs;
struct ly_set disabled_bitenums;
};
struct lys_glob_unres {
struct ly_set dep_sets;
struct ly_set implementing;
struct ly_set creating;
struct lys_depset_unres ds_unres;
};
struct lysc_unres_when {
struct lysc_node *node;
struct lysc_when *when;
};
struct lysc_unres_must {
struct lysc_node *node;
const struct lysp_module **local_mods;
struct lysc_ext_instance *ext;
};
struct lysc_unres_leafref {
struct lysc_node *node;
const struct lysp_module *local_mod;
struct lysc_ext_instance *ext;
};
struct lysc_unres_dflt {
union {
struct lysc_node_leaf *leaf;
struct lysc_node_leaflist *llist;
};
struct lysp_qname *dflt;
struct lysp_qname *dflts;
};
#define DUP_STRING(CTX, ORIG, DUP, RET) RET = lysdict_dup(CTX, ORIG, &(DUP))
#define DUP_STRING_RET(CTX, ORIG, DUP) LY_CHECK_RET(lysdict_dup(CTX, ORIG, &(DUP)))
#define DUP_STRING_GOTO(CTX, ORIG, DUP, RET, GOTO) LY_CHECK_GOTO(RET = lysdict_dup(CTX, ORIG, &(DUP)), GOTO)
#define DUP_ARRAY(CTX, ORIG_ARRAY, NEW_ARRAY, DUP_FUNC) \
if (ORIG_ARRAY) { \
LY_ARRAY_COUNT_TYPE __u; \
LY_ARRAY_CREATE_RET(CTX, NEW_ARRAY, LY_ARRAY_COUNT(ORIG_ARRAY), LY_EMEM); \
LY_ARRAY_FOR(ORIG_ARRAY, __u) { \
LY_ARRAY_INCREMENT(NEW_ARRAY); \
LY_CHECK_RET(DUP_FUNC(CTX, &(ORIG_ARRAY)[__u], &(NEW_ARRAY)[__u])); \
} \
}
#define DUP_ARRAY2(CTX, PMOD, ORIG_ARRAY, NEW_ARRAY, DUP_FUNC) \
if (ORIG_ARRAY) { \
LY_ARRAY_COUNT_TYPE __u; \
LY_ARRAY_CREATE_RET(CTX, NEW_ARRAY, LY_ARRAY_COUNT(ORIG_ARRAY), LY_EMEM); \
LY_ARRAY_FOR(ORIG_ARRAY, __u) { \
LY_ARRAY_INCREMENT(NEW_ARRAY); \
LY_CHECK_RET(DUP_FUNC(CTX, PMOD, &(ORIG_ARRAY)[__u], &(NEW_ARRAY)[__u])); \
} \
}
#define DUP_EXTS(CTX, PMOD, PARENT, PARENT_STMT, ORIG_ARRAY, NEW_ARRAY, DUP_FUNC) \
if (ORIG_ARRAY) { \
LY_ARRAY_COUNT_TYPE __u, __new_start; \
__new_start = LY_ARRAY_COUNT(NEW_ARRAY); \
LY_ARRAY_CREATE_RET(CTX, NEW_ARRAY, LY_ARRAY_COUNT(ORIG_ARRAY), LY_EMEM); \
LY_ARRAY_FOR(ORIG_ARRAY, __u) { \
LY_ARRAY_INCREMENT(NEW_ARRAY); \
LY_CHECK_RET(DUP_FUNC(CTX, PMOD, PARENT, PARENT_STMT, &(ORIG_ARRAY)[__u], &(NEW_ARRAY)[__new_start + __u])); \
} \
}
#define COMPILE_OP_ARRAY_GOTO(CTX, ARRAY_P, ARRAY_C, PARENT, FUNC, USES_STATUS, RET, GOTO) \
if (ARRAY_P) { \
LY_ARRAY_COUNT_TYPE __u = (ARRAY_C) ? LY_ARRAY_COUNT(ARRAY_C) : 0; \
LY_ARRAY_CREATE_GOTO((CTX)->ctx, ARRAY_C, __u + LY_ARRAY_COUNT(ARRAY_P), RET, GOTO); \
LY_ARRAY_FOR(ARRAY_P, __u) { \
LY_ARRAY_INCREMENT(ARRAY_C); \
RET = FUNC(CTX, &(ARRAY_P)[__u], PARENT, &(ARRAY_C)[LY_ARRAY_COUNT(ARRAY_C) - 1], USES_STATUS); \
if (RET == LY_EDENIED) { \
LY_ARRAY_DECREMENT(ARRAY_C); \
RET = LY_SUCCESS; \
} else if (RET) { \
goto GOTO; \
} \
} \
}
#define COMPILE_ARRAY_GOTO(CTX, ARRAY_P, ARRAY_C, FUNC, RET, GOTO) \
if (ARRAY_P) { \
LY_ARRAY_COUNT_TYPE __u = (ARRAY_C) ? LY_ARRAY_COUNT(ARRAY_C) : 0; \
LY_ARRAY_CREATE_GOTO((CTX)->ctx, ARRAY_C, __u + LY_ARRAY_COUNT(ARRAY_P), RET, GOTO); \
LY_ARRAY_FOR(ARRAY_P, __u) { \
LY_ARRAY_INCREMENT(ARRAY_C); \
RET = FUNC(CTX, &(ARRAY_P)[__u], &(ARRAY_C)[LY_ARRAY_COUNT(ARRAY_C) - 1]); \
LY_CHECK_GOTO(RET, GOTO); \
} \
}
#define COMPILE_EXTS_GOTO(CTX, EXTS_P, EXT_C, PARENT, RET, GOTO) \
if (EXTS_P) { \
LY_ARRAY_COUNT_TYPE __u = (EXT_C) ? LY_ARRAY_COUNT(EXT_C) : 0; \
LY_ARRAY_CREATE_GOTO((CTX)->ctx, EXT_C, __u + LY_ARRAY_COUNT(EXTS_P), RET, GOTO); \
LY_ARRAY_FOR(EXTS_P, __u) { \
LY_ARRAY_INCREMENT(EXT_C); \
RET = lys_compile_ext(CTX, &(EXTS_P)[__u], &(EXT_C)[LY_ARRAY_COUNT(EXT_C) - 1], PARENT); \
if (RET == LY_ENOT) { \
LY_ARRAY_DECREMENT(EXT_C); \
RET = LY_SUCCESS; \
} else if (RET) { \
goto GOTO; \
} \
} \
}
void lysc_update_path(struct lysc_ctx *ctx, const struct lys_module *parent_module, const char *name);
LY_ERR lys_compile_ext(struct lysc_ctx *ctx, struct lysp_ext_instance *extp, struct lysc_ext_instance *ext, void *parent);
LY_ERR lys_identity_precompile(struct lysc_ctx *ctx_sc, struct ly_ctx *ctx, struct lysp_module *parsed_mod,
const struct lysp_ident *identities_p, struct lysc_ident **identities);
LY_ERR lys_compile_identity_bases(struct lysc_ctx *ctx, const struct lysp_module *base_pmod, const char **bases_p,
struct lysc_ident *ident, struct lysc_ident ***bases);
LY_ERR lys_compile_identities(struct lys_module *mod);
LY_ERR lys_compile_extensions(struct lys_module *mod);
LY_ERR lys_compile(struct lys_module *mod, struct lys_depset_unres *unres);
LY_ERR lysc_check_status(struct lysc_ctx *ctx, const struct lysc_node *snode, uint16_t flags1, void *mod1,
const char *name1, uint16_t flags2, void *mod2, const char *name2);
LY_ERR lys_compile_expr_implement(const struct ly_ctx *ctx, const struct lyxp_expr *expr, LY_VALUE_FORMAT format,
void *prefix_data, ly_bool implement, struct lys_glob_unres *unres, const struct lys_module **mod_p);
LY_ERR lys_compile_depset_all(struct ly_ctx *ctx, struct lys_glob_unres *unres);
LY_ERR lys_implement(struct lys_module *mod, const char **features, struct lys_glob_unres *unres);
#endif