summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/apimagic/apimagic.h31
-rw-r--r--project/common.mk1
-rw-r--r--src/driver/amgc_unit_ctx.c6
-rw-r--r--src/internal/apimagic_driver_impl.h1
-rw-r--r--src/logic/amgc_unit_entities.c161
5 files changed, 199 insertions, 1 deletions
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 <stdint.h>
#include <stdio.h>
+#include <cparser/ast/entity.h>
#include <cparser/driver/c_driver.h>
#include <cparser/driver/driver_t.h>
@@ -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 <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);
+ }
+}