aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/genksyms/genksyms.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/genksyms/genksyms.c')
-rw-r--r--scripts/genksyms/genksyms.c71
1 files changed, 66 insertions, 5 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index 4a350816a9e8..f9e75531ea03 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -62,6 +62,7 @@ static const struct {
62 [SYM_ENUM] = {'e', "enum"}, 62 [SYM_ENUM] = {'e', "enum"},
63 [SYM_STRUCT] = {'s', "struct"}, 63 [SYM_STRUCT] = {'s', "struct"},
64 [SYM_UNION] = {'u', "union"}, 64 [SYM_UNION] = {'u', "union"},
65 [SYM_ENUM_CONST] = {'E', "enum constant"},
65}; 66};
66 67
67static int equal_list(struct string_list *a, struct string_list *b); 68static int equal_list(struct string_list *a, struct string_list *b);
@@ -149,10 +150,16 @@ static unsigned long crc32(const char *s)
149 150
150static enum symbol_type map_to_ns(enum symbol_type t) 151static enum symbol_type map_to_ns(enum symbol_type t)
151{ 152{
152 if (t == SYM_TYPEDEF) 153 switch (t) {
153 t = SYM_NORMAL; 154 case SYM_ENUM_CONST:
154 else if (t == SYM_UNION) 155 case SYM_NORMAL:
155 t = SYM_STRUCT; 156 case SYM_TYPEDEF:
157 return SYM_NORMAL;
158 case SYM_ENUM:
159 case SYM_STRUCT:
160 case SYM_UNION:
161 return SYM_STRUCT;
162 }
156 return t; 163 return t;
157} 164}
158 165
@@ -191,10 +198,47 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
191 struct string_list *defn, int is_extern, 198 struct string_list *defn, int is_extern,
192 int is_reference) 199 int is_reference)
193{ 200{
194 unsigned long h = crc32(name) % HASH_BUCKETS; 201 unsigned long h;
195 struct symbol *sym; 202 struct symbol *sym;
196 enum symbol_status status = STATUS_UNCHANGED; 203 enum symbol_status status = STATUS_UNCHANGED;
204 /* The parser adds symbols in the order their declaration completes,
205 * so it is safe to store the value of the previous enum constant in
206 * a static variable.
207 */
208 static int enum_counter;
209 static struct string_list *last_enum_expr;
210
211 if (type == SYM_ENUM_CONST) {
212 if (defn) {
213 free_list(last_enum_expr, NULL);
214 last_enum_expr = copy_list_range(defn, NULL);
215 enum_counter = 1;
216 } else {
217 struct string_list *expr;
218 char buf[20];
219
220 snprintf(buf, sizeof(buf), "%d", enum_counter++);
221 if (last_enum_expr) {
222 expr = copy_list_range(last_enum_expr, NULL);
223 defn = concat_list(mk_node("("),
224 expr,
225 mk_node(")"),
226 mk_node("+"),
227 mk_node(buf), NULL);
228 } else {
229 defn = mk_node(buf);
230 }
231 }
232 } else if (type == SYM_ENUM) {
233 free_list(last_enum_expr, NULL);
234 last_enum_expr = NULL;
235 enum_counter = 0;
236 if (!name)
237 /* Anonymous enum definition, nothing more to do */
238 return NULL;
239 }
197 240
241 h = crc32(name) % HASH_BUCKETS;
198 for (sym = symtab[h]; sym; sym = sym->hash_next) { 242 for (sym = symtab[h]; sym; sym = sym->hash_next) {
199 if (map_to_ns(sym->type) == map_to_ns(type) && 243 if (map_to_ns(sym->type) == map_to_ns(type) &&
200 strcmp(name, sym->name) == 0) { 244 strcmp(name, sym->name) == 0) {
@@ -343,6 +387,22 @@ struct string_list *copy_node(struct string_list *node)
343 return newnode; 387 return newnode;
344} 388}
345 389
390struct string_list *copy_list_range(struct string_list *start,
391 struct string_list *end)
392{
393 struct string_list *res, *n;
394
395 if (start == end)
396 return NULL;
397 n = res = copy_node(start);
398 for (start = start->next; start != end; start = start->next) {
399 n->next = copy_node(start);
400 n = n->next;
401 }
402 n->next = NULL;
403 return res;
404}
405
346static int equal_list(struct string_list *a, struct string_list *b) 406static int equal_list(struct string_list *a, struct string_list *b)
347{ 407{
348 while (a && b) { 408 while (a && b) {
@@ -512,6 +572,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
512 crc = partial_crc32_one(' ', crc); 572 crc = partial_crc32_one(' ', crc);
513 break; 573 break;
514 574
575 case SYM_ENUM_CONST:
515 case SYM_TYPEDEF: 576 case SYM_TYPEDEF:
516 subsym = find_symbol(cur->string, cur->tag, 0); 577 subsym = find_symbol(cur->string, cur->tag, 0);
517 /* FIXME: Bad reference files can segfault here. */ 578 /* FIXME: Bad reference files can segfault here. */