diff options
Diffstat (limited to 'src/scanner.c')
| -rw-r--r-- | src/scanner.c | 208 |
1 files changed, 149 insertions, 59 deletions
diff --git a/src/scanner.c b/src/scanner.c index adc9aa3..75322f7 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -28,6 +28,7 @@ #include <errno.h> #include <ctype.h> #include <expat.h> +#include <getopt.h> #include "wayland-util.h" @@ -39,12 +40,17 @@ enum side { static int usage(int ret) { - fprintf(stderr, "usage: ./scanner [client-header|server-header|code]" + fprintf(stderr, "usage: ./scanner [OPTION] [client-header|server-header|code]" " [input_file output_file]\n"); fprintf(stderr, "\n"); fprintf(stderr, "Converts XML protocol descriptions supplied on " "stdin or input file to client\n" - "headers, server headers, or protocol marshalling code.\n"); + "headers, server headers, or protocol marshalling code.\n\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -h, --help display this help and exit.\n" + " -c, --include-core-only include the core version of the headers,\n" + " that is e.g. wayland-client-core.h instead\n" + " of wayland-client.h.\n"); exit(ret); } @@ -68,6 +74,7 @@ struct protocol { int null_run_length; char *copyright; struct description *description; + bool core_headers; }; struct interface { @@ -985,10 +992,64 @@ format_copyright(const char *copyright) } static void +emit_types_forward_declarations(struct protocol *protocol, + struct wl_list *message_list, + struct wl_array *types) +{ + struct message *m; + struct arg *a; + int length; + char **p; + + 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: + if (!a->interface_name) + continue; + + m->all_null = 0; + p = fail_on_null(wl_array_add(types, sizeof *p)); + *p = a->interface_name; + break; + default: + break; + } + } + + if (m->all_null && length > protocol->null_run_length) + protocol->null_run_length = length; + } +} + +static int +cmp_names(const void *p1, const void *p2) +{ + const char * const *s1 = p1, * const *s2 = p2; + + return strcmp(*s1, *s2); +} + +static const char * +get_include_name(bool core, enum side side) +{ + if (side == SERVER) + return core ? "wayland-server-core.h" : "wayland-server.h"; + else + return core ? "wayland-client-core.h" : "wayland-client.h"; +} + +static void emit_header(struct protocol *protocol, enum side side) { struct interface *i; + struct wl_array types; const char *s = (side == SERVER) ? "SERVER" : "CLIENT"; + char **p, *prev; if (protocol->copyright) format_copyright(protocol->copyright); @@ -1007,17 +1068,39 @@ emit_header(struct protocol *protocol, enum side side) "struct wl_resource;\n\n", protocol->uppercase_name, s, protocol->uppercase_name, s, - (side == SERVER) ? "wayland-server.h" : "wayland-client.h"); + get_include_name(protocol->core_headers, side)); - wl_list_for_each(i, &protocol->interface_list, link) - printf("struct %s;\n", i->name); - printf("\n"); + wl_array_init(&types); + wl_list_for_each(i, &protocol->interface_list, link) { + emit_types_forward_declarations(protocol, &i->request_list, &types); + emit_types_forward_declarations(protocol, &i->event_list, &types); + } wl_list_for_each(i, &protocol->interface_list, link) { + p = fail_on_null(wl_array_add(&types, sizeof *p)); + *p = i->name; + } + + qsort(types.data, types.size / sizeof *p, sizeof *p, cmp_names); + prev = NULL; + wl_array_for_each(p, &types) { + if (prev && strcmp(*p, prev) == 0) + continue; + printf("struct %s;\n", *p); + prev = *p; + } + printf("\n"); + + prev = NULL; + wl_array_for_each(p, &types) { + if (prev && strcmp(*p, prev) == 0) + continue; printf("extern const struct wl_interface " - "%s_interface;\n", - i->name); + "%s_interface;\n", *p); + prev = *p; } + + wl_array_release(&types); printf("\n"); wl_list_for_each(i, &protocol->interface_list, link) { @@ -1044,41 +1127,6 @@ emit_header(struct protocol *protocol, enum side side) } static void -emit_types_forward_declarations(struct protocol *protocol, - struct wl_list *message_list, - struct wl_array *types) -{ - struct message *m; - struct arg *a; - int length; - char **p; - - 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: - if (!a->interface_name) - continue; - - m->all_null = 0; - p = fail_on_null(wl_array_add(types, sizeof *p)); - *p = 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; @@ -1181,14 +1229,6 @@ emit_messages(struct wl_list *message_list, printf("};\n\n"); } -static int -cmp_names(const void *p1, const void *p2) -{ - const char * const *s1 = p1, * const *s2 = p2; - - return strcmp(*s1, *s2); -} - static void emit_code(struct protocol *protocol) { @@ -1260,33 +1300,82 @@ int main(int argc, char *argv[]) FILE *input = stdin; int len; void *buf; + bool help = false, core_headers = false; + bool fail = false; + int opt, option_index = 0; enum { CLIENT_HEADER, SERVER_HEADER, CODE, } mode; - if (argc != 2 && argc != 4) + static const struct option options[] = { + {"help", no_argument, 0, 0 }, + {"include-core-only", no_argument, 0, 0 }, + {0, 0, 0, 0 } + }; + + while (1) { + opt = getopt_long(argc, argv, "hc", + options, &option_index); + + if (opt == -1) + break; + + if (opt == 0) { + switch (option_index) { + case 0: + help = true; + break; + case 1: + core_headers = true; + break; + default: + fail = true; + break; + } + continue; + } + + switch (opt) { + case 'h': + help = true; + break; + case 'c': + core_headers = true; + break; + default: + fail = true; + break; + } + } + + argv += optind; + argc -= optind; + + if (help) + usage(EXIT_SUCCESS); + else if ((argc != 1 && argc != 3) || fail) usage(EXIT_FAILURE); - else if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0) + else if (strcmp(argv[0], "help") == 0) usage(EXIT_SUCCESS); - else if (strcmp(argv[1], "client-header") == 0) + else if (strcmp(argv[0], "client-header") == 0) mode = CLIENT_HEADER; - else if (strcmp(argv[1], "server-header") == 0) + else if (strcmp(argv[0], "server-header") == 0) mode = SERVER_HEADER; - else if (strcmp(argv[1], "code") == 0) + else if (strcmp(argv[0], "code") == 0) mode = CODE; else usage(EXIT_FAILURE); - if (argc == 4) { - input = fopen(argv[2], "r"); + if (argc == 3) { + input = fopen(argv[1], "r"); if (input == NULL) { fprintf(stderr, "Could not open input file: %s\n", strerror(errno)); exit(EXIT_FAILURE); } - if (freopen(argv[3], "w", stdout) == NULL) { + if (freopen(argv[2], "w", stdout) == NULL) { fprintf(stderr, "Could not open output file: %s\n", strerror(errno)); exit(EXIT_FAILURE); @@ -1297,6 +1386,7 @@ int main(int argc, char *argv[]) protocol.type_index = 0; protocol.null_run_length = 0; protocol.copyright = NULL; + protocol.core_headers = core_headers; memset(&ctx, 0, sizeof ctx); ctx.protocol = &protocol; |
