aboutsummaryrefslogtreecommitdiffstats
path: root/scanner.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-09-14 11:13:18 -0400
committerKristian Høgsberg <krh@bitplanet.net>2010-09-14 12:41:55 -0400
commit6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c (patch)
tree7670e24beb6fab2629d0ccd4451df5f90a344d89 /scanner.c
parentMove example compositor to subdirectory (diff)
downloadwayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar.gz
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar.bz2
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar.lz
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar.xz
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.tar.zst
wayland-6dd08ebbe108c2c78cc23d6af0b00a84199d8b2c.zip
Move core protocol libraries into wayland/ subdirectory
Diffstat (limited to 'scanner.c')
-rw-r--r--scanner.c677
1 files changed, 0 insertions, 677 deletions
diff --git a/scanner.c b/scanner.c
deleted file mode 100644
index 613e12b..0000000
--- a/scanner.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <expat.h>
-
-#include "wayland-util.h"
-
-static const char copyright[] =
- "/*\n"
- " * Copyright © 2010 Kristian Høgsberg\n"
- " *\n"
- " * Permission to use, copy, modify, distribute, and sell this software and its\n"
- " * documentation for any purpose is hereby granted without fee, provided that\n"
- " * the above copyright notice appear in all copies and that both that copyright\n"
- " * notice and this permission notice appear in supporting documentation, and\n"
- " * that the name of the copyright holders not be used in advertising or\n"
- " * publicity pertaining to distribution of the software without specific,\n"
- " * written prior permission. The copyright holders make no representations\n"
- " * about the suitability of this software for any purpose. It is provided \"as\n"
- " * is\" without express or implied warranty.\n"
- " *\n"
- " * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\n"
- " * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO\n"
- " * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR\n"
- " * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n"
- " * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n"
- " * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n"
- " * OF THIS SOFTWARE.\n"
- " */\n";
-
-static int
-usage(int ret)
-{
- fprintf(stderr, "usage: ./scanner [header|code]\n");
- exit(ret);
-}
-
-#define XML_BUFFER_SIZE 4096
-
-struct protocol {
- struct wl_list interface_list;
-};
-
-struct interface {
- char *name;
- char *uppercase_name;
- int version;
- struct wl_list request_list;
- struct wl_list event_list;
- struct wl_list link;
-};
-
-struct message {
- char *name;
- char *uppercase_name;
- struct wl_list arg_list;
- struct wl_list link;
- int destructor;
-};
-
-enum arg_type {
- NEW_ID,
- INT,
- UNSIGNED,
- STRING,
- OBJECT,
- ARRAY,
- FD
-};
-
-struct arg {
- char *name;
- enum arg_type type;
- char *interface_name;
- struct wl_list link;
-};
-
-struct parse_context {
- struct protocol *protocol;
- struct interface *interface;
- struct message *message;
-};
-
-static char *
-uppercase_dup(const char *src)
-{
- char *u;
- int i;
-
- u = strdup(src);
- for (i = 0; u[i]; i++)
- u[i] = toupper(u[i]);
- u[i] = '\0';
-
- return u;
-}
-
-static void
-start_element(void *data, const char *element_name, const char **atts)
-{
- struct parse_context *ctx = data;
- struct interface *interface;
- struct message *message;
- struct arg *arg;
- const char *name, *type, *interface_name;
- int i, version;
-
- name = NULL;
- type = NULL;
- version = 0;
- interface_name = NULL;
- for (i = 0; atts[i]; i += 2) {
- if (strcmp(atts[i], "name") == 0)
- name = atts[i + 1];
- if (strcmp(atts[i], "version") == 0)
- version = atoi(atts[i + 1]);
- if (strcmp(atts[i], "type") == 0)
- type = atts[i + 1];
- if (strcmp(atts[i], "interface") == 0)
- interface_name = atts[i + 1];
- }
-
- if (strcmp(element_name, "interface") == 0) {
- if (name == NULL) {
- fprintf(stderr, "no interface name given\n");
- exit(EXIT_FAILURE);
- }
-
- if (version == 0) {
- fprintf(stderr, "no interface version given\n");
- exit(EXIT_FAILURE);
- }
-
- interface = malloc(sizeof *interface);
- interface->name = strdup(name);
- interface->uppercase_name = uppercase_dup(name);
- interface->version = version;
- wl_list_init(&interface->request_list);
- wl_list_init(&interface->event_list);
- wl_list_insert(ctx->protocol->interface_list.prev,
- &interface->link);
- ctx->interface = interface;
- } else if (strcmp(element_name, "request") == 0 ||
- strcmp(element_name, "event") == 0) {
- if (name == NULL) {
- fprintf(stderr, "no request name given\n");
- exit(EXIT_FAILURE);
- }
-
- message = malloc(sizeof *message);
- message->name = strdup(name);
- message->uppercase_name = uppercase_dup(name);
- wl_list_init(&message->arg_list);
-
- if (strcmp(element_name, "request") == 0)
- wl_list_insert(ctx->interface->request_list.prev,
- &message->link);
- else
- wl_list_insert(ctx->interface->event_list.prev,
- &message->link);
-
- if (type != NULL && strcmp(type, "destructor") == 0)
- message->destructor = 1;
- else
- message->destructor = 0;
-
- ctx->message = message;
- } else if (strcmp(element_name, "arg") == 0) {
- arg = malloc(sizeof *arg);
- arg->name = strdup(name);
-
- if (strcmp(type, "int") == 0)
- arg->type = INT;
- else if (strcmp(type, "uint") == 0)
- arg->type = UNSIGNED;
- else if (strcmp(type, "string") == 0)
- arg->type = STRING;
- else if (strcmp(type, "array") == 0)
- arg->type = ARRAY;
- else if (strcmp(type, "fd") == 0)
- arg->type = FD;
- else if (strcmp(type, "new_id") == 0) {
- if (interface_name == NULL) {
- fprintf(stderr, "no interface name given\n");
- exit(EXIT_FAILURE);
- }
- arg->type = NEW_ID;
- arg->interface_name = strdup(interface_name);
- } else if (strcmp(type, "object") == 0) {
- if (interface_name == NULL) {
- fprintf(stderr, "no interface name given\n");
- exit(EXIT_FAILURE);
- }
- arg->type = OBJECT;
- arg->interface_name = strdup(interface_name);
- } else {
- fprintf(stderr, "unknown type: %s\n", type);
- exit(EXIT_FAILURE);
- }
-
- wl_list_insert(ctx->message->arg_list.prev,
- &arg->link);
- }
-}
-
-static void
-emit_opcodes(struct wl_list *message_list, struct interface *interface)
-{
- struct message *m;
- int opcode;
-
- if (wl_list_empty(message_list))
- return;
-
- opcode = 0;
- wl_list_for_each(m, message_list, link)
- printf("#define WL_%s_%s\t%d\n",
- interface->uppercase_name, m->uppercase_name, opcode++);
-
- printf("\n");
-}
-
-static void
-emit_type(struct arg *a)
-{
- switch (a->type) {
- default:
- case INT:
- case FD:
- printf("int ");
- break;
- case NEW_ID:
- case UNSIGNED:
- printf("uint32_t ");
- break;
- case STRING:
- printf("const char *");
- break;
- case OBJECT:
- printf("struct wl_%s *", a->interface_name);
- break;
- case ARRAY:
- printf("struct wl_array *");
- break;
- }
-}
-
-static void
-emit_stubs(struct wl_list *message_list, struct interface *interface)
-{
- struct message *m;
- struct arg *a, *ret;
- int has_destructor, has_destroy;
-
- /* We provide a hand written constructor for the display object */
- if (strcmp(interface->name, "display") != 0)
- printf("static inline struct wl_%s *\n"
- "wl_%s_create(struct wl_display *display, uint32_t id)\n"
- "{\n"
- "\treturn (struct wl_%s *)\n"
- "\t\twl_proxy_create_for_id(display, &wl_%s_interface, id);\n"
- "}\n\n",
- interface->name,
- interface->name,
- interface->name,
- interface->name);
-
- printf("static inline void\n"
- "wl_%s_set_user_data(struct wl_%s *%s, void *user_data)\n"
- "{\n"
- "\twl_proxy_set_user_data((struct wl_proxy *) %s, user_data);\n"
- "}\n\n",
- interface->name, interface->name, interface->name,
- interface->name);
-
- printf("static inline void *\n"
- "wl_%s_get_user_data(struct wl_%s *%s)\n"
- "{\n"
- "\treturn wl_proxy_get_user_data((struct wl_proxy *) %s);\n"
- "}\n\n",
- interface->name, interface->name, interface->name,
- interface->name);
-
- has_destructor = 0;
- has_destroy = 0;
- wl_list_for_each(m, message_list, link) {
- if (m->destructor)
- has_destructor = 1;
- if (strcmp(m->name, "destroy)") == 0)
- has_destroy = 1;
- }
-
- if (!has_destructor && has_destroy) {
- fprintf(stderr,
- "interface %s has method named destroy but"
- "no destructor", interface->name);
- exit(EXIT_FAILURE);
- }
-
- /* And we have a hand-written display destructor */
- if (!has_destructor && strcmp(interface->name, "display") != 0)
- printf("static inline void\n"
- "wl_%s_destroy(struct wl_%s *%s)\n"
- "{\n"
- "\twl_proxy_destroy("
- "(struct wl_proxy *) %s);\n"
- "}\n\n",
- interface->name, interface->name, interface->name,
- interface->name);
-
- if (wl_list_empty(message_list))
- return;
-
- wl_list_for_each(m, message_list, link) {
- ret = NULL;
- wl_list_for_each(a, &m->arg_list, link) {
- if (a->type == NEW_ID)
- ret = a;
- }
-
- if (ret)
- printf("static inline struct wl_%s *\n",
- ret->interface_name);
- else
- printf("static inline void\n");
-
- printf("wl_%s_%s(struct wl_%s *%s",
- interface->name, m->name,
- interface->name, interface->name);
-
- wl_list_for_each(a, &m->arg_list, link) {
- if (a->type == NEW_ID)
- continue;
- printf(", ");
- emit_type(a);
- printf("%s", a->name);
- }
-
- printf(")\n"
- "{\n");
- if (ret)
- printf("\tstruct wl_proxy *%s;\n\n"
- "\t%s = wl_proxy_create("
- "(struct wl_proxy *) %s,\n"
- "\t\t\t &wl_%s_interface);\n"
- "\tif (!%s)\n"
- "\t\treturn NULL;\n\n",
- ret->name,
- ret->name,
- interface->name, ret->interface_name,
- ret->name);
-
- printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
- "\t\t\t WL_%s_%s",
- interface->name,
- interface->uppercase_name,
- m->uppercase_name);
-
- wl_list_for_each(a, &m->arg_list, link) {
- printf(", ");
- printf("%s", a->name);
- }
- printf(");\n");
-
- if (m->destructor)
- printf("\n\twl_proxy_destroy("
- "(struct wl_proxy *) %s);\n",
- interface->name);
-
- if (ret)
- printf("\n\treturn (struct wl_%s *) %s;\n",
- ret->interface_name, ret->name);
-
- printf("}\n\n");
- }
-}
-
-static const char *indent(int n)
-{
- const char *whitespace[] = {
- "\t\t\t\t\t\t\t\t\t\t\t\t",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t ",
- "\t\t\t\t\t\t\t\t\t\t\t\t "
- };
-
- return whitespace[n % 8] + 12 - n / 8;
-}
-
-static void
-emit_structs(struct wl_list *message_list, struct interface *interface)
-{
- struct message *m;
- struct arg *a;
- int is_interface, n;
-
- if (wl_list_empty(message_list))
- return;
-
- is_interface = message_list == &interface->request_list;
- printf("struct wl_%s_%s {\n", interface->name,
- is_interface ? "interface" : "listener");
-
- wl_list_for_each(m, message_list, link) {
- printf("\tvoid (*%s)(", m->name);
-
- n = strlen(m->name) + 17;
- if (is_interface) {
- printf("struct wl_client *client,\n"
- "%sstruct wl_%s *%s",
- indent(n),
- interface->name, interface->name);
- } else {
- printf("void *data,\n"),
- printf("%sstruct wl_%s *%s",
- indent(n), interface->name, interface->name);
- }
-
- wl_list_for_each(a, &m->arg_list, link) {
- printf(",\n%s", indent(n));
-
- emit_type(a);
- printf("%s", a->name);
- }
-
- printf(");\n");
- }
-
- printf("};\n\n");
-
- if (!is_interface) {
- printf("static inline int\n"
- "wl_%s_add_listener(struct wl_%s *%s,\n"
- "%sconst struct wl_%s_listener *listener, void *data)\n"
- "{\n"
- "\treturn wl_proxy_add_listener((struct wl_proxy *) %s,\n"
- "%s(void (**)(void)) listener, data);\n"
- "}\n\n",
- interface->name, interface->name, interface->name,
- indent(17 + strlen(interface->name)),
- interface->name,
- interface->name,
- indent(37));
- }
-}
-
-static const char client_prototypes[] =
- "struct wl_proxy;\n\n"
-
- "extern void\n"
- "wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);\n"
-
- "extern struct wl_proxy *\n"
- "wl_proxy_create(struct wl_proxy *factory,\n"
- "\t\tconst struct wl_interface *interface);\n"
-
- "extern struct wl_proxy *\n"
- "wl_proxy_create_for_id(struct wl_display *display,\n"
- "\t\t const struct wl_interface *interface, uint32_t id);\n"
-
- "extern void\n"
- "wl_proxy_destroy(struct wl_proxy *proxy);\n\n"
-
- "extern int\n"
- "wl_proxy_add_listener(struct wl_proxy *proxy,\n"
- "\t\t void (**implementation)(void), void *data);\n\n"
-
- "extern void\n"
- "wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);\n\n"
-
- "extern void *\n"
- "wl_proxy_get_user_data(struct wl_proxy *proxy);\n\n";
-
-
-static void
-emit_header(struct protocol *protocol, int server)
-{
- struct interface *i;
-
- printf("%s\n\n"
- "#ifndef WAYLAND_PROTOCOL_H\n"
- "#define WAYLAND_PROTOCOL_H\n"
- "\n"
- "#ifdef __cplusplus\n"
- "extern \"C\" {\n"
- "#endif\n"
- "\n"
- "#include <stdint.h>\n"
- "#include \"wayland-util.h\"\n\n"
- "struct wl_client;\n\n", copyright);
-
- wl_list_for_each(i, &protocol->interface_list, link)
- printf("struct wl_%s;\n", i->name);
- printf("\n");
-
- if (!server)
- printf(client_prototypes);
-
- wl_list_for_each(i, &protocol->interface_list, link) {
- printf("extern const struct wl_interface "
- "wl_%s_interface;\n",
- i->name);
- }
- printf("\n");
-
- wl_list_for_each(i, &protocol->interface_list, link) {
-
- if (server) {
- emit_structs(&i->request_list, i);
- emit_opcodes(&i->event_list, i);
- } else {
- emit_structs(&i->event_list, i);
- emit_opcodes(&i->request_list, i);
- emit_stubs(&i->request_list, i);
- }
- }
-
- printf("#ifdef __cplusplus\n"
- "}\n"
- "#endif\n"
- "\n"
- "#endif\n");
-}
-
-static void
-emit_messages(struct wl_list *message_list,
- struct interface *interface, const char *suffix)
-{
- struct message *m;
- struct arg *a;
-
- if (wl_list_empty(message_list))
- return;
-
- printf("static const struct wl_message "
- "%s_%s[] = {\n",
- interface->name, suffix);
-
- wl_list_for_each(m, message_list, link) {
- printf("\t{ \"%s\", \"", m->name);
- wl_list_for_each(a, &m->arg_list, link) {
- switch (a->type) {
- default:
- case INT:
- printf("i");
- break;
- case NEW_ID:
- printf("n");
- break;
- case UNSIGNED:
- printf("u");
- break;
- case STRING:
- printf("s");
- break;
- case OBJECT:
- printf("o");
- break;
- case ARRAY:
- printf("a");
- break;
- case FD:
- printf("h");
- break;
- }
- }
- printf("\" },\n");
- }
-
- printf("};\n\n");
-}
-
-static void
-emit_code(struct protocol *protocol)
-{
- struct interface *i;
-
- printf("%s\n\n"
- "#include <stdlib.h>\n"
- "#include <stdint.h>\n"
- "#include \"wayland-util.h\"\n\n",
- copyright);
-
- wl_list_for_each(i, &protocol->interface_list, link) {
-
- emit_messages(&i->request_list, i, "requests");
- emit_messages(&i->event_list, i, "events");
-
- printf("WL_EXPORT const struct wl_interface "
- "wl_%s_interface = {\n"
- "\t\"%s\", %d,\n",
- i->name, i->name, i->version);
-
- if (!wl_list_empty(&i->request_list))
- printf("\tARRAY_LENGTH(%s_requests), %s_requests,\n",
- i->name, i->name);
- else
- printf("\t0, NULL,\n");
-
- if (!wl_list_empty(&i->event_list))
- printf("\tARRAY_LENGTH(%s_events), %s_events,\n",
- i->name, i->name);
- else
- printf("\t0, NULL,\n");
-
- printf("};\n\n");
- }
-}
-
-int main(int argc, char *argv[])
-{
- struct parse_context ctx;
- struct protocol protocol;
- XML_Parser parser;
- int len;
- void *buf;
-
- if (argc != 2)
- usage(EXIT_FAILURE);
-
- wl_list_init(&protocol.interface_list);
- ctx.protocol = &protocol;
-
- parser = XML_ParserCreate(NULL);
- XML_SetUserData(parser, &ctx);
- if (parser == NULL) {
- fprintf(stderr, "failed to create parser\n");
- exit(EXIT_FAILURE);
- }
-
- XML_SetElementHandler(parser, start_element, NULL);
- do {
- buf = XML_GetBuffer(parser, XML_BUFFER_SIZE);
- len = fread(buf, 1, XML_BUFFER_SIZE, stdin);
- if (len < 0) {
- fprintf(stderr, "fread: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- XML_ParseBuffer(parser, len, len == 0);
-
- } while (len > 0);
-
- XML_ParserFree(parser);
-
- if (strcmp(argv[1], "client-header") == 0) {
- emit_header(&protocol, 0);
- } else if (strcmp(argv[1], "server-header") == 0) {
- emit_header(&protocol, 1);
- } else if (strcmp(argv[1], "code") == 0) {
- emit_code(&protocol);
- }
-
- return 0;
-}