/**********************************************************/ /* apimagic: cparser-based API normalization utility */ /* Copyright (C) 2015--2016 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */ /**********************************************************/ #include #include #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; union type_t * etype; struct amgc_unit_entities_impl *entities; size_t ndefs; size_t nelements; int enumval; int ptrdepth; 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: enumval = (int)get_tarval_long(entity->enum_value.tv); uentities->enumvals[meta->nenumvals].entity = entity; uentities->enumvals[meta->nenumvals].enumval = enumval; meta->nenumvals++; break; case ENTITY_TYPEDEF: etype = entity->declaration.type; ptrdepth = 0; for (; etype->kind == TYPE_POINTER; etype=etype->pointer.points_to) ptrdepth++; uentities->typedefs[meta->ntypedefs].entity = entity; uentities->typedefs[meta->ntypedefs].reftype = etype; uentities->typedefs[meta->ntypedefs].ptrdepth = ptrdepth; 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); } }