|
|
c4a105 |
/**********************************************************/
|
|
|
c4a105 |
/* apimagic: cparser-based API normalization utility */
|
|
|
c4a105 |
/* Copyright (C) 2015--2016 Z. Gilboa */
|
|
|
c4a105 |
/* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */
|
|
|
c4a105 |
/**********************************************************/
|
|
|
c4a105 |
|
|
|
c4a105 |
#include <cparser/ast/ast_t.h>
|
|
|
c4a105 |
#include <cparser/ast/entity_t.h>
|
|
|
c4a105 |
#include <cparser/ast/symbol_t.h>
|
|
|
c4a105 |
|
|
|
c4a105 |
#include <apimagic/apimagic.h>
|
|
|
c4a105 |
|
|
|
c4a105 |
static const struct amgc_entity * enumval_vector_entity(
|
|
|
c4a105 |
const struct amgc_unit_ctx * uctx,
|
|
|
c4a105 |
const union entity_t * entity)
|
|
|
c4a105 |
{
|
|
|
c4a105 |
const struct amgc_entity * aentity;
|
|
|
c4a105 |
|
|
|
c4a105 |
aentity = uctx->entities->enumvals;
|
|
|
c4a105 |
|
|
|
c4a105 |
for (; aentity->entity; aentity++)
|
|
|
c4a105 |
if (aentity->entity == entity)
|
|
|
c4a105 |
return aentity;
|
|
|
c4a105 |
|
|
|
c4a105 |
return 0;
|
|
|
c4a105 |
}
|
|
|
c4a105 |
|
|
|
c4a105 |
static int enumval_cmp(const void * ptra, const void * ptrb)
|
|
|
c4a105 |
{
|
|
|
c4a105 |
struct amgc_entity * entitya = (struct amgc_entity *)ptra;
|
|
|
c4a105 |
struct amgc_entity * entityb = (struct amgc_entity *)ptrb;
|
|
|
c4a105 |
|
|
|
c4a105 |
if (entitya->enumval == entityb->enumval)
|
|
|
c4a105 |
return (strcmp(
|
|
|
c4a105 |
entitya->altname
|
|
|
c4a105 |
? entitya->altname
|
|
|
c4a105 |
: entitya->entity->base.symbol->string,
|
|
|
c4a105 |
entityb->altname
|
|
|
c4a105 |
? entityb->altname
|
|
|
c4a105 |
: entityb->entity->base.symbol->string));
|
|
|
c4a105 |
else if ((entitya->enumval <= -128) && (entityb->enumval >= 0))
|
|
|
c4a105 |
return 1;
|
|
|
c4a105 |
else if ((entityb->enumval <= -128) && (entitya->enumval >= 0))
|
|
|
c4a105 |
return -1;
|
|
|
c4a105 |
else if ((entitya->enumval < entityb->enumval) && (entitya->enumval > -128) && (entityb->enumval > -128))
|
|
|
c4a105 |
return -1;
|
|
|
c4a105 |
else
|
|
|
c4a105 |
return 1;
|
|
|
c4a105 |
}
|
|
|
c4a105 |
|
|
|
d4478b |
int amgc_get_enum_members(
|
|
|
c4a105 |
const struct amgc_unit_ctx * uctx,
|
|
|
c4a105 |
const union entity_t * penum,
|
|
|
c4a105 |
struct amgc_entity ** pmembers)
|
|
|
c4a105 |
{
|
|
|
c4a105 |
int nmembers;
|
|
|
c4a105 |
struct amgc_entity * buffer;
|
|
|
c4a105 |
struct amgc_entity * pentity;
|
|
|
c4a105 |
const struct amgc_entity * aentity;
|
|
|
c4a105 |
const union entity_t * entity;
|
|
|
c4a105 |
|
|
|
c4a105 |
if (penum->base.kind != ENTITY_ENUM)
|
|
|
c4a105 |
return -1;
|
|
|
c4a105 |
|
|
|
c4a105 |
entity = penum->enume.first_value;
|
|
|
c4a105 |
nmembers= 0;
|
|
|
c4a105 |
|
|
|
c4a105 |
for (; entity && (entity->base.kind == ENTITY_ENUM_VALUE); ) {
|
|
|
c4a105 |
if (!(aentity = enumval_vector_entity(uctx,entity)))
|
|
|
c4a105 |
return -1;
|
|
|
c4a105 |
|
|
|
c4a105 |
if (!aentity->fexclude)
|
|
|
c4a105 |
nmembers++;
|
|
|
c4a105 |
|
|
|
c4a105 |
entity = entity->base.next;
|
|
|
c4a105 |
}
|
|
|
c4a105 |
|
|
|
c4a105 |
/* use first element as a guard */
|
|
|
c4a105 |
if (!(buffer = calloc(1+nmembers+1,sizeof(*buffer))))
|
|
|
c4a105 |
return -1;
|
|
|
c4a105 |
|
|
|
c4a105 |
pentity = &buffer[1];
|
|
|
c4a105 |
entity = penum->enume.first_value;
|
|
|
c4a105 |
|
|
|
c4a105 |
for (; entity && (entity->base.kind == ENTITY_ENUM_VALUE); ) {
|
|
|
c4a105 |
aentity = enumval_vector_entity(uctx,entity);
|
|
|
c4a105 |
|
|
|
c4a105 |
if (!aentity->fexclude)
|
|
|
c4a105 |
memcpy(pentity++,aentity,sizeof(*pentity));
|
|
|
c4a105 |
|
|
|
c4a105 |
entity = entity->base.next;
|
|
|
c4a105 |
}
|
|
|
c4a105 |
|
|
|
c4a105 |
*pmembers = &buffer[1];
|
|
|
c4a105 |
qsort(*pmembers,nmembers,sizeof(struct amgc_entity),enumval_cmp);
|
|
|
c4a105 |
|
|
|
c4a105 |
return 0;
|
|
|
c4a105 |
}
|
|
|
c4a105 |
|
|
|
d4478b |
void amgc_free_enum_members(struct amgc_entity * members)
|
|
|
c4a105 |
{
|
|
|
c4a105 |
/* first element is a guard */
|
|
|
c4a105 |
if (members)
|
|
|
c4a105 |
free(--members);
|
|
|
c4a105 |
}
|