summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAuke Booij <auke@tulcod.com>2015-12-05 12:39:12 +0000
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-05-03 14:54:11 +0300
commit7ccf35d43209ca4c4283cd3a3746f8126d4c64c1 (patch)
tree209918b24f6914192825b54e5620b690f3c3eb4d
parente21aeb5d1290de0ab67995bbd6341ef399a1f399 (diff)
downloadwayland-7ccf35d43209ca4c4283cd3a3746f8126d4c64c1.tar.gz
protocol: add support for cross-interface enum attributes
The enum attribute, for which scanner support was introduced in 1771299, can be used to link message arguments to <enum>s. However, some arguments refer to <enum>s in a different <interface>. This adds scanner support for referring to an <enum> in a different <interface> using dot notation. It also sets the attributes in this style in the wayland XML protocol (wl_shm_pool::create_buffer::format to wl_shm::format, and wl_surface::set_buffer_transform::transform to wl_output::transform), and updates the documentation XSL so that this new style is supported. Changes since v2: - add object:: prefix for all enumerations in the documentation - fix whitespace in scanner.c - minor code fixup to return early and avoid casts in scanner.c Changes since v1: - several implementation bugs fixed Signed-off-by: Auke Booij <auke@tulcod.com> Reviewed-by: Nils Christopher Brause <nilschrbrause@googlemail.com> Reviewed-by: Bill Spitzak <spitzak@gmail.com> [Pekka: rebased across cde251a124d41977b447098cc530fcad2834a45f] [Pekka: wrap lines and space fixes in scanner.c] Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r--doc/publican/protocol-to-docbook.xsl19
-rw-r--r--protocol/wayland.xml4
-rw-r--r--src/scanner.c69
3 files changed, 71 insertions, 21 deletions
diff --git a/doc/publican/protocol-to-docbook.xsl b/doc/publican/protocol-to-docbook.xsl
index 5344442..210e0db 100644
--- a/doc/publican/protocol-to-docbook.xsl
+++ b/doc/publican/protocol-to-docbook.xsl
@@ -152,9 +152,22 @@
<term><xsl:value-of select="@name"/></term>
<listitem>
<simpara>
- <link linkend="protocol-spec-{../../@name}-enum-{@enum}">
- <xsl:value-of select="../../@name"/>::<xsl:value-of select="@enum"/>
- </link>
+ <xsl:choose>
+ <xsl:when test="contains(@enum, '.')">
+ <link linkend="protocol-spec-{substring-before(@enum, '.')}-enum-{substring-after(@enum, '.')}">
+ <xsl:value-of select="substring-before(@enum, '.')"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="substring-after(@enum, '.')"/>
+ </link>
+ </xsl:when>
+ <xsl:otherwise>
+ <link linkend="protocol-spec-{../../@name}-enum-{@enum}">
+ <xsl:value-of select="../../@name"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="@enum"/>
+ </link>
+ </xsl:otherwise>
+ </xsl:choose>
(<xsl:value-of select="@type"/>)
<xsl:if test="@summary" >
- <xsl:value-of select="@summary"/>
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 1555677..92e3f43 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -229,7 +229,7 @@
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="int"/>
- <arg name="format" type="uint"/>
+ <arg name="format" type="uint" enum="wl_shm.format"/>
</request>
<request name="destroy" type="destructor">
@@ -1580,7 +1580,7 @@
wl_output.transform enum the invalid_transform protocol error
is raised.
</description>
- <arg name="transform" type="int"/>
+ <arg name="transform" type="int" enum="wl_output.transform"/>
</request>
<!-- Version 3 additions -->
diff --git a/src/scanner.c b/src/scanner.c
index 52c07a6..1317a06 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -752,8 +752,8 @@ start_element(void *data, const char *element_name, const char **atts)
enumeration->bitfield = true;
else
fail(&ctx->loc,
- "invalid value (%s) for bitfield attribute (only true/false are accepted)",
- bitfield);
+ "invalid value (%s) for bitfield attribute (only true/false are accepted)",
+ bitfield);
wl_list_insert(ctx->interface->enumeration_list.prev,
&enumeration->link);
@@ -790,32 +790,68 @@ start_element(void *data, const char *element_name, const char **atts)
}
}
+static struct enumeration *
+find_enumeration(struct protocol *protocol,
+ struct interface *interface,
+ char *enum_attribute)
+{
+ struct interface *i;
+ struct enumeration *e;
+ char *enum_name;
+ uint idx = 0, j;
+
+ for (j = 0; j + 1 < strlen(enum_attribute); j++) {
+ if (enum_attribute[j] == '.') {
+ idx = j;
+ }
+ }
+
+ if (idx > 0) {
+ enum_name = enum_attribute + idx + 1;
+
+ wl_list_for_each(i, &protocol->interface_list, link)
+ if (strncmp(i->name, enum_attribute, idx) == 0)
+ wl_list_for_each(e, &i->enumeration_list, link)
+ if (strcmp(e->name, enum_name) == 0)
+ return e;
+ } else if (interface) {
+ enum_name = enum_attribute;
+
+ wl_list_for_each(e, &interface->enumeration_list, link)
+ if (strcmp(e->name, enum_name) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
static void
-verify_arguments(struct parse_context *ctx, struct wl_list *messages, struct wl_list *enumerations)
+verify_arguments(struct parse_context *ctx,
+ struct interface *interface,
+ struct wl_list *messages,
+ struct wl_list *enumerations)
{
struct message *m;
wl_list_for_each(m, messages, link) {
struct arg *a;
wl_list_for_each(a, &m->arg_list, link) {
- struct enumeration *e, *f;
+ struct enumeration *e;
if (!a->enumeration_name)
continue;
- f = NULL;
- wl_list_for_each(e, enumerations, link) {
- if(strcmp(e->name, a->enumeration_name) == 0)
- f = e;
- }
- if (f == NULL)
+ e = find_enumeration(ctx->protocol, interface,
+ a->enumeration_name);
+
+ if (e == NULL)
fail(&ctx->loc,
"could not find enumeration %s",
a->enumeration_name);
switch (a->type) {
case INT:
- if (f->bitfield)
+ if (e->bitfield)
fail(&ctx->loc,
"bitfield-style enum must only be referenced by uint");
break;
@@ -853,12 +889,13 @@ end_element(void *data, const XML_Char *name)
ctx->enumeration->name);
}
ctx->enumeration = NULL;
- } else if (strcmp(name, "interface") == 0) {
- struct interface *i = ctx->interface;
-
- verify_arguments(ctx, &i->request_list, &i->enumeration_list);
- verify_arguments(ctx, &i->event_list, &i->enumeration_list);
+ } else if (strcmp(name, "protocol") == 0) {
+ struct interface *i;
+ wl_list_for_each(i, &ctx->protocol->interface_list, link) {
+ verify_arguments(ctx, i, &i->request_list, &i->enumeration_list);
+ verify_arguments(ctx, i, &i->event_list, &i->enumeration_list);
+ }
}
}