summaryrefslogtreecommitdiffhomepage
path: root/src/logic/amgc_unit_entities.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/logic/amgc_unit_entities.c')
-rw-r--r--src/logic/amgc_unit_entities.c161
1 files changed, 161 insertions, 0 deletions
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);
+ }
+}