1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/**********************************************************/
/* apimagic: cparser-based API normalization utility */
/* Copyright (C) 2015--2016 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.APIMAGIC. */
/**********************************************************/
#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;
}
/* 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);
}
|