From c4a105a804c25415eaf79588b38a5d7fc8e75d70 Mon Sep 17 00:00:00 2001 From: midipix Date: Thu, 31 Dec 2015 20:35:26 -0500 Subject: amgc_get_enum_members(): initial implementation. --- src/logic/amgc_enum_members.c | 105 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/logic/amgc_enum_members.c (limited to 'src') diff --git a/src/logic/amgc_enum_members.c b/src/logic/amgc_enum_members.c new file mode 100644 index 0000000..321303f --- /dev/null +++ b/src/logic/amgc_enum_members.c @@ -0,0 +1,105 @@ +/**********************************************************/ +/* apimagic: cparser-based API normalization utility */ +/* Copyright (C) 2015--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */ +/**********************************************************/ + +#include +#include +#include + +#include + +static const struct amgc_entity * enumval_vector_entity( + const struct amgc_unit_ctx * uctx, + const union entity_t * entity) +{ + const struct amgc_entity * aentity; + + aentity = uctx->entities->enumvals; + + for (; aentity->entity; aentity++) + if (aentity->entity == entity) + return aentity; + + return 0; +} + +static int enumval_cmp(const void * ptra, const void * ptrb) +{ + struct amgc_entity * entitya = (struct amgc_entity *)ptra; + struct amgc_entity * entityb = (struct amgc_entity *)ptrb; + + if (entitya->enumval == entityb->enumval) + return (strcmp( + entitya->altname + ? entitya->altname + : entitya->entity->base.symbol->string, + entityb->altname + ? entityb->altname + : entityb->entity->base.symbol->string)); + else if ((entitya->enumval <= -128) && (entityb->enumval >= 0)) + return 1; + else if ((entityb->enumval <= -128) && (entitya->enumval >= 0)) + return -1; + else if ((entitya->enumval < entityb->enumval) && (entitya->enumval > -128) && (entityb->enumval > -128)) + return -1; + else + return 1; +} + +amgc_api int amgc_get_enum_members( + const struct amgc_unit_ctx * uctx, + const union entity_t * penum, + struct amgc_entity ** pmembers) +{ + int nmembers; + struct amgc_entity * buffer; + struct amgc_entity * pentity; + const struct amgc_entity * aentity; + const union entity_t * entity; + + if (penum->base.kind != ENTITY_ENUM) + return -1; + + entity = penum->enume.first_value; + nmembers= 0; + + for (; entity && (entity->base.kind == ENTITY_ENUM_VALUE); ) { + if (!(aentity = enumval_vector_entity(uctx,entity))) + return -1; + + if (!aentity->fexclude) + nmembers++; + + entity = entity->base.next; + } + + /* use first element as a guard */ + if (!(buffer = calloc(1+nmembers+1,sizeof(*buffer)))) + return -1; + + pentity = &buffer[1]; + entity = penum->enume.first_value; + + for (; entity && (entity->base.kind == ENTITY_ENUM_VALUE); ) { + aentity = enumval_vector_entity(uctx,entity); + + if (!aentity->fexclude) + memcpy(pentity++,aentity,sizeof(*pentity)); + + entity = entity->base.next; + } + + *pmembers = &buffer[1]; + qsort(*pmembers,nmembers,sizeof(struct amgc_entity),enumval_cmp); + + return 0; +} + +amgc_api void amgc_free_enum_members(struct amgc_entity * members) +{ + /* first element is a guard */ + if (members) + free(--members); +} -- cgit v1.2.3