aboutsummaryrefslogtreecommitdiffstats
path: root/src/scanner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scanner.c')
-rw-r--r--src/scanner.c208
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;