/**********************************************************/ /* apimagic: cparser-based API normalization utility */ /* Copyright (C) 2015--2021 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; } 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; } void amgc_free_enum_members(struct amgc_entity * members) { /* first element is a guard */ if (members) free(--members); }