mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	
		
			
	
	
		
			444 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			444 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * 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;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum arg_type {
							 | 
						||
| 
								 | 
							
									NEW_ID,
							 | 
						||
| 
								 | 
							
									INT,
							 | 
						||
| 
								 | 
							
									UNSIGNED,
							 | 
						||
| 
								 | 
							
									STRING,
							 | 
						||
| 
								 | 
							
									OBJECT,
							 | 
						||
| 
								 | 
							
									ARRAY
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct arg {
							 | 
						||
| 
								 | 
							
									char *name;
							 | 
						||
| 
								 | 
							
									enum arg_type type;
							 | 
						||
| 
								 | 
							
									char *object_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;
							 | 
						||
| 
								 | 
							
									int i, version;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									name = 0;
							 | 
						||
| 
								 | 
							
									type = 0;
							 | 
						||
| 
								 | 
							
									version = 0;
							 | 
						||
| 
								 | 
							
									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(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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										ctx->message = message;
							 | 
						||
| 
								 | 
							
									} else if (strcmp(element_name, "arg") == 0) {
							 | 
						||
| 
								 | 
							
										arg = malloc(sizeof *arg);
							 | 
						||
| 
								 | 
							
										arg->name = strdup(name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (strcmp(type, "new_id") == 0)
							 | 
						||
| 
								 | 
							
											arg->type = NEW_ID;
							 | 
						||
| 
								 | 
							
										else 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 {
							 | 
						||
| 
								 | 
							
											arg->type = OBJECT;
							 | 
						||
| 
								 | 
							
											arg->object_name = strdup(type);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										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_structs(struct wl_list *message_list, struct interface *interface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									struct message *m;
							 | 
						||
| 
								 | 
							
									struct arg *a;
							 | 
						||
| 
								 | 
							
									int is_interface;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (is_interface) {
							 | 
						||
| 
								 | 
							
											printf("struct wl_client *client, struct wl_%s *%s",
							 | 
						||
| 
								 | 
							
											       interface->name, interface->name);
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											printf("void *data, struct wl_%s *%s",
							 | 
						||
| 
								 | 
							
											       interface->name, interface->name);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (!wl_list_empty(&m->arg_list))
							 | 
						||
| 
								 | 
							
											printf(", ");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										wl_list_for_each(a, &m->arg_list, link) {
							 | 
						||
| 
								 | 
							
											switch (a->type) {
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
											case INT:
							 | 
						||
| 
								 | 
							
												printf("int32_t ");
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case NEW_ID:
							 | 
						||
| 
								 | 
							
											case UNSIGNED:
							 | 
						||
| 
								 | 
							
												printf("uint32_t ");
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case STRING:
							 | 
						||
| 
								 | 
							
												printf("const char *");
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case OBJECT:
							 | 
						||
| 
								 | 
							
												printf("struct wl_%s *", a->object_name);
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case ARRAY:
							 | 
						||
| 
								 | 
							
												printf("struct wl_array *");
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											printf("%s%s",
							 | 
						||
| 
								 | 
							
											       a->name,
							 | 
						||
| 
								 | 
							
											       a->link.next == &m->arg_list ? "" : ", ");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										printf(");\n");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									printf("};\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");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										printf("extern const struct wl_interface "
							 | 
						||
| 
								 | 
							
										       "wl_%s_interface;\n\n",
							 | 
						||
| 
								 | 
							
										       i->name);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										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;
							 | 
						||
| 
								 | 
							
								}
							 |