2010-08-03 09:26:44 -04:00
|
|
|
/*
|
2011-08-11 14:51:31 -04:00
|
|
|
* Copyright © 2008-2011 Kristian Høgsberg
|
|
|
|
|
* Copyright © 2011 Intel Corporation
|
2010-08-03 09:26:44 -04:00
|
|
|
*
|
2011-08-11 14:51:31 -04:00
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
|
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
|
|
|
* that the name of the copyright holders not be used in advertising or
|
|
|
|
|
* publicity pertaining to distribution of the software without specific,
|
|
|
|
|
* written prior permission. The copyright holders make no representations
|
|
|
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
|
|
|
* is" without express or implied warranty.
|
2010-08-03 09:26:44 -04:00
|
|
|
*
|
2011-08-11 14:51:31 -04:00
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
|
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
|
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
|
|
|
* OF THIS SOFTWARE.
|
2010-08-03 09:26:44 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <expat.h>
|
|
|
|
|
|
|
|
|
|
#include "wayland-util.h"
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
usage(int ret)
|
|
|
|
|
{
|
2011-04-06 15:36:01 +02:00
|
|
|
fprintf(stderr, "usage: ./scanner [client-header|server-header|code]\n");
|
2010-08-03 09:26:44 -04:00
|
|
|
exit(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define XML_BUFFER_SIZE 4096
|
|
|
|
|
|
|
|
|
|
struct protocol {
|
2010-09-14 15:52:43 -04:00
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
2010-08-03 09:26:44 -04:00
|
|
|
struct wl_list interface_list;
|
2011-07-12 13:22:25 -04:00
|
|
|
int type_index;
|
|
|
|
|
int null_run_length;
|
2011-07-25 18:14:20 -07:00
|
|
|
char *copyright;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description {
|
|
|
|
|
char *summary;
|
|
|
|
|
char *text;
|
|
|
|
|
};
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
struct interface {
|
|
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
|
|
|
|
int version;
|
|
|
|
|
struct wl_list request_list;
|
|
|
|
|
struct wl_list event_list;
|
2011-01-21 21:57:55 -05:00
|
|
|
struct wl_list enumeration_list;
|
2010-08-03 09:26:44 -04:00
|
|
|
struct wl_list link;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *description;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct message {
|
|
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
|
|
|
|
struct wl_list arg_list;
|
|
|
|
|
struct wl_list link;
|
2011-07-12 13:22:25 -04:00
|
|
|
int arg_count;
|
|
|
|
|
int type_index;
|
|
|
|
|
int all_null;
|
2010-09-02 20:22:42 -04:00
|
|
|
int destructor;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *description;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum arg_type {
|
|
|
|
|
NEW_ID,
|
|
|
|
|
INT,
|
|
|
|
|
UNSIGNED,
|
|
|
|
|
STRING,
|
|
|
|
|
OBJECT,
|
2010-08-26 21:49:44 -04:00
|
|
|
ARRAY,
|
|
|
|
|
FD
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct arg {
|
|
|
|
|
char *name;
|
|
|
|
|
enum arg_type type;
|
2010-08-09 21:25:50 -04:00
|
|
|
char *interface_name;
|
2010-08-03 09:26:44 -04:00
|
|
|
struct wl_list link;
|
|
|
|
|
};
|
|
|
|
|
|
2011-01-21 21:57:55 -05:00
|
|
|
struct enumeration {
|
|
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
|
|
|
|
struct wl_list entry_list;
|
|
|
|
|
struct wl_list link;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *description;
|
2011-01-21 21:57:55 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct entry {
|
|
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
|
|
|
|
char *value;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
char *summary;
|
2011-01-21 21:57:55 -05:00
|
|
|
struct wl_list link;
|
|
|
|
|
};
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
struct parse_context {
|
2011-04-13 16:50:02 -04:00
|
|
|
const char *filename;
|
|
|
|
|
XML_Parser parser;
|
2010-08-03 09:26:44 -04:00
|
|
|
struct protocol *protocol;
|
|
|
|
|
struct interface *interface;
|
|
|
|
|
struct message *message;
|
2011-01-21 21:57:55 -05:00
|
|
|
struct enumeration *enumeration;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *description;
|
2011-07-25 18:14:20 -07:00
|
|
|
char character_data[8192];
|
|
|
|
|
int character_data_length;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
static char *
|
|
|
|
|
desc_dup(char *src)
|
|
|
|
|
{
|
|
|
|
|
char *u;
|
|
|
|
|
int i, j = 0, col = 0, line = 0, len;
|
|
|
|
|
|
|
|
|
|
len = strlen(src) * 2;
|
|
|
|
|
u = malloc(len); /* enough room for newlines & comments */
|
|
|
|
|
if (!u)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
memset(u, 0, len);
|
|
|
|
|
|
|
|
|
|
/* Strip leading space */
|
|
|
|
|
for (i = 0; isspace(src[i]); i++)
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
for (; src[i]; i++) {
|
|
|
|
|
/* Collapse multiple spaces into 1 */
|
|
|
|
|
if (isspace(src[i]) && isspace(src[i + 1]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (isspace(src[i]))
|
|
|
|
|
src[i] = ' ';
|
|
|
|
|
|
|
|
|
|
if (col > 72 && isspace(src[i])) {
|
|
|
|
|
if (src[i+1]) {
|
|
|
|
|
u[j++] = '\n';
|
|
|
|
|
u[j++] = ' ';
|
|
|
|
|
u[j++] = '*';
|
|
|
|
|
u[j++] = ' ';
|
|
|
|
|
}
|
|
|
|
|
line++;
|
|
|
|
|
col = 0;
|
|
|
|
|
} else {
|
|
|
|
|
u[j++] = src[i];
|
|
|
|
|
col++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
u[j++] = '\0';
|
|
|
|
|
|
|
|
|
|
return u;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
static void
|
|
|
|
|
fail(struct parse_context *ctx, const char *msg)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "%s:%ld: %s\n",
|
|
|
|
|
ctx->filename, XML_GetCurrentLineNumber(ctx->parser), msg);
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2011-01-21 21:57:55 -05:00
|
|
|
struct enumeration *enumeration;
|
|
|
|
|
struct entry *entry;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *description;
|
|
|
|
|
const char *name, *type, *interface_name, *value, *summary;
|
2010-08-03 09:26:44 -04:00
|
|
|
int i, version;
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
name = NULL;
|
|
|
|
|
type = NULL;
|
2010-08-03 09:26:44 -04:00
|
|
|
version = 0;
|
2010-08-09 21:25:50 -04:00
|
|
|
interface_name = NULL;
|
2011-01-21 21:57:55 -05:00
|
|
|
value = NULL;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
summary = NULL;
|
|
|
|
|
description = NULL;
|
2010-08-03 09:26:44 -04:00
|
|
|
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];
|
2011-01-21 21:57:55 -05:00
|
|
|
if (strcmp(atts[i], "value") == 0)
|
|
|
|
|
value = atts[i + 1];
|
2010-08-09 21:25:50 -04:00
|
|
|
if (strcmp(atts[i], "interface") == 0)
|
|
|
|
|
interface_name = atts[i + 1];
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
if (strcmp(atts[i], "summary") == 0)
|
|
|
|
|
summary = atts[i + 1];
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
ctx->character_data_length = 0;
|
2010-09-14 15:52:43 -04:00
|
|
|
if (strcmp(element_name, "protocol") == 0) {
|
2011-04-13 16:50:02 -04:00
|
|
|
if (name == NULL)
|
|
|
|
|
fail(ctx, "no protocol name given");
|
2010-09-14 15:52:43 -04:00
|
|
|
|
|
|
|
|
ctx->protocol->name = strdup(name);
|
|
|
|
|
ctx->protocol->uppercase_name = uppercase_dup(name);
|
2011-07-25 18:14:20 -07:00
|
|
|
} else if (strcmp(element_name, "copyright") == 0) {
|
|
|
|
|
|
2010-09-14 15:52:43 -04:00
|
|
|
} else if (strcmp(element_name, "interface") == 0) {
|
2011-04-13 16:50:02 -04:00
|
|
|
if (name == NULL)
|
|
|
|
|
fail(ctx, "no interface name given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
if (version == 0)
|
|
|
|
|
fail(ctx, "no interface version given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
interface = malloc(sizeof *interface);
|
|
|
|
|
interface->name = strdup(name);
|
|
|
|
|
interface->uppercase_name = uppercase_dup(name);
|
|
|
|
|
interface->version = version;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
interface->description = NULL;
|
2010-08-03 09:26:44 -04:00
|
|
|
wl_list_init(&interface->request_list);
|
|
|
|
|
wl_list_init(&interface->event_list);
|
2011-01-21 21:57:55 -05:00
|
|
|
wl_list_init(&interface->enumeration_list);
|
2010-08-03 09:26:44 -04:00
|
|
|
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) {
|
2011-04-13 16:50:02 -04:00
|
|
|
if (name == NULL)
|
|
|
|
|
fail(ctx, "no request name given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
message = malloc(sizeof *message);
|
|
|
|
|
message->name = strdup(name);
|
|
|
|
|
message->uppercase_name = uppercase_dup(name);
|
|
|
|
|
wl_list_init(&message->arg_list);
|
2011-07-12 13:22:25 -04:00
|
|
|
message->arg_count = 0;
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2010-09-02 20:22:42 -04:00
|
|
|
if (type != NULL && strcmp(type, "destructor") == 0)
|
|
|
|
|
message->destructor = 1;
|
|
|
|
|
else
|
|
|
|
|
message->destructor = 0;
|
|
|
|
|
|
2011-05-04 15:51:47 -04:00
|
|
|
if (strcmp(name, "destroy") == 0 && !message->destructor)
|
|
|
|
|
fail(ctx, "destroy request should be destructor type");
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
ctx->message = message;
|
|
|
|
|
} else if (strcmp(element_name, "arg") == 0) {
|
|
|
|
|
arg = malloc(sizeof *arg);
|
|
|
|
|
arg->name = strdup(name);
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
if (strcmp(type, "int") == 0)
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2010-08-26 21:49:44 -04:00
|
|
|
else if (strcmp(type, "fd") == 0)
|
|
|
|
|
arg->type = FD;
|
2010-08-09 21:25:50 -04:00
|
|
|
else if (strcmp(type, "new_id") == 0) {
|
|
|
|
|
arg->type = NEW_ID;
|
|
|
|
|
} else if (strcmp(type, "object") == 0) {
|
2010-08-03 09:26:44 -04:00
|
|
|
arg->type = OBJECT;
|
2010-08-09 21:25:50 -04:00
|
|
|
} else {
|
2011-04-13 16:50:02 -04:00
|
|
|
fail(ctx, "unknown type");
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
2011-10-24 16:04:09 -04:00
|
|
|
switch (arg->type) {
|
|
|
|
|
case NEW_ID:
|
|
|
|
|
case OBJECT:
|
|
|
|
|
if (interface_name == NULL)
|
|
|
|
|
fail(ctx, "no interface name given");
|
2011-11-18 21:23:33 -05:00
|
|
|
arg->interface_name = strdup(interface_name);
|
2011-10-24 16:04:09 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (interface_name != NULL)
|
2011-10-24 17:05:39 -04:00
|
|
|
fail(ctx, "interface not allowed");
|
2011-10-24 16:04:09 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-21 21:57:55 -05:00
|
|
|
wl_list_insert(ctx->message->arg_list.prev, &arg->link);
|
2011-07-12 13:22:25 -04:00
|
|
|
ctx->message->arg_count++;
|
2011-01-21 21:57:55 -05:00
|
|
|
} else if (strcmp(element_name, "enum") == 0) {
|
2011-04-13 16:50:02 -04:00
|
|
|
if (name == NULL)
|
|
|
|
|
fail(ctx, "no enum name given");
|
2011-01-21 21:57:55 -05:00
|
|
|
|
|
|
|
|
enumeration = malloc(sizeof *enumeration);
|
|
|
|
|
enumeration->name = strdup(name);
|
|
|
|
|
enumeration->uppercase_name = uppercase_dup(name);
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
enumeration->description = NULL;
|
2011-01-21 21:57:55 -05:00
|
|
|
wl_list_init(&enumeration->entry_list);
|
|
|
|
|
|
|
|
|
|
wl_list_insert(ctx->interface->enumeration_list.prev,
|
|
|
|
|
&enumeration->link);
|
|
|
|
|
|
|
|
|
|
ctx->enumeration = enumeration;
|
|
|
|
|
} else if (strcmp(element_name, "entry") == 0) {
|
2011-10-31 11:21:38 -04:00
|
|
|
if (name == NULL)
|
|
|
|
|
fail(ctx, "no entry name given");
|
|
|
|
|
|
2011-01-21 21:57:55 -05:00
|
|
|
entry = malloc(sizeof *entry);
|
|
|
|
|
entry->name = strdup(name);
|
|
|
|
|
entry->uppercase_name = uppercase_dup(name);
|
|
|
|
|
entry->value = strdup(value);
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
if (summary)
|
|
|
|
|
entry->summary = strdup(summary);
|
|
|
|
|
else
|
|
|
|
|
entry->summary = NULL;
|
2011-01-21 21:57:55 -05:00
|
|
|
wl_list_insert(ctx->enumeration->entry_list.prev,
|
|
|
|
|
&entry->link);
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
} else if (strcmp(element_name, "description") == 0) {
|
|
|
|
|
if (summary == NULL)
|
|
|
|
|
fail(ctx, "description without summary");
|
|
|
|
|
|
|
|
|
|
description = malloc(sizeof *description);
|
|
|
|
|
if (summary)
|
|
|
|
|
description->summary = strdup(summary);
|
|
|
|
|
else
|
|
|
|
|
description->summary = NULL;
|
|
|
|
|
|
|
|
|
|
if (ctx->message)
|
|
|
|
|
ctx->message->description = description;
|
|
|
|
|
else if (ctx->enumeration)
|
|
|
|
|
ctx->enumeration->description = description;
|
|
|
|
|
else if (ctx->interface)
|
|
|
|
|
ctx->interface->description = description;
|
|
|
|
|
else
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"<description> found in unsupported element\n");
|
|
|
|
|
ctx->description = description;
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
static void
|
|
|
|
|
end_element(void *data, const XML_Char *name)
|
|
|
|
|
{
|
|
|
|
|
struct parse_context *ctx = data;
|
|
|
|
|
|
|
|
|
|
if (strcmp(name, "copyright") == 0) {
|
|
|
|
|
ctx->protocol->copyright =
|
|
|
|
|
strndup(ctx->character_data,
|
|
|
|
|
ctx->character_data_length);
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
} else if (strcmp(name, "description") == 0) {
|
|
|
|
|
char *text = strndup(ctx->character_data,
|
|
|
|
|
ctx->character_data_length);
|
|
|
|
|
if (text)
|
|
|
|
|
ctx->description->text = desc_dup(text);
|
|
|
|
|
ctx->description = NULL;
|
|
|
|
|
} else if (strcmp(name, "request") == 0 ||
|
|
|
|
|
strcmp(name, "event") == 0) {
|
|
|
|
|
ctx->message = NULL;
|
|
|
|
|
} else if (strcmp(name, "enum") == 0) {
|
|
|
|
|
ctx->enumeration = NULL;
|
2011-07-25 18:14:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
character_data(void *data, const XML_Char *s, int len)
|
|
|
|
|
{
|
|
|
|
|
struct parse_context *ctx = data;
|
|
|
|
|
|
|
|
|
|
if (ctx->character_data_length + len > sizeof (ctx->character_data)) {
|
|
|
|
|
fprintf(stderr, "too much character data");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(ctx->character_data + ctx->character_data_length, s, len);
|
|
|
|
|
ctx->character_data_length += len;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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)
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("#define %s_%s\t%d\n",
|
2010-08-03 09:26:44 -04:00
|
|
|
interface->uppercase_name, m->uppercase_name, opcode++);
|
|
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
static void
|
|
|
|
|
emit_type(struct arg *a)
|
|
|
|
|
{
|
|
|
|
|
switch (a->type) {
|
|
|
|
|
default:
|
|
|
|
|
case INT:
|
2010-08-26 21:49:44 -04:00
|
|
|
case FD:
|
2011-07-07 13:39:08 -04:00
|
|
|
printf("int32_t ");
|
2010-08-09 21:25:50 -04:00
|
|
|
break;
|
|
|
|
|
case NEW_ID:
|
|
|
|
|
case UNSIGNED:
|
|
|
|
|
printf("uint32_t ");
|
|
|
|
|
break;
|
|
|
|
|
case STRING:
|
|
|
|
|
printf("const char *");
|
|
|
|
|
break;
|
|
|
|
|
case OBJECT:
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("struct %s *", a->interface_name);
|
2010-08-09 21:25:50 -04:00
|
|
|
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;
|
2010-09-02 20:22:42 -04:00
|
|
|
int has_destructor, has_destroy;
|
2010-08-09 21:25:50 -04:00
|
|
|
|
2011-08-19 13:40:28 -04:00
|
|
|
/* We provide a hand written functions for the display object */
|
|
|
|
|
if (strcmp(interface->name, "wl_display") == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2010-08-17 21:23:10 -04:00
|
|
|
printf("static inline void\n"
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_set_user_data(struct %s *%s, void *user_data)\n"
|
2010-08-17 21:23:10 -04:00
|
|
|
"{\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"
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_get_user_data(struct %s *%s)\n"
|
2010-08-17 21:23:10 -04:00
|
|
|
"{\n"
|
|
|
|
|
"\treturn wl_proxy_get_user_data((struct wl_proxy *) %s);\n"
|
|
|
|
|
"}\n\n",
|
|
|
|
|
interface->name, interface->name, interface->name,
|
|
|
|
|
interface->name);
|
|
|
|
|
|
2010-09-02 20:22:42 -04:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-19 13:40:28 -04:00
|
|
|
if (!has_destructor)
|
2010-09-02 20:22:42 -04:00
|
|
|
printf("static inline void\n"
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_destroy(struct %s *%s)\n"
|
2010-09-02 20:22:42 -04:00
|
|
|
"{\n"
|
|
|
|
|
"\twl_proxy_destroy("
|
|
|
|
|
"(struct wl_proxy *) %s);\n"
|
|
|
|
|
"}\n\n",
|
|
|
|
|
interface->name, interface->name, interface->name,
|
|
|
|
|
interface->name);
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
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)
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("static inline struct %s *\n",
|
2010-08-09 21:25:50 -04:00
|
|
|
ret->interface_name);
|
|
|
|
|
else
|
|
|
|
|
printf("static inline void\n");
|
|
|
|
|
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("%s_%s(struct %s *%s",
|
2010-08-09 21:25:50 -04:00
|
|
|
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("
|
2010-08-10 10:53:44 -04:00
|
|
|
"(struct wl_proxy *) %s,\n"
|
2011-04-18 10:24:11 -04:00
|
|
|
"\t\t\t &%s_interface);\n"
|
2010-08-09 21:25:50 -04:00
|
|
|
"\tif (!%s)\n"
|
|
|
|
|
"\t\treturn NULL;\n\n",
|
|
|
|
|
ret->name,
|
|
|
|
|
ret->name,
|
|
|
|
|
interface->name, ret->interface_name,
|
|
|
|
|
ret->name);
|
|
|
|
|
|
2010-08-10 10:53:44 -04:00
|
|
|
printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
|
2011-04-18 10:24:11 -04:00
|
|
|
"\t\t\t %s_%s",
|
2010-08-09 21:25:50 -04:00
|
|
|
interface->name,
|
|
|
|
|
interface->uppercase_name,
|
|
|
|
|
m->uppercase_name);
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
|
|
|
|
printf(", ");
|
|
|
|
|
printf("%s", a->name);
|
|
|
|
|
}
|
|
|
|
|
printf(");\n");
|
|
|
|
|
|
2010-09-02 20:22:42 -04:00
|
|
|
if (m->destructor)
|
|
|
|
|
printf("\n\twl_proxy_destroy("
|
|
|
|
|
"(struct wl_proxy *) %s);\n",
|
|
|
|
|
interface->name);
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
if (ret)
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("\n\treturn (struct %s *) %s;\n",
|
2010-08-09 21:25:50 -04:00
|
|
|
ret->interface_name, ret->name);
|
|
|
|
|
|
|
|
|
|
printf("}\n\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-10 10:53:44 -04:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-21 21:57:55 -05:00
|
|
|
static void
|
|
|
|
|
emit_enumerations(struct interface *interface)
|
|
|
|
|
{
|
|
|
|
|
struct enumeration *e;
|
|
|
|
|
struct entry *entry;
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(e, &interface->enumeration_list, link) {
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
struct description *desc = e->description;
|
|
|
|
|
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("#ifndef %s_%s_ENUM\n",
|
2011-01-23 12:21:15 +01:00
|
|
|
interface->uppercase_name, e->uppercase_name);
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("#define %s_%s_ENUM\n",
|
2011-01-23 12:21:15 +01:00
|
|
|
interface->uppercase_name, e->uppercase_name);
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
|
|
|
|
|
if (desc) {
|
|
|
|
|
printf("/**\n"
|
|
|
|
|
" * %s_%s - %s\n", interface->name,
|
|
|
|
|
e->name, desc->summary);
|
|
|
|
|
wl_list_for_each(entry, &e->entry_list, link) {
|
|
|
|
|
printf(" * @%s_%s_%s: %s\n",
|
|
|
|
|
interface->uppercase_name,
|
|
|
|
|
e->uppercase_name,
|
|
|
|
|
entry->uppercase_name,
|
|
|
|
|
entry->summary);
|
|
|
|
|
}
|
|
|
|
|
if (desc->text) {
|
|
|
|
|
printf(" *\n"
|
|
|
|
|
" * %s\n", desc->text);
|
|
|
|
|
}
|
|
|
|
|
printf(" */\n");
|
|
|
|
|
}
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("enum %s_%s {\n", interface->name, e->name);
|
2011-01-21 21:57:55 -05:00
|
|
|
wl_list_for_each(entry, &e->entry_list, link)
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("\t%s_%s_%s = %s,\n",
|
2011-01-21 21:57:55 -05:00
|
|
|
interface->uppercase_name,
|
|
|
|
|
e->uppercase_name,
|
|
|
|
|
entry->uppercase_name, entry->value);
|
2011-01-23 12:21:15 +01:00
|
|
|
printf("};\n");
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("#endif /* %s_%s_ENUM */\n\n",
|
2011-01-23 12:21:15 +01:00
|
|
|
interface->uppercase_name, e->uppercase_name);
|
2011-01-21 21:57:55 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
static void
|
|
|
|
|
emit_structs(struct wl_list *message_list, struct interface *interface)
|
|
|
|
|
{
|
|
|
|
|
struct message *m;
|
|
|
|
|
struct arg *a;
|
2010-08-10 10:53:44 -04:00
|
|
|
int is_interface, n;
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
if (wl_list_empty(message_list))
|
|
|
|
|
return;
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
is_interface = message_list == &interface->request_list;
|
scanner: Support documentation elements
On Wed, 18 Jan 2012 12:29:37 -0800
"Kristensen, Kristian H" <kristian.h.kristensen@intel.com> wrote:
> Yeah, that looks good. I was thinking of a separate <description> tag
> to avoid stuffing too much into an attribute.
How does this look? It adds a summary attribute to atomic elements,
and a <description> tag with a summary for others. Spits out enum
documentation like this:
/**
* wl_display_error - global error values
* @WL_DISPLAY_ERROR_INVALID_OBJECT: server couldn't find object
* @WL_DISPLAY_ERROR_INVALID_METHOD: method doesn't exist on the specified interface
* @WL_DISPLAY_ERROR_NO_MEMORY: server is out of memory
*
* These errors are global and can be emitted in response to any server request.
*/
enum wl_display_error {
WL_DISPLAY_ERROR_INVALID_OBJECT = 0,
WL_DISPLAY_ERROR_INVALID_METHOD = 1,
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
and structure documentation like this:
/**
* wl_display - core global object
* @bind: bind an object to the display
* @sync: (none)
*
* The core global object. This is a special singleton object. It is used for
* internal wayland protocol features.
*/
struct wl_display_interface {
void (*bind)(struct wl_client *client,
struct wl_resource *resource,
uint32_t name,
const char *interface,
uint32_t version,
uint32_t id);
void (*sync)(struct wl_client *client,
struct wl_resource *resource,
uint32_t callback);
};
2012-01-18 14:09:47 -08:00
|
|
|
if (interface->description) {
|
|
|
|
|
struct description *desc = interface->description;
|
|
|
|
|
printf("/**\n"
|
|
|
|
|
" * %s - %s\n", interface->name, desc->summary);
|
|
|
|
|
wl_list_for_each(m, message_list, link) {
|
|
|
|
|
struct description *mdesc = m->description;
|
|
|
|
|
printf(" * @%s: %s\n", m->name, mdesc ? mdesc->summary :
|
|
|
|
|
"(none)");
|
|
|
|
|
}
|
|
|
|
|
printf(" *\n"
|
|
|
|
|
" * %s\n"
|
|
|
|
|
" */\n", desc->text);
|
|
|
|
|
}
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("struct %s_%s {\n", interface->name,
|
2010-08-03 09:26:44 -04:00
|
|
|
is_interface ? "interface" : "listener");
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(m, message_list, link) {
|
|
|
|
|
printf("\tvoid (*%s)(", m->name);
|
|
|
|
|
|
2010-08-10 10:53:44 -04:00
|
|
|
n = strlen(m->name) + 17;
|
2010-08-03 09:26:44 -04:00
|
|
|
if (is_interface) {
|
2010-08-10 10:53:44 -04:00
|
|
|
printf("struct wl_client *client,\n"
|
2011-08-18 17:53:50 -04:00
|
|
|
"%sstruct wl_resource *resource",
|
|
|
|
|
indent(n));
|
2010-08-03 09:26:44 -04:00
|
|
|
} else {
|
2010-08-10 10:53:44 -04:00
|
|
|
printf("void *data,\n"),
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("%sstruct %s *%s",
|
2010-08-10 10:53:44 -04:00
|
|
|
indent(n), interface->name, interface->name);
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
2010-08-10 10:53:44 -04:00
|
|
|
printf(",\n%s", indent(n));
|
|
|
|
|
|
2011-08-27 12:05:09 -04:00
|
|
|
if (is_interface && a->type == OBJECT)
|
|
|
|
|
printf("struct wl_resource *");
|
|
|
|
|
else
|
|
|
|
|
emit_type(a);
|
|
|
|
|
|
2010-08-10 10:53:44 -04:00
|
|
|
printf("%s", a->name);
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(");\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("};\n\n");
|
2010-08-10 10:53:44 -04:00
|
|
|
|
|
|
|
|
if (!is_interface) {
|
|
|
|
|
printf("static inline int\n"
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_add_listener(struct %s *%s,\n"
|
|
|
|
|
"%sconst struct %s_listener *listener, void *data)\n"
|
2010-08-10 10:53:44 -04:00
|
|
|
"{\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,
|
2011-08-09 14:31:36 +02:00
|
|
|
indent(14 + strlen(interface->name)),
|
2010-08-10 10:53:44 -04:00
|
|
|
interface->name,
|
|
|
|
|
interface->name,
|
|
|
|
|
indent(37));
|
|
|
|
|
}
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
static void
|
|
|
|
|
format_copyright(const char *copyright)
|
|
|
|
|
{
|
2011-07-27 12:05:34 -07:00
|
|
|
int bol = 1, start = 0, i;
|
2011-07-25 18:14:20 -07:00
|
|
|
|
|
|
|
|
for (i = 0; copyright[i]; i++) {
|
|
|
|
|
if (bol && (copyright[i] == ' ' || copyright[i] == '\t')) {
|
|
|
|
|
continue;
|
|
|
|
|
} else if (bol) {
|
|
|
|
|
bol = 0;
|
|
|
|
|
start = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (copyright[i] == '\n' || copyright[i] == '\0') {
|
|
|
|
|
printf("%s %.*s\n",
|
|
|
|
|
i == 0 ? "/*" : " *",
|
|
|
|
|
i - start, copyright + start);
|
|
|
|
|
bol = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
printf(" */\n\n");
|
|
|
|
|
}
|
2010-08-10 14:02:48 -04:00
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
static void
|
|
|
|
|
emit_header(struct protocol *protocol, int server)
|
|
|
|
|
{
|
|
|
|
|
struct interface *i;
|
2010-09-14 15:52:43 -04:00
|
|
|
const char *s = server ? "SERVER" : "CLIENT";
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
if (protocol->copyright)
|
|
|
|
|
format_copyright(protocol->copyright);
|
|
|
|
|
|
|
|
|
|
printf("#ifndef %s_%s_PROTOCOL_H\n"
|
2010-09-14 15:52:43 -04:00
|
|
|
"#define %s_%s_PROTOCOL_H\n"
|
2010-08-03 09:26:44 -04:00
|
|
|
"\n"
|
|
|
|
|
"#ifdef __cplusplus\n"
|
|
|
|
|
"extern \"C\" {\n"
|
|
|
|
|
"#endif\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"#include <stdint.h>\n"
|
2010-11-21 11:47:11 +01:00
|
|
|
"#include <stddef.h>\n"
|
2010-08-03 09:26:44 -04:00
|
|
|
"#include \"wayland-util.h\"\n\n"
|
2011-08-18 17:53:50 -04:00
|
|
|
"struct wl_client;\n"
|
|
|
|
|
"struct wl_resource;\n\n",
|
2010-09-14 15:52:43 -04:00
|
|
|
protocol->uppercase_name, s,
|
|
|
|
|
protocol->uppercase_name, s);
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
wl_list_for_each(i, &protocol->interface_list, link)
|
2011-04-18 10:24:11 -04:00
|
|
|
printf("struct %s;\n", i->name);
|
2010-08-03 09:26:44 -04:00
|
|
|
printf("\n");
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
wl_list_for_each(i, &protocol->interface_list, link) {
|
|
|
|
|
printf("extern const struct wl_interface "
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_interface;\n",
|
2010-08-09 21:25:50 -04:00
|
|
|
i->name);
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
wl_list_for_each(i, &protocol->interface_list, link) {
|
|
|
|
|
|
2011-01-21 21:57:55 -05:00
|
|
|
emit_enumerations(i);
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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);
|
2010-08-09 21:25:50 -04:00
|
|
|
emit_stubs(&i->request_list, i);
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("#ifdef __cplusplus\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"#endif\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"#endif\n");
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-12 13:22:25 -04:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2010-08-26 21:49:44 -04:00
|
|
|
case FD:
|
|
|
|
|
printf("h");
|
|
|
|
|
break;
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
}
|
2011-07-12 13:22:25 -04:00
|
|
|
printf("\", types + %d },\n", m->type_index);
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("};\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
emit_code(struct protocol *protocol)
|
|
|
|
|
{
|
|
|
|
|
struct interface *i;
|
|
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
if (protocol->copyright)
|
|
|
|
|
format_copyright(protocol->copyright);
|
|
|
|
|
|
|
|
|
|
printf("#include <stdlib.h>\n"
|
2010-08-03 09:26:44 -04:00
|
|
|
"#include <stdint.h>\n"
|
2011-07-25 18:14:20 -07:00
|
|
|
"#include \"wayland-util.h\"\n\n");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2011-07-12 13:22:25 -04:00
|
|
|
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");
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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 "
|
2011-04-18 10:24:11 -04:00
|
|
|
"%s_interface = {\n"
|
2010-08-03 09:26:44 -04:00
|
|
|
"\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;
|
|
|
|
|
int len;
|
|
|
|
|
void *buf;
|
|
|
|
|
|
|
|
|
|
if (argc != 2)
|
|
|
|
|
usage(EXIT_FAILURE);
|
|
|
|
|
|
|
|
|
|
wl_list_init(&protocol.interface_list);
|
2011-07-12 13:22:25 -04:00
|
|
|
protocol.type_index = 0;
|
|
|
|
|
protocol.null_run_length = 0;
|
2011-07-27 05:50:41 -07:00
|
|
|
protocol.copyright = NULL;
|
2010-08-03 09:26:44 -04:00
|
|
|
ctx.protocol = &protocol;
|
|
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
ctx.filename = "<stdin>";
|
|
|
|
|
ctx.parser = XML_ParserCreate(NULL);
|
|
|
|
|
XML_SetUserData(ctx.parser, &ctx);
|
|
|
|
|
if (ctx.parser == NULL) {
|
2010-08-03 09:26:44 -04:00
|
|
|
fprintf(stderr, "failed to create parser\n");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-25 18:14:20 -07:00
|
|
|
XML_SetElementHandler(ctx.parser, start_element, end_element);
|
|
|
|
|
XML_SetCharacterDataHandler(ctx.parser, character_data);
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
do {
|
2011-04-13 16:50:02 -04:00
|
|
|
buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
|
2010-08-03 09:26:44 -04:00
|
|
|
len = fread(buf, 1, XML_BUFFER_SIZE, stdin);
|
|
|
|
|
if (len < 0) {
|
|
|
|
|
fprintf(stderr, "fread: %s\n", strerror(errno));
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
2011-04-13 16:50:02 -04:00
|
|
|
XML_ParseBuffer(ctx.parser, len, len == 0);
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
} while (len > 0);
|
|
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
XML_ParserFree(ctx.parser);
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|