diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/driver/amgc_unit_ctx.c | 6 | ||||
-rw-r--r-- | src/internal/apimagic_driver_impl.h | 1 | ||||
-rw-r--r-- | src/logic/amgc_unit_entities.c | 161 |
3 files changed, 167 insertions, 1 deletions
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 <cparser/ast/ast_t.h> +#include <cparser/ast/entity_t.h> + +#include <apimagic/apimagic.h> + +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); + } +} |