| |
| |
| |
| |
| |
| |
| #include <cparser/ast/ast_t.h> |
| #include <cparser/ast/entity_t.h> |
| #include <cparser/ast/symbol_t.h> |
| |
| #include <apimagic/apimagic.h> |
| |
| 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; |
| } |
| |
| |
| 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) |
| { |
| |
| if (members) |
| free(--members); |
| } |