Skip to content

Commit

Permalink
Merge branch 'genksyms-enum' into kbuild/kbuild
Browse files Browse the repository at this point in the history
  • Loading branch information
Michal Marek committed Mar 17, 2011
2 parents 00759c0 + 303fc01 commit a88bab9
Show file tree
Hide file tree
Showing 8 changed files with 988 additions and 863 deletions.
4 changes: 2 additions & 2 deletions scripts/genksyms/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ $(obj)/keywords.c: $(obj)/keywords.gperf FORCE
# flex

quiet_cmd_lex.c = FLEX $@
cmd_lex.c = flex -o$@ -d $< $(obj)/parse.h
cmd_lex.c = flex -o$@ -d $<

$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h $(obj)/keywords.c FORCE
$(obj)/lex.c: $(obj)/lex.l $(obj)/keywords.c FORCE
$(call if_changed,lex.c)
cp $@ $@_shipped

Expand Down
192 changes: 136 additions & 56 deletions scripts/genksyms/genksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,22 @@ static int nsyms;
static struct symbol *expansion_trail;
static struct symbol *visited_symbols;

static const char *const symbol_type_name[] = {
"normal", "typedef", "enum", "struct", "union"
static const struct {
int n;
const char *name;
} symbol_types[] = {
[SYM_NORMAL] = { 0, NULL},
[SYM_TYPEDEF] = {'t', "typedef"},
[SYM_ENUM] = {'e', "enum"},
[SYM_STRUCT] = {'s', "struct"},
[SYM_UNION] = {'u', "union"},
[SYM_ENUM_CONST] = {'E', "enum constant"},
};

static int equal_list(struct string_list *a, struct string_list *b);
static void print_list(FILE * f, struct string_list *list);
static struct string_list *concat_list(struct string_list *start, ...);
static struct string_list *mk_node(const char *string);
static void print_location(void);
static void print_type_name(enum symbol_type type, const char *name);

Expand Down Expand Up @@ -140,14 +150,20 @@ static unsigned long crc32(const char *s)

static enum symbol_type map_to_ns(enum symbol_type t)
{
if (t == SYM_TYPEDEF)
t = SYM_NORMAL;
else if (t == SYM_UNION)
t = SYM_STRUCT;
switch (t) {
case SYM_ENUM_CONST:
case SYM_NORMAL:
case SYM_TYPEDEF:
return SYM_NORMAL;
case SYM_ENUM:
case SYM_STRUCT:
case SYM_UNION:
return SYM_STRUCT;
}
return t;
}

struct symbol *find_symbol(const char *name, enum symbol_type ns)
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
{
unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym;
Expand All @@ -158,6 +174,8 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
sym->is_declared)
break;

if (exact && sym && sym->type != ns)
return NULL;
return sym;
}

Expand All @@ -180,10 +198,47 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern,
int is_reference)
{
unsigned long h = crc32(name) % HASH_BUCKETS;
unsigned long h;
struct symbol *sym;
enum symbol_status status = STATUS_UNCHANGED;
/* The parser adds symbols in the order their declaration completes,
* so it is safe to store the value of the previous enum constant in
* a static variable.
*/
static int enum_counter;
static struct string_list *last_enum_expr;

if (type == SYM_ENUM_CONST) {
if (defn) {
free_list(last_enum_expr, NULL);
last_enum_expr = copy_list_range(defn, NULL);
enum_counter = 1;
} else {
struct string_list *expr;
char buf[20];

snprintf(buf, sizeof(buf), "%d", enum_counter++);
if (last_enum_expr) {
expr = copy_list_range(last_enum_expr, NULL);
defn = concat_list(mk_node("("),
expr,
mk_node(")"),
mk_node("+"),
mk_node(buf), NULL);
} else {
defn = mk_node(buf);
}
}
} else if (type == SYM_ENUM) {
free_list(last_enum_expr, NULL);
last_enum_expr = NULL;
enum_counter = 0;
if (!name)
/* Anonymous enum definition, nothing more to do */
return NULL;
}

h = crc32(name) % HASH_BUCKETS;
for (sym = symtab[h]; sym; sym = sym->hash_next) {
if (map_to_ns(sym->type) == map_to_ns(type) &&
strcmp(name, sym->name) == 0) {
Expand Down Expand Up @@ -247,8 +302,12 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
sym->is_override = 0;

if (flag_debug) {
fprintf(debugfile, "Defn for %s %s == <",
symbol_type_name[type], name);
if (symbol_types[type].name)
fprintf(debugfile, "Defn for %s %s == <",
symbol_types[type].name, name);
else
fprintf(debugfile, "Defn for type%d %s == <",
type, name);
if (is_extern)
fputs("extern ", debugfile);
print_list(debugfile, defn);
Expand Down Expand Up @@ -288,6 +347,35 @@ void free_list(struct string_list *s, struct string_list *e)
}
}

static struct string_list *mk_node(const char *string)
{
struct string_list *newnode;

newnode = xmalloc(sizeof(*newnode));
newnode->string = xstrdup(string);
newnode->tag = SYM_NORMAL;
newnode->next = NULL;

return newnode;
}

static struct string_list *concat_list(struct string_list *start, ...)
{
va_list ap;
struct string_list *n, *n2;

if (!start)
return NULL;
for (va_start(ap, start); (n = va_arg(ap, struct string_list *));) {
for (n2 = n; n2->next; n2 = n2->next)
;
n2->next = start;
start = n;
}
va_end(ap);
return start;
}

struct string_list *copy_node(struct string_list *node)
{
struct string_list *newnode;
Expand All @@ -299,6 +387,22 @@ struct string_list *copy_node(struct string_list *node)
return newnode;
}

struct string_list *copy_list_range(struct string_list *start,
struct string_list *end)
{
struct string_list *res, *n;

if (start == end)
return NULL;
n = res = copy_node(start);
for (start = start->next; start != end; start = start->next) {
n->next = copy_node(start);
n = n->next;
}
n->next = NULL;
return res;
}

static int equal_list(struct string_list *a, struct string_list *b)
{
while (a && b) {
Expand Down Expand Up @@ -346,8 +450,8 @@ static struct string_list *read_node(FILE *f)
if (node.string[1] == '#') {
int n;

for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) {
if (node.string[0] == symbol_type_name[n][0]) {
for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
if (node.string[0] == symbol_types[n].n) {
node.tag = n;
node.string += 2;
return copy_node(&node);
Expand Down Expand Up @@ -397,8 +501,8 @@ static void read_reference(FILE *f)

static void print_node(FILE * f, struct string_list *list)
{
if (list->tag != SYM_NORMAL) {
putc(symbol_type_name[list->tag][0], f);
if (symbol_types[list->tag].n) {
putc(symbol_types[list->tag].n, f);
putc('#', f);
}
fputs(list->string, f);
Expand Down Expand Up @@ -468,8 +572,9 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
crc = partial_crc32_one(' ', crc);
break;

case SYM_ENUM_CONST:
case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag);
subsym = find_symbol(cur->string, cur->tag, 0);
/* FIXME: Bad reference files can segfault here. */
if (subsym->expansion_trail) {
if (flag_dump_defs)
Expand All @@ -486,55 +591,30 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
case SYM_STRUCT:
case SYM_UNION:
case SYM_ENUM:
subsym = find_symbol(cur->string, cur->tag);
subsym = find_symbol(cur->string, cur->tag, 0);
if (!subsym) {
struct string_list *n, *t = NULL;
struct string_list *n;

error_with_pos("expand undefined %s %s",
symbol_type_name[cur->tag],
symbol_types[cur->tag].name,
cur->string);

n = xmalloc(sizeof(*n));
n->string = xstrdup(symbol_type_name[cur->tag]);
n->tag = SYM_NORMAL;
n->next = t;
t = n;

n = xmalloc(sizeof(*n));
n->string = xstrdup(cur->string);
n->tag = SYM_NORMAL;
n->next = t;
t = n;

n = xmalloc(sizeof(*n));
n->string = xstrdup("{");
n->tag = SYM_NORMAL;
n->next = t;
t = n;

n = xmalloc(sizeof(*n));
n->string = xstrdup("UNKNOWN");
n->tag = SYM_NORMAL;
n->next = t;
t = n;

n = xmalloc(sizeof(*n));
n->string = xstrdup("}");
n->tag = SYM_NORMAL;
n->next = t;
t = n;

n = concat_list(mk_node
(symbol_types[cur->tag].name),
mk_node(cur->string),
mk_node("{"),
mk_node("UNKNOWN"),
mk_node("}"), NULL);
subsym =
add_symbol(cur->string, cur->tag, n, 0);
}
if (subsym->expansion_trail) {
if (flag_dump_defs) {
fprintf(debugfile, "%s %s ",
symbol_type_name[cur->tag],
symbol_types[cur->tag].name,
cur->string);
}

crc = partial_crc32(symbol_type_name[cur->tag],
crc = partial_crc32(symbol_types[cur->tag].name,
crc);
crc = partial_crc32_one(' ', crc);
crc = partial_crc32(cur->string, crc);
Expand Down Expand Up @@ -565,7 +645,7 @@ void export_symbol(const char *name)
{
struct symbol *sym;

sym = find_symbol(name, SYM_NORMAL);
sym = find_symbol(name, SYM_NORMAL, 0);
if (!sym)
error_with_pos("export undefined symbol %s", name);
else {
Expand Down Expand Up @@ -624,8 +704,8 @@ static void print_location(void)

static void print_type_name(enum symbol_type type, const char *name)
{
if (type != SYM_NORMAL)
fprintf(stderr, "%s %s", symbol_type_name[type], name);
if (symbol_types[type].name)
fprintf(stderr, "%s %s", symbol_types[type].name, name);
else
fprintf(stderr, "%s", name);
}
Expand Down Expand Up @@ -771,8 +851,8 @@ int main(int argc, char **argv)

if (sym->is_override)
fputs("override ", dumpfile);
if (sym->type != SYM_NORMAL) {
putc(symbol_type_name[sym->type][0], dumpfile);
if (symbol_types[sym->type].n) {
putc(symbol_types[sym->type].n, dumpfile);
putc('#', dumpfile);
}
fputs(sym->name, dumpfile);
Expand Down
7 changes: 5 additions & 2 deletions scripts/genksyms/genksyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
#include <stdio.h>

enum symbol_type {
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION,
SYM_ENUM_CONST
};

enum symbol_status {
Expand Down Expand Up @@ -58,14 +59,16 @@ typedef struct string_list **yystype;
extern int cur_line;
extern char *cur_filename;

struct symbol *find_symbol(const char *name, enum symbol_type ns);
struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact);
struct symbol *add_symbol(const char *name, enum symbol_type type,
struct string_list *defn, int is_extern);
void export_symbol(const char *);

void free_node(struct string_list *list);
void free_list(struct string_list *s, struct string_list *e);
struct string_list *copy_node(struct string_list *);
struct string_list *copy_list_range(struct string_list *start,
struct string_list *end);

int yylex(void);
int yyparse(void);
Expand Down
Loading

0 comments on commit a88bab9

Please sign in to comment.