From 7a622c84067e5298d9f9a3f3d78bc3da04896c96 Mon Sep 17 00:00:00 2001 From: midipix Date: Thu, 31 Dec 2015 03:30:03 -0500 Subject: ammgc_get_unit_entities(): initial implementation and integration. --- include/apimagic/apimagic.h | 31 +++++++ project/common.mk | 1 + src/driver/amgc_unit_ctx.c | 6 +- src/internal/apimagic_driver_impl.h | 1 + src/logic/amgc_unit_entities.c | 161 ++++++++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/logic/amgc_unit_entities.c diff --git a/include/apimagic/apimagic.h b/include/apimagic/apimagic.h index 500463c..f6c1767 100644 --- a/include/apimagic/apimagic.h +++ b/include/apimagic/apimagic.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -76,11 +77,39 @@ struct amgc_unit_meta { int ngenerated; }; +struct amgc_define { + const pp_definition_t * symbol; + const char * definition; + const char * altname; +}; + +struct amgc_entity { + const union entity_t * entity; + const char * altname; + int enumval; + bool fmbstr; + bool futf16; + bool fset; + bool fexclude; +}; + +struct amgc_unit_entities { + struct amgc_define * defines; + struct amgc_entity * enums; + struct amgc_entity * enumvals; + struct amgc_entity * typedefs; + struct amgc_entity * structs; + struct amgc_entity * unions; + struct amgc_entity * functions; + struct amgc_entity * generated; +}; + struct amgc_unit_ctx { const char * const * path; const struct amgc_input * map; const struct amgc_common_ctx * cctx; const struct amgc_unit_meta * meta; + const struct amgc_unit_entities*entities; const struct compilation_unit_t*ccunit; void * any; int status; @@ -105,6 +134,8 @@ amgc_api int amgc_lang_std_from_string (const char * std); /* low-level api */ amgc_api int amgc_init_unit_meta (const struct amgc_unit_ctx *, struct amgc_unit_meta *); +amgc_api int amgc_get_unit_entities (const struct amgc_unit_ctx *, struct amgc_unit_meta *, struct amgc_unit_entities **); +amgc_api void amgc_free_unit_entities (struct amgc_unit_entities *); #ifdef __cplusplus } diff --git a/project/common.mk b/project/common.mk index 7179244..1945a6a 100644 --- a/project/common.mk +++ b/project/common.mk @@ -4,6 +4,7 @@ COMMON_SRCS = \ src/driver/amgc_unit_ctx.c \ src/logic/amgc_init_unit_meta.c \ src/logic/amgc_map_input.c \ + src/logic/amgc_unit_entities.c \ src/skin/amgc_skin_default.c \ APP_SRCS = \ diff --git a/src/driver/amgc_unit_ctx.c b/src/driver/amgc_unit_ctx.c index 4da986a..334ee32 100644 --- a/src/driver/amgc_unit_ctx.c +++ b/src/driver/amgc_unit_ctx.c @@ -22,6 +22,9 @@ static int amgc_free_unit_ctx_impl(struct amgc_unit_ctx_impl * ctx, int status) { if (ctx) { + if (ctx->entities) + amgc_free_unit_entities(ctx->entities); + amgc_unmap_input(&ctx->map); free(ctx); } @@ -155,9 +158,10 @@ int amgc_get_unit_ctx( ctx->uctx.map = &ctx->map; ctx->uctx.cctx = &ctx->cctx; ctx->uctx.meta = &ctx->meta; + ctx->uctx.entities = ctx->entities; ctx->uctx.ccunit= &ctx->ccunit; - if (amgc_init_unit_meta(&ctx->uctx,&ctx->meta)) + if (amgc_get_unit_entities(&ctx->uctx,&ctx->meta,&ctx->entities)) return amgc_free_unit_ctx_impl(ctx,-1); *pctx = &ctx->uctx; diff --git a/src/internal/apimagic_driver_impl.h b/src/internal/apimagic_driver_impl.h index 98f4465..659597d 100644 --- a/src/internal/apimagic_driver_impl.h +++ b/src/internal/apimagic_driver_impl.h @@ -26,6 +26,7 @@ struct amgc_unit_ctx_impl { struct amgc_common_ctx cctx; struct amgc_unit_ctx uctx; struct amgc_unit_meta meta; + struct amgc_unit_entities * entities; struct compilation_unit_t ccunit; }; diff --git a/src/logic/amgc_unit_entities.c b/src/logic/amgc_unit_entities.c new file mode 100644 index 0000000..b528a19 --- /dev/null +++ b/src/logic/amgc_unit_entities.c @@ -0,0 +1,161 @@ +/**********************************************************/ +/* apimagic: cparser-based API normalization utility */ +/* Copyright (C) 2015--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */ +/**********************************************************/ + +#include +#include + +#include + +struct amgc_unit_entities_impl { + struct amgc_define * adefines; + struct amgc_entity * aentities; + struct amgc_unit_entities entities; +}; + +static int amgc_free_unit_entities_impl( + struct amgc_unit_entities_impl *entities, + int status) +{ + if (entities->adefines) + free(entities->adefines); + + if (entities->aentities) + free(entities->aentities); + + free (entities); + return status; +} + +int amgc_get_unit_entities( + const struct amgc_unit_ctx * uctx, + struct amgc_unit_meta * meta, + struct amgc_unit_entities ** pentities) +{ + struct amgc_unit_meta umeta; + struct amgc_define * adefine; + struct amgc_entity * aentity; + struct amgc_unit_entities * uentities; + union entity_t * entity; + struct amgc_unit_entities_impl *entities; + size_t ndefs; + size_t nelements; + + if (!meta) + meta = &umeta; + + if (amgc_init_unit_meta(uctx,meta)) + return -1; + + if (!(entities = calloc(1,sizeof(*entities)))) + return -1; + + /* use first element as a guard */ + ndefs = 1; + ndefs += meta->ndefines + 1; + + nelements = 1; + nelements += meta->nenums + 1; + nelements += meta->nenumvals + 1; + nelements += meta->ntypedefs + 1; + nelements += meta->nstructs + 1; + nelements += meta->nunions + 1; + nelements += meta->nfunctions + 1; + nelements += meta->ngenerated + 1; + + if (!(entities->adefines = calloc(ndefs,sizeof(struct amgc_define)))) + return amgc_free_unit_entities_impl(entities,-1); + + if (!(entities->aentities = calloc(nelements,sizeof(struct amgc_entity)))) + return amgc_free_unit_entities_impl(entities,-1); + + adefine = &entities->adefines[1]; + entities->entities.defines = adefine; + + aentity = &entities->aentities[1]; + entities->entities.enums = aentity; + aentity += meta->nenums + 1; + + entities->entities.enumvals = aentity; + aentity += meta->nenumvals + 1; + + entities->entities.typedefs = aentity; + aentity += meta->ntypedefs + 1; + + entities->entities.structs = aentity; + aentity += meta->nstructs + 1; + + entities->entities.unions = aentity; + aentity += meta->nunions + 1; + + entities->entities.functions = aentity; + aentity += meta->nfunctions + 1; + + entities->entities.generated = aentity; + aentity += meta->ngenerated + 1; + + meta = &umeta; + memset(meta,0,sizeof(*meta)); + + entity = uctx->ccunit->ast->scope.first_entity; + uentities = &entities->entities; + + for (; entity; entity=entity->base.next) { + if (strcmp(*uctx->path,entity->base.pos.input_name)) + continue; + + if ((is_declaration(entity)) && (entity->declaration.implicit)) + uentities->generated[meta->ngenerated++].entity = entity; + + else { + switch (entity->kind) { + case ENTITY_ENUM: + uentities->enums[meta->nenums++].entity = entity; + break; + + case ENTITY_ENUM_VALUE: + uentities->enumvals[meta->nenumvals++].entity = entity; + break; + + case ENTITY_TYPEDEF: + uentities->typedefs[meta->ntypedefs++].entity = entity; + meta->ntypedefs++; + break; + + case ENTITY_STRUCT: + if (entity->base.symbol || entity->compound.alias) + uentities->structs[meta->nstructs++].entity = entity; + break; + + case ENTITY_UNION: + if (entity->base.symbol || entity->compound.alias) + uentities->unions[meta->nunions++].entity = entity; + break; + + case ENTITY_FUNCTION: + uentities->functions[meta->nfunctions++].entity = entity; + break; + + default: + break; + } + } + } + + *pentities = uentities; + return 0; +} + +void amgc_free_unit_entities(struct amgc_unit_entities * ctx) +{ + struct amgc_unit_entities_impl *ictx; + uintptr_t addr; + + if (ctx) { + addr = (uintptr_t)ctx - offsetof(struct amgc_unit_entities_impl,entities); + ictx = (struct amgc_unit_entities_impl *)addr; + amgc_free_unit_entities_impl(ictx,0); + } +} -- cgit v1.2.3