diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2011-07-12 13:22:25 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-07-15 15:04:45 -0400 |
commit | f6bf070aee4527e9793681b42ac57a587d239f4c (patch) | |
tree | 8453c673529c934357b7c9ff00caaf2445d5f5b5 | |
parent | 671a62cb968b6793f0504770888b23b79e6fb81e (diff) |
scanner: Output type info for new_id arguments
-rw-r--r-- | wayland/scanner.c | 99 | ||||
-rw-r--r-- | wayland/wayland-util.h | 2 |
2 files changed, 99 insertions, 2 deletions
diff --git a/wayland/scanner.c b/wayland/scanner.c index 6df9df8..300e39d 100644 --- a/wayland/scanner.c +++ b/wayland/scanner.c @@ -60,6 +60,8 @@ struct protocol { char *name; char *uppercase_name; struct wl_list interface_list; + int type_index; + int null_run_length; }; struct interface { @@ -77,6 +79,9 @@ struct message { char *uppercase_name; struct wl_list arg_list; struct wl_list link; + int arg_count; + int type_index; + int all_null; int destructor; }; @@ -204,6 +209,7 @@ start_element(void *data, const char *element_name, const char **atts) message->name = strdup(name); message->uppercase_name = uppercase_dup(name); wl_list_init(&message->arg_list); + message->arg_count = 0; if (strcmp(element_name, "request") == 0) wl_list_insert(ctx->interface->request_list.prev, @@ -250,6 +256,7 @@ start_element(void *data, const char *element_name, const char **atts) } wl_list_insert(ctx->message->arg_list.prev, &arg->link); + ctx->message->arg_count++; } else if (strcmp(element_name, "enum") == 0) { if (name == NULL) fail(ctx, "no enum name given"); @@ -599,6 +606,80 @@ emit_header(struct protocol *protocol, int server) } static void +emit_types_forward_declarations(struct protocol *protocol, + struct wl_list *message_list) +{ + struct message *m; + struct arg *a; + int length; + + wl_list_for_each(m, message_list, link) { + length = 0; + m->all_null = 1; + wl_list_for_each(a, &m->arg_list, link) { + length++; + switch (a->type) { + case NEW_ID: + case OBJECT: + m->all_null = 0; + printf("extern const struct wl_interface %s_interface;\n", + a->interface_name); + break; + default: + break; + } + } + + if (m->all_null && length > protocol->null_run_length) + protocol->null_run_length = length; + } +} + +static void +emit_null_run(struct protocol *protocol) +{ + int i; + + for (i = 0; i < protocol->null_run_length; i++) + printf("\tNULL,\n"); +} + +static void +emit_types(struct protocol *protocol, struct wl_list *message_list) +{ + struct message *m; + struct arg *a; + + wl_list_for_each(m, message_list, link) { + if (m->all_null) { + m->type_index = 0; + continue; + } + + m->type_index = + protocol->null_run_length + protocol->type_index; + protocol->type_index += m->arg_count; + + wl_list_for_each(a, &m->arg_list, link) { + switch (a->type) { + case NEW_ID: + case OBJECT: + if (strcmp(a->interface_name, + "wl_object") != 0) + printf("\t&%s_interface,\n", + a->interface_name); + else + printf("\tNULL,\n"); + break; + default: + printf("\tNULL,\n"); + break; + } + } + } +} + +static void emit_messages(struct wl_list *message_list, struct interface *interface, const char *suffix) { @@ -640,7 +721,7 @@ emit_messages(struct wl_list *message_list, break; } } - printf("\", NULL },\n"); + printf("\", types + %d },\n", m->type_index); } printf("};\n\n"); @@ -658,6 +739,20 @@ emit_code(struct protocol *protocol) copyright); wl_list_for_each(i, &protocol->interface_list, link) { + emit_types_forward_declarations(protocol, &i->request_list); + emit_types_forward_declarations(protocol, &i->event_list); + } + printf("\n"); + + printf("static const struct wl_interface *types[] = {\n"); + emit_null_run(protocol); + wl_list_for_each(i, &protocol->interface_list, link) { + emit_types(protocol, &i->request_list); + emit_types(protocol, &i->event_list); + } + printf("};\n\n"); + + wl_list_for_each(i, &protocol->interface_list, link) { emit_messages(&i->request_list, i, "requests"); emit_messages(&i->event_list, i, "events"); @@ -694,6 +789,8 @@ int main(int argc, char *argv[]) usage(EXIT_FAILURE); wl_list_init(&protocol.interface_list); + protocol.type_index = 0; + protocol.null_run_length = 0; ctx.protocol = &protocol; ctx.filename = "<stdin>"; diff --git a/wayland/wayland-util.h b/wayland/wayland-util.h index 7808081..a9f869a 100644 --- a/wayland/wayland-util.h +++ b/wayland/wayland-util.h @@ -47,7 +47,7 @@ extern "C" { struct wl_message { const char *name; const char *signature; - const void **types; + const struct wl_interface **types; }; struct wl_interface { |