diff options
author | Auke Booij <auke@tulcod.com> | 2015-12-05 12:39:12 +0000 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2016-05-03 14:54:11 +0300 |
commit | 7ccf35d43209ca4c4283cd3a3746f8126d4c64c1 (patch) | |
tree | 209918b24f6914192825b54e5620b690f3c3eb4d | |
parent | e21aeb5d1290de0ab67995bbd6341ef399a1f399 (diff) | |
download | wayland-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.xsl | 19 | ||||
-rw-r--r-- | protocol/wayland.xml | 4 | ||||
-rw-r--r-- | src/scanner.c | 69 |
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); + } } } |