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>
|
2012-05-07 23:41:48 -04:00
|
|
|
#include <stdarg.h>
|
2010-08-03 09:26:44 -04:00
|
|
|
#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");
|
2013-08-07 11:05:58 +10:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
fprintf(stderr, "Converts XML protocol descriptions supplied on "
|
|
|
|
|
"stdin to client headers,\n"
|
|
|
|
|
"server headers, or protocol marshalling code.\n");
|
2010-08-03 09:26:44 -04:00
|
|
|
exit(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define XML_BUFFER_SIZE 4096
|
|
|
|
|
|
2013-11-15 14:21:11 -08:00
|
|
|
struct location {
|
|
|
|
|
const char *filename;
|
|
|
|
|
int line_number;
|
|
|
|
|
};
|
|
|
|
|
|
2012-01-19 14:13:36 -08:00
|
|
|
struct description {
|
|
|
|
|
char *summary;
|
|
|
|
|
char *text;
|
|
|
|
|
};
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2012-01-19 14:13:36 -08:00
|
|
|
struct description *description;
|
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
|
|
|
};
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
struct interface {
|
2013-11-15 14:37:55 -08:00
|
|
|
struct location loc;
|
2010-08-03 09:26:44 -04:00
|
|
|
char *name;
|
|
|
|
|
char *uppercase_name;
|
|
|
|
|
int version;
|
2012-03-05 10:31:53 -05:00
|
|
|
int since;
|
2010-08-03 09:26:44 -04:00
|
|
|
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 {
|
2013-11-15 14:37:55 -08:00
|
|
|
struct location loc;
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2013-11-15 13:26:03 -08:00
|
|
|
int new_id_count;
|
2011-07-12 13:22:25 -04:00
|
|
|
int type_index;
|
|
|
|
|
int all_null;
|
2010-09-02 20:22:42 -04:00
|
|
|
int destructor;
|
2012-03-05 10:31:53 -05:00
|
|
|
int since;
|
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,
|
2012-05-08 17:17:25 +01:00
|
|
|
FIXED,
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2012-07-02 20:03:30 +10:00
|
|
|
int nullable;
|
2010-08-09 21:25:50 -04:00
|
|
|
char *interface_name;
|
2010-08-03 09:26:44 -04:00
|
|
|
struct wl_list link;
|
2012-01-19 14:13:36 -08:00
|
|
|
char *summary;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
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 {
|
2013-11-15 14:21:11 -08:00
|
|
|
struct location loc;
|
2011-04-13 16:50:02 -04:00
|
|
|
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];
|
2012-03-23 14:00:32 +02:00
|
|
|
unsigned int character_data_length;
|
2010-08-03 09:26:44 -04:00
|
|
|
};
|
|
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
static void *
|
|
|
|
|
fail_on_null(void *p)
|
|
|
|
|
{
|
|
|
|
|
if (p == NULL) {
|
|
|
|
|
fprintf(stderr, "wayland-scanner: out of memory\n");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
xmalloc(size_t s)
|
|
|
|
|
{
|
|
|
|
|
return fail_on_null(malloc(s));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
xstrdup(const char *s)
|
|
|
|
|
{
|
|
|
|
|
return fail_on_null(strdup(s));
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
static char *
|
|
|
|
|
uppercase_dup(const char *src)
|
|
|
|
|
{
|
|
|
|
|
char *u;
|
|
|
|
|
int i;
|
|
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
u = xstrdup(src);
|
2010-08-03 09:26:44 -04:00
|
|
|
for (i = 0; u[i]; i++)
|
|
|
|
|
u[i] = toupper(u[i]);
|
|
|
|
|
u[i] = '\0';
|
|
|
|
|
|
|
|
|
|
return u;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 22:23:05 -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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-15 00:49:13 +02:00
|
|
|
static void
|
|
|
|
|
desc_dump(char *desc, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
|
|
|
|
|
2012-01-19 14:13:36 -08:00
|
|
|
static void
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(char *desc, const char *fmt, ...)
|
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
|
|
|
{
|
2012-05-07 23:41:48 -04:00
|
|
|
va_list ap;
|
2012-10-15 00:49:11 +02:00
|
|
|
char buf[128], hang;
|
2012-10-21 22:24:33 -04:00
|
|
|
int col, i, j, k, startcol, newlines;
|
2012-05-07 23:41:48 -04:00
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
vsnprintf(buf, sizeof buf, fmt, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
for (i = 0, col = 0; buf[i] != '*'; i++) {
|
|
|
|
|
if (buf[i] == '\t')
|
|
|
|
|
col = (col + 8) & ~7;
|
|
|
|
|
else
|
|
|
|
|
col++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("%s", buf);
|
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
|
|
|
|
2012-05-07 23:41:48 -04:00
|
|
|
if (!desc) {
|
|
|
|
|
printf("(none)\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startcol = col;
|
|
|
|
|
col += strlen(&buf[i]);
|
|
|
|
|
if (col - startcol > 2)
|
|
|
|
|
hang = '\t';
|
|
|
|
|
else
|
|
|
|
|
hang = ' ';
|
|
|
|
|
|
|
|
|
|
for (i = 0; desc[i]; ) {
|
|
|
|
|
k = i;
|
2012-10-21 22:24:33 -04:00
|
|
|
newlines = 0;
|
|
|
|
|
while (desc[i] && isspace(desc[i])) {
|
|
|
|
|
if (desc[i] == '\n')
|
|
|
|
|
newlines++;
|
2012-05-07 23:41:48 -04:00
|
|
|
i++;
|
2012-10-21 22:24:33 -04:00
|
|
|
}
|
2012-05-07 23:41:48 -04:00
|
|
|
if (!desc[i])
|
|
|
|
|
break;
|
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
|
|
|
|
2012-05-07 22:43:56 -04:00
|
|
|
j = i;
|
2012-05-07 23:41:48 -04:00
|
|
|
while (desc[i] && !isspace(desc[i]))
|
2012-05-07 22:43:56 -04:00
|
|
|
i++;
|
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
|
|
|
|
2012-10-21 22:24:33 -04:00
|
|
|
if (newlines > 1)
|
|
|
|
|
printf("\n%s*", indent(startcol));
|
|
|
|
|
if (newlines > 1 || col + i - j > 72) {
|
2012-05-07 23:41:48 -04:00
|
|
|
printf("\n%s*%c", indent(startcol), hang);
|
2012-01-19 14:13:36 -08:00
|
|
|
col = startcol;
|
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
|
|
|
}
|
2012-05-07 22:43:56 -04:00
|
|
|
|
2012-05-07 23:41:48 -04:00
|
|
|
if (col > startcol && k > 0)
|
|
|
|
|
col += printf(" ");
|
|
|
|
|
col += printf("%.*s", i - j, &desc[j]);
|
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
|
|
|
}
|
2012-05-07 23:41:48 -04:00
|
|
|
putchar('\n');
|
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
|
|
|
}
|
|
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
static void
|
2013-11-15 14:29:40 -08:00
|
|
|
fail(struct location *loc, const char *msg, ...)
|
2011-04-13 16:50:02 -04:00
|
|
|
{
|
2013-11-15 14:29:40 -08:00
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
va_start(ap, msg);
|
|
|
|
|
fprintf(stderr, "%s:%d: error: ",
|
|
|
|
|
loc->filename, loc->line_number);
|
|
|
|
|
vfprintf(stderr, msg, ap);
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
va_end(ap);
|
2011-04-13 16:50:02 -04:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-15 14:37:55 -08:00
|
|
|
static void
|
|
|
|
|
warn(struct location *loc, const char *msg, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
va_start(ap, msg);
|
|
|
|
|
fprintf(stderr, "%s:%d: warning: ",
|
|
|
|
|
loc->filename, loc->line_number);
|
|
|
|
|
vfprintf(stderr, msg, ap);
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
va_end(ap);
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-02 20:03:30 +10:00
|
|
|
static int
|
|
|
|
|
is_nullable_type(struct arg *arg)
|
|
|
|
|
{
|
|
|
|
|
switch (arg->type) {
|
|
|
|
|
/* Strings, objects, and arrays are possibly nullable */
|
|
|
|
|
case STRING:
|
|
|
|
|
case OBJECT:
|
2012-07-23 19:54:41 +01:00
|
|
|
case NEW_ID:
|
2012-07-02 20:03:30 +10:00
|
|
|
case ARRAY:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2012-03-05 10:31:53 -05:00
|
|
|
const char *name, *type, *interface_name, *value, *summary, *since;
|
2012-07-02 20:03:30 +10:00
|
|
|
const char *allow_null;
|
2012-03-05 10:31:53 -05:00
|
|
|
char *end;
|
2010-08-03 09:26:44 -04:00
|
|
|
int i, version;
|
|
|
|
|
|
2013-11-15 14:21:11 -08:00
|
|
|
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
|
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;
|
2012-03-05 10:31:53 -05:00
|
|
|
since = NULL;
|
2012-07-02 20:03:30 +10:00
|
|
|
allow_null = 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];
|
2012-03-05 10:31:53 -05:00
|
|
|
if (strcmp(atts[i], "since") == 0)
|
|
|
|
|
since = atts[i + 1];
|
2012-07-02 20:03:30 +10:00
|
|
|
if (strcmp(atts[i], "allow-null") == 0)
|
|
|
|
|
allow_null = 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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no protocol name given");
|
2010-09-14 15:52:43 -04:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
ctx->protocol->name = xstrdup(name);
|
2010-09-14 15:52:43 -04:00
|
|
|
ctx->protocol->uppercase_name = uppercase_dup(name);
|
2012-01-19 14:13:36 -08:00
|
|
|
ctx->protocol->description = NULL;
|
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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no interface name given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2011-04-13 16:50:02 -04:00
|
|
|
if (version == 0)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no interface version given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
interface = xmalloc(sizeof *interface);
|
2013-11-15 14:37:55 -08:00
|
|
|
interface->loc = ctx->loc;
|
2013-07-13 00:35:21 -04:00
|
|
|
interface->name = xstrdup(name);
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2012-03-05 10:31:53 -05:00
|
|
|
interface->since = 1;
|
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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no request name given");
|
2010-08-03 09:26:44 -04:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
message = xmalloc(sizeof *message);
|
2013-11-15 14:37:55 -08:00
|
|
|
message->loc = ctx->loc;
|
2013-07-13 00:35:21 -04:00
|
|
|
message->name = xstrdup(name);
|
2010-08-03 09:26:44 -04:00
|
|
|
message->uppercase_name = uppercase_dup(name);
|
|
|
|
|
wl_list_init(&message->arg_list);
|
2011-07-12 13:22:25 -04:00
|
|
|
message->arg_count = 0;
|
2013-11-15 13:26:03 -08:00
|
|
|
message->new_id_count = 0;
|
2012-01-19 14:13:36 -08:00
|
|
|
message->description = NULL;
|
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;
|
|
|
|
|
|
2012-03-05 10:31:53 -05:00
|
|
|
if (since != NULL) {
|
2013-12-17 13:48:54 +02:00
|
|
|
errno = 0;
|
2012-03-05 10:31:53 -05:00
|
|
|
version = strtol(since, &end, 0);
|
|
|
|
|
if (errno == EINVAL || end == since || *end != '\0')
|
2013-11-15 14:29:40 -08:00
|
|
|
fail(&ctx->loc,
|
|
|
|
|
"invalid integer (%s)\n", since);
|
2014-05-08 23:39:47 +02:00
|
|
|
} else {
|
|
|
|
|
version = 1;
|
2012-03-05 10:31:53 -05:00
|
|
|
}
|
|
|
|
|
|
2014-05-08 23:39:47 +02:00
|
|
|
if (version < ctx->interface->since)
|
|
|
|
|
fail(&ctx->loc, "since version not increasing\n");
|
|
|
|
|
ctx->interface->since = version;
|
|
|
|
|
message->since = version;
|
2012-03-05 10:31:53 -05:00
|
|
|
|
2011-05-04 15:51:47 -04:00
|
|
|
if (strcmp(name, "destroy") == 0 && !message->destructor)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "destroy request should be destructor type");
|
2011-05-04 15:51:47 -04:00
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
ctx->message = message;
|
|
|
|
|
} else if (strcmp(element_name, "arg") == 0) {
|
2012-10-12 11:28:25 +02:00
|
|
|
if (name == NULL)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no argument name given");
|
2012-10-12 11:28:25 +02:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
arg = xmalloc(sizeof *arg);
|
|
|
|
|
arg->name = xstrdup(name);
|
2010-08-03 09:26:44 -04:00
|
|
|
|
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;
|
2012-05-08 17:17:25 +01:00
|
|
|
else if (strcmp(type, "fixed") == 0)
|
|
|
|
|
arg->type = FIXED;
|
2010-08-03 09:26:44 -04:00
|
|
|
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 {
|
2013-11-15 14:29:40 -08:00
|
|
|
fail(&ctx->loc, "unknown type (%s)", type);
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
2011-10-24 16:04:09 -04:00
|
|
|
switch (arg->type) {
|
|
|
|
|
case NEW_ID:
|
2013-11-15 13:26:03 -08:00
|
|
|
ctx->message->new_id_count++;
|
|
|
|
|
|
|
|
|
|
/* Fall through to OBJECT case. */
|
|
|
|
|
|
2011-10-24 16:04:09 -04:00
|
|
|
case OBJECT:
|
2012-10-08 13:21:55 -04:00
|
|
|
if (interface_name)
|
2013-07-13 00:35:21 -04:00
|
|
|
arg->interface_name = xstrdup(interface_name);
|
2012-10-20 11:38:57 -04:00
|
|
|
else
|
|
|
|
|
arg->interface_name = NULL;
|
2011-10-24 16:04:09 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (interface_name != NULL)
|
2013-11-15 14:29:40 -08:00
|
|
|
fail(&ctx->loc, "interface attribute not allowed for type %s", type);
|
2011-10-24 16:04:09 -04:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-02 20:03:30 +10:00
|
|
|
if (allow_null == NULL || strcmp(allow_null, "false") == 0)
|
|
|
|
|
arg->nullable = 0;
|
|
|
|
|
else if (strcmp(allow_null, "true") == 0)
|
|
|
|
|
arg->nullable = 1;
|
|
|
|
|
else
|
2013-11-15 14:29:40 -08:00
|
|
|
fail(&ctx->loc, "invalid value for allow-null attribute (%s)", allow_null);
|
2012-07-02 20:03:30 +10:00
|
|
|
|
|
|
|
|
if (allow_null != NULL && !is_nullable_type(arg))
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "allow-null is only valid for objects, strings, and arrays");
|
2012-07-02 20:03:30 +10:00
|
|
|
|
2012-01-19 14:13:36 -08:00
|
|
|
arg->summary = NULL;
|
|
|
|
|
if (summary)
|
2013-07-13 00:35:21 -04:00
|
|
|
arg->summary = xstrdup(summary);
|
2012-01-19 14:13:36 -08:00
|
|
|
|
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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no enum name given");
|
2011-01-21 21:57:55 -05:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
enumeration = xmalloc(sizeof *enumeration);
|
|
|
|
|
enumeration->name = xstrdup(name);
|
2011-01-21 21:57:55 -05:00
|
|
|
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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "no entry name given");
|
2011-10-31 11:21:38 -04:00
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
entry = xmalloc(sizeof *entry);
|
|
|
|
|
entry->name = xstrdup(name);
|
2011-01-21 21:57:55 -05:00
|
|
|
entry->uppercase_name = uppercase_dup(name);
|
2013-07-13 00:35:21 -04:00
|
|
|
entry->value = xstrdup(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)
|
2013-07-13 00:35:21 -04:00
|
|
|
entry->summary = xstrdup(summary);
|
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
|
|
|
|
|
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)
|
2013-11-15 14:21:11 -08:00
|
|
|
fail(&ctx->loc, "description without summary");
|
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
|
|
|
|
2013-07-13 00:35:21 -04:00
|
|
|
description = xmalloc(sizeof *description);
|
|
|
|
|
description->summary = xstrdup(summary);
|
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 (ctx->message)
|
|
|
|
|
ctx->message->description = description;
|
|
|
|
|
else if (ctx->enumeration)
|
|
|
|
|
ctx->enumeration->description = description;
|
|
|
|
|
else if (ctx->interface)
|
|
|
|
|
ctx->interface->description = description;
|
|
|
|
|
else
|
2012-01-19 14:13:36 -08:00
|
|
|
ctx->protocol->description = description;
|
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
|
|
|
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) {
|
2012-10-20 11:38:57 -04:00
|
|
|
ctx->description->text =
|
|
|
|
|
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
|
|
|
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;
|
2012-05-08 17:17:25 +01:00
|
|
|
case FIXED:
|
|
|
|
|
printf("wl_fixed_t ");
|
|
|
|
|
break;
|
2010-08-09 21:25:50 -04:00
|
|
|
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
|
|
|
|
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;
|
2013-02-25 16:01:38 -05:00
|
|
|
if (strcmp(m->name, "destroy") == 0)
|
2010-09-02 20:22:42 -04:00
|
|
|
has_destroy = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!has_destructor && has_destroy) {
|
2013-11-15 14:37:55 -08:00
|
|
|
fail(&interface->loc,
|
|
|
|
|
"interface '%s' has method named destroy "
|
|
|
|
|
"but no destructor",
|
|
|
|
|
interface->name);
|
2010-09-02 20:22:42 -04:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-13 20:06:30 +01:00
|
|
|
if (!has_destroy && strcmp(interface->name, "wl_display") != 0)
|
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) {
|
2013-11-15 13:26:03 -08:00
|
|
|
if (m->new_id_count > 1) {
|
2013-11-15 14:37:55 -08:00
|
|
|
warn(&m->loc,
|
|
|
|
|
"request '%s::%s' has more than "
|
|
|
|
|
"one new_id arg, not emitting stub\n",
|
|
|
|
|
interface->name, m->name);
|
2013-11-15 13:26:03 -08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-09 21:25:50 -04:00
|
|
|
ret = NULL;
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
|
|
|
|
if (a->type == NEW_ID)
|
|
|
|
|
ret = a;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-08 13:21:55 -04:00
|
|
|
if (ret && ret->interface_name == NULL)
|
|
|
|
|
printf("static inline void *\n");
|
|
|
|
|
else 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) {
|
2012-10-08 13:21:55 -04:00
|
|
|
if (a->type == NEW_ID && a->interface_name == NULL) {
|
|
|
|
|
printf(", const struct wl_interface *interface"
|
|
|
|
|
", uint32_t version");
|
|
|
|
|
continue;
|
|
|
|
|
} else if (a->type == NEW_ID)
|
2010-08-09 21:25:50 -04:00
|
|
|
continue;
|
|
|
|
|
printf(", ");
|
|
|
|
|
emit_type(a);
|
|
|
|
|
printf("%s", a->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(")\n"
|
|
|
|
|
"{\n");
|
2012-10-08 13:21:55 -04:00
|
|
|
if (ret) {
|
2010-08-09 21:25:50 -04:00
|
|
|
printf("\tstruct wl_proxy *%s;\n\n"
|
client: Introduce functions to allocate and marshal proxies atomically
The server requires clients to only allocate one ID ahead of the previously
highest ID in order to keep the ID range tight. Failure to do so will
make the server close the client connection. However, the way we allocate
new IDs is racy. The generated code looks like:
new_proxy = wl_proxy_create(...);
wl_proxy_marshal(proxy, ... new_proxy, ...);
If two threads do this at the same time, there's a chance that thread A
will allocate a proxy, then get pre-empted by thread B which then allocates
a proxy and then passes it to wl_proxy_marshal(). The ID for thread As
proxy will be one higher that the currently highest ID, but the ID for
thread Bs proxy will be two higher. But since thread B prempted thread A
before it could send its new ID, B will send its new ID first, the server
will see the ID from thread Bs proxy first, and will reject it.
We fix this by introducing wl_proxy_marshal_constructor(). This
function is identical to wl_proxy_marshal(), except that it will
allocate a wl_proxy for NEW_ID arguments and send it, all under the
display mutex. By introducing a new function, we maintain backwards
compatibility with older code from the generator, and make sure that
the new generated code has an explicit dependency on a new enough
libwayland-client.so.
A virtual Wayland merit badge goes to Kalle Vahlman, who tracked this
down and analyzed the issue.
Reported-by: Kalle Vahlman <kalle.vahlman@movial.com>
2013-11-14 21:29:06 -08:00
|
|
|
"\t%s = wl_proxy_marshal_constructor("
|
|
|
|
|
"(struct wl_proxy *) %s,\n"
|
|
|
|
|
"\t\t\t %s_%s, ",
|
|
|
|
|
ret->name, ret->name,
|
|
|
|
|
interface->name,
|
|
|
|
|
interface->uppercase_name,
|
|
|
|
|
m->uppercase_name);
|
|
|
|
|
|
2012-10-08 13:21:55 -04:00
|
|
|
if (ret->interface_name == NULL)
|
client: Introduce functions to allocate and marshal proxies atomically
The server requires clients to only allocate one ID ahead of the previously
highest ID in order to keep the ID range tight. Failure to do so will
make the server close the client connection. However, the way we allocate
new IDs is racy. The generated code looks like:
new_proxy = wl_proxy_create(...);
wl_proxy_marshal(proxy, ... new_proxy, ...);
If two threads do this at the same time, there's a chance that thread A
will allocate a proxy, then get pre-empted by thread B which then allocates
a proxy and then passes it to wl_proxy_marshal(). The ID for thread As
proxy will be one higher that the currently highest ID, but the ID for
thread Bs proxy will be two higher. But since thread B prempted thread A
before it could send its new ID, B will send its new ID first, the server
will see the ID from thread Bs proxy first, and will reject it.
We fix this by introducing wl_proxy_marshal_constructor(). This
function is identical to wl_proxy_marshal(), except that it will
allocate a wl_proxy for NEW_ID arguments and send it, all under the
display mutex. By introducing a new function, we maintain backwards
compatibility with older code from the generator, and make sure that
the new generated code has an explicit dependency on a new enough
libwayland-client.so.
A virtual Wayland merit badge goes to Kalle Vahlman, who tracked this
down and analyzed the issue.
Reported-by: Kalle Vahlman <kalle.vahlman@movial.com>
2013-11-14 21:29:06 -08:00
|
|
|
printf("interface");
|
2012-10-08 13:21:55 -04:00
|
|
|
else
|
client: Introduce functions to allocate and marshal proxies atomically
The server requires clients to only allocate one ID ahead of the previously
highest ID in order to keep the ID range tight. Failure to do so will
make the server close the client connection. However, the way we allocate
new IDs is racy. The generated code looks like:
new_proxy = wl_proxy_create(...);
wl_proxy_marshal(proxy, ... new_proxy, ...);
If two threads do this at the same time, there's a chance that thread A
will allocate a proxy, then get pre-empted by thread B which then allocates
a proxy and then passes it to wl_proxy_marshal(). The ID for thread As
proxy will be one higher that the currently highest ID, but the ID for
thread Bs proxy will be two higher. But since thread B prempted thread A
before it could send its new ID, B will send its new ID first, the server
will see the ID from thread Bs proxy first, and will reject it.
We fix this by introducing wl_proxy_marshal_constructor(). This
function is identical to wl_proxy_marshal(), except that it will
allocate a wl_proxy for NEW_ID arguments and send it, all under the
display mutex. By introducing a new function, we maintain backwards
compatibility with older code from the generator, and make sure that
the new generated code has an explicit dependency on a new enough
libwayland-client.so.
A virtual Wayland merit badge goes to Kalle Vahlman, who tracked this
down and analyzed the issue.
Reported-by: Kalle Vahlman <kalle.vahlman@movial.com>
2013-11-14 21:29:06 -08:00
|
|
|
printf("&%s_interface", ret->interface_name);
|
|
|
|
|
} else {
|
|
|
|
|
printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
|
|
|
|
|
"\t\t\t %s_%s",
|
|
|
|
|
interface->name,
|
|
|
|
|
interface->uppercase_name,
|
|
|
|
|
m->uppercase_name);
|
2012-10-08 13:21:55 -04:00
|
|
|
}
|
2010-08-09 21:25:50 -04:00
|
|
|
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
client: Introduce functions to allocate and marshal proxies atomically
The server requires clients to only allocate one ID ahead of the previously
highest ID in order to keep the ID range tight. Failure to do so will
make the server close the client connection. However, the way we allocate
new IDs is racy. The generated code looks like:
new_proxy = wl_proxy_create(...);
wl_proxy_marshal(proxy, ... new_proxy, ...);
If two threads do this at the same time, there's a chance that thread A
will allocate a proxy, then get pre-empted by thread B which then allocates
a proxy and then passes it to wl_proxy_marshal(). The ID for thread As
proxy will be one higher that the currently highest ID, but the ID for
thread Bs proxy will be two higher. But since thread B prempted thread A
before it could send its new ID, B will send its new ID first, the server
will see the ID from thread Bs proxy first, and will reject it.
We fix this by introducing wl_proxy_marshal_constructor(). This
function is identical to wl_proxy_marshal(), except that it will
allocate a wl_proxy for NEW_ID arguments and send it, all under the
display mutex. By introducing a new function, we maintain backwards
compatibility with older code from the generator, and make sure that
the new generated code has an explicit dependency on a new enough
libwayland-client.so.
A virtual Wayland merit badge goes to Kalle Vahlman, who tracked this
down and analyzed the issue.
Reported-by: Kalle Vahlman <kalle.vahlman@movial.com>
2013-11-14 21:29:06 -08:00
|
|
|
if (a->type == NEW_ID) {
|
|
|
|
|
if (a->interface_name == NULL)
|
|
|
|
|
printf(", interface->name, version");
|
|
|
|
|
printf(", NULL");
|
|
|
|
|
} else {
|
|
|
|
|
printf(", %s", a->name);
|
|
|
|
|
}
|
2010-08-09 21:25:50 -04:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
2012-10-08 13:21:55 -04:00
|
|
|
if (ret && ret->interface_name == NULL)
|
|
|
|
|
printf("\n\treturn (void *) %s;\n", ret->name);
|
|
|
|
|
else 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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-02 15:16:33 +02:00
|
|
|
static void
|
|
|
|
|
emit_event_wrappers(struct wl_list *message_list, struct interface *interface)
|
|
|
|
|
{
|
|
|
|
|
struct message *m;
|
|
|
|
|
struct arg *a;
|
|
|
|
|
|
|
|
|
|
/* We provide hand written functions for the display object */
|
|
|
|
|
if (strcmp(interface->name, "wl_display") == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(m, message_list, link) {
|
|
|
|
|
printf("static inline void\n"
|
|
|
|
|
"%s_send_%s(struct wl_resource *resource_",
|
|
|
|
|
interface->name, m->name);
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
|
|
|
|
printf(", ");
|
|
|
|
|
switch (a->type) {
|
|
|
|
|
case NEW_ID:
|
|
|
|
|
case OBJECT:
|
|
|
|
|
printf("struct wl_resource *");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
emit_type(a);
|
|
|
|
|
}
|
|
|
|
|
printf("%s", a->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(")\n"
|
|
|
|
|
"{\n"
|
|
|
|
|
"\twl_resource_post_event(resource_, %s_%s",
|
|
|
|
|
interface->uppercase_name, m->uppercase_name);
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(a, &m->arg_list, link)
|
|
|
|
|
printf(", %s", a->name);
|
|
|
|
|
|
|
|
|
|
printf(");\n");
|
|
|
|
|
printf("}\n\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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) {
|
2012-05-07 23:41:48 -04:00
|
|
|
printf("/**\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(desc->summary,
|
|
|
|
|
" * %s_%s - ",
|
|
|
|
|
interface->name, e->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
|
|
|
wl_list_for_each(entry, &e->entry_list, link) {
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(entry->summary,
|
|
|
|
|
" * @%s_%s_%s: ",
|
2012-05-07 23:41:48 -04:00
|
|
|
interface->uppercase_name,
|
|
|
|
|
e->uppercase_name,
|
2012-10-15 00:49:11 +02:00
|
|
|
entry->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->text) {
|
2012-05-07 23:41:48 -04:00
|
|
|
printf(" *\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(desc->text, " * ");
|
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
|
|
|
}
|
|
|
|
|
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;
|
2012-05-07 23:41:48 -04:00
|
|
|
printf("/**\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(desc->summary, " * %s - ", interface->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
|
|
|
wl_list_for_each(m, message_list, link) {
|
|
|
|
|
struct description *mdesc = m->description;
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(mdesc ? mdesc->summary : "(none)",
|
|
|
|
|
" * @%s: ",
|
|
|
|
|
m->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
|
|
|
}
|
2012-05-07 23:41:48 -04:00
|
|
|
printf(" *\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(desc->text, " * ");
|
2012-01-19 14:13:36 -08:00
|
|
|
printf(" */\n");
|
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
|
|
|
}
|
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) {
|
2012-01-19 14:13:36 -08:00
|
|
|
struct description *mdesc = m->description;
|
|
|
|
|
|
|
|
|
|
printf("\t/**\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(mdesc ? mdesc->summary : "(none)",
|
|
|
|
|
"\t * %s - ", m->name);
|
2012-01-19 14:13:36 -08:00
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
2012-10-08 13:21:55 -04:00
|
|
|
|
|
|
|
|
if (is_interface && a->type == NEW_ID &&
|
|
|
|
|
a->interface_name == NULL)
|
|
|
|
|
printf("\t * @interface: name of the objects interface\n"
|
|
|
|
|
"\t * @version: version of the objects interface\n");
|
|
|
|
|
|
|
|
|
|
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(a->summary ? a->summary : "(none)",
|
|
|
|
|
"\t * @%s: ", a->name);
|
2012-01-19 14:13:36 -08:00
|
|
|
}
|
|
|
|
|
if (mdesc) {
|
2012-05-07 23:41:48 -04:00
|
|
|
printf("\t *\n");
|
2012-10-15 00:49:11 +02:00
|
|
|
desc_dump(mdesc->text, "\t * ");
|
2012-01-19 14:13:36 -08:00
|
|
|
}
|
2012-03-05 10:31:53 -05:00
|
|
|
if (m->since > 1) {
|
|
|
|
|
printf("\t * @since: %d\n", m->since);
|
|
|
|
|
}
|
2012-01-24 18:30:13 +02:00
|
|
|
printf("\t */\n");
|
2010-08-03 09:26:44 -04:00
|
|
|
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 *");
|
2012-10-08 13:21:55 -04:00
|
|
|
else if (is_interface && a->type == NEW_ID && a->interface_name == NULL)
|
|
|
|
|
printf("const char *interface, uint32_t version, uint32_t ");
|
|
|
|
|
else if (!is_interface && a->type == OBJECT && a->interface_name == NULL)
|
2013-06-27 20:09:18 -05:00
|
|
|
printf("void *");
|
2012-10-08 13:21:55 -04:00
|
|
|
|
2012-06-28 22:01:58 -04:00
|
|
|
else if (!is_interface && a->type == NEW_ID)
|
|
|
|
|
printf("struct %s *", a->interface_name);
|
2011-08-27 12:05:09 -04:00
|
|
|
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"
|
2012-07-05 16:31:29 +12:00
|
|
|
"#include \"%s\"\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,
|
2012-07-05 16:31:29 +12:00
|
|
|
protocol->uppercase_name, s,
|
|
|
|
|
server ? "wayland-util.h" : "wayland-client.h");
|
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);
|
2012-03-02 15:16:33 +02:00
|
|
|
emit_event_wrappers(&i->event_list, i);
|
2010-08-03 09:26:44 -04:00
|
|
|
} 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,
|
2014-04-03 15:57:54 -07:00
|
|
|
struct wl_list *message_list,
|
|
|
|
|
struct wl_array *types)
|
2011-07-12 13:22:25 -04:00
|
|
|
{
|
|
|
|
|
struct message *m;
|
|
|
|
|
struct arg *a;
|
|
|
|
|
int length;
|
2014-04-03 15:57:54 -07:00
|
|
|
char **p;
|
2011-07-12 13:22:25 -04:00
|
|
|
|
|
|
|
|
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:
|
2012-10-08 13:21:55 -04:00
|
|
|
if (!a->interface_name)
|
|
|
|
|
continue;
|
|
|
|
|
|
2011-07-12 13:22:25 -04:00
|
|
|
m->all_null = 0;
|
2014-05-05 14:45:19 -07:00
|
|
|
p = fail_on_null(wl_array_add(types, sizeof *p));
|
2014-04-03 15:57:54 -07:00
|
|
|
*p = a->interface_name;
|
2011-07-12 13:22:25 -04:00
|
|
|
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:
|
2012-10-08 13:21:55 -04:00
|
|
|
if (a->interface_name)
|
2011-07-12 13:22:25 -04:00
|
|
|
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);
|
2013-06-27 20:09:19 -05:00
|
|
|
|
|
|
|
|
if (m->since > 1)
|
|
|
|
|
printf("%d", m->since);
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
wl_list_for_each(a, &m->arg_list, link) {
|
2012-07-02 20:03:30 +10:00
|
|
|
if (is_nullable_type(a) && a->nullable)
|
|
|
|
|
printf("?");
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
switch (a->type) {
|
|
|
|
|
default:
|
|
|
|
|
case INT:
|
|
|
|
|
printf("i");
|
|
|
|
|
break;
|
|
|
|
|
case NEW_ID:
|
2012-10-08 13:21:55 -04:00
|
|
|
if (a->interface_name == NULL)
|
|
|
|
|
printf("su");
|
2010-08-03 09:26:44 -04:00
|
|
|
printf("n");
|
|
|
|
|
break;
|
|
|
|
|
case UNSIGNED:
|
|
|
|
|
printf("u");
|
|
|
|
|
break;
|
2012-05-08 17:17:25 +01:00
|
|
|
case FIXED:
|
|
|
|
|
printf("f");
|
|
|
|
|
break;
|
2010-08-03 09:26:44 -04:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-03 15:57:54 -07:00
|
|
|
static int
|
|
|
|
|
cmp_names(const void *p1, const void *p2)
|
|
|
|
|
{
|
|
|
|
|
const char * const *s1 = p1, * const *s2 = p2;
|
|
|
|
|
|
|
|
|
|
return strcmp(*s1, *s2);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-03 09:26:44 -04:00
|
|
|
static void
|
|
|
|
|
emit_code(struct protocol *protocol)
|
|
|
|
|
{
|
|
|
|
|
struct interface *i;
|
2014-04-03 15:57:54 -07:00
|
|
|
struct wl_array types;
|
|
|
|
|
char **p, *prev;
|
2010-08-03 09:26:44 -04:00
|
|
|
|
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
|
|
|
|
2014-04-03 15:57:54 -07:00
|
|
|
wl_array_init(&types);
|
2011-07-12 13:22:25 -04:00
|
|
|
wl_list_for_each(i, &protocol->interface_list, link) {
|
2014-04-03 15:57:54 -07:00
|
|
|
emit_types_forward_declarations(protocol, &i->request_list, &types);
|
|
|
|
|
emit_types_forward_declarations(protocol, &i->event_list, &types);
|
|
|
|
|
}
|
|
|
|
|
qsort(types.data, types.size / sizeof *p, sizeof *p, cmp_names);
|
|
|
|
|
prev = NULL;
|
|
|
|
|
wl_array_for_each(p, &types) {
|
|
|
|
|
if (prev && strcmp(*p, prev) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
printf("extern const struct wl_interface %s_interface;\n", *p);
|
|
|
|
|
prev = *p;
|
2011-07-12 13:22:25 -04:00
|
|
|
}
|
2014-04-03 15:57:54 -07:00
|
|
|
wl_array_release(&types);
|
|
|
|
|
printf("\n");
|
2011-07-12 13:22:25 -04:00
|
|
|
|
|
|
|
|
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))
|
2012-10-19 17:08:38 -04:00
|
|
|
printf("\t%d, %s_requests,\n",
|
2013-02-25 17:12:51 +02:00
|
|
|
wl_list_length(&i->request_list), i->name);
|
2010-08-03 09:26:44 -04:00
|
|
|
else
|
|
|
|
|
printf("\t0, NULL,\n");
|
|
|
|
|
|
|
|
|
|
if (!wl_list_empty(&i->event_list))
|
2012-10-19 17:08:38 -04:00
|
|
|
printf("\t%d, %s_events,\n",
|
2013-02-25 17:12:51 +02:00
|
|
|
wl_list_length(&i->event_list), i->name);
|
2010-08-03 09:26:44 -04:00
|
|
|
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;
|
2013-08-07 11:05:57 +10:00
|
|
|
enum {
|
|
|
|
|
CLIENT_HEADER,
|
|
|
|
|
SERVER_HEADER,
|
|
|
|
|
CODE,
|
|
|
|
|
} mode;
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
if (argc != 2)
|
|
|
|
|
usage(EXIT_FAILURE);
|
2013-08-07 11:05:57 +10:00
|
|
|
else if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0)
|
|
|
|
|
usage(EXIT_SUCCESS);
|
|
|
|
|
else if (strcmp(argv[1], "client-header") == 0)
|
|
|
|
|
mode = CLIENT_HEADER;
|
|
|
|
|
else if (strcmp(argv[1], "server-header") == 0)
|
|
|
|
|
mode = SERVER_HEADER;
|
|
|
|
|
else if (strcmp(argv[1], "code") == 0)
|
|
|
|
|
mode = CODE;
|
2013-10-07 21:36:31 -07:00
|
|
|
else
|
|
|
|
|
usage(EXIT_FAILURE);
|
2010-08-03 09:26:44 -04:00
|
|
|
|
|
|
|
|
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;
|
2012-10-20 11:38:57 -04:00
|
|
|
memset(&ctx, 0, sizeof ctx);
|
2010-08-03 09:26:44 -04:00
|
|
|
ctx.protocol = &protocol;
|
|
|
|
|
|
2013-11-15 14:21:11 -08:00
|
|
|
ctx.loc.filename = "<stdin>";
|
2011-04-13 16:50:02 -04:00
|
|
|
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) {
|
2012-06-15 22:01:06 +00:00
|
|
|
fprintf(stderr, "fread: %m\n");
|
2010-08-03 09:26:44 -04:00
|
|
|
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
|
|
|
|
2013-10-07 21:36:31 -07:00
|
|
|
switch (mode) {
|
2013-08-07 11:05:57 +10:00
|
|
|
case CLIENT_HEADER:
|
|
|
|
|
emit_header(&protocol, 0);
|
|
|
|
|
break;
|
|
|
|
|
case SERVER_HEADER:
|
|
|
|
|
emit_header(&protocol, 1);
|
|
|
|
|
break;
|
|
|
|
|
case CODE:
|
|
|
|
|
emit_code(&protocol);
|
|
|
|
|
break;
|
2010-08-03 09:26:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|