<div dir="ltr"><div>I believe this is correct and worth using.<br><br></div>The only difference with mine is that the protocol-to-docbook.xsl puts the enum arg handling into it's own top-level clause, rather than as an if statement. This I think makes it more consistent with the other argument special-cases (one for object ids, and another for new ids). I'm not sure if this is really important, and also I think I could submit it as an extra patch after this.<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 14, 2015 at 4:48 AM, Auke Booij <span dir="ltr"><<a href="mailto:auke@tulcod.com" target="_blank">auke@tulcod.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Bill, any chance you could review this? Or would you prefer it if this<br>
were based on your patch (which I do still support)?<br>
<br>
On 5 December 2015 at 13:39, Auke Booij <<a href="mailto:auke@tulcod.com">auke@tulcod.com</a>> wrote:<br>
> The enum attribute, for which scanner support was introduced in<br>
> 1771299, can be used to link message arguments to <enum>s. However,<br>
> some arguments refer to <enum>s in a different <interface>.<br>
><br>
> This adds scanner support for referring to an <enum> in a different<br>
> <interface> using dot notation. It also sets the attributes in this<br>
> style in the wayland XML protocol (wl_shm_pool::create_buffer::format<br>
> to wl_shm::format, and wl_surface::set_buffer_transform::transform to<br>
> wl_output::transform), and updates the documentation XSL so that this<br>
> new style is supported.<br>
><br>
> Changes since v2:<br>
> - add object:: prefix for all enumerations in the documentation<br>
> - fix whitespace in scanner.c<br>
> - minor code fixup to return early and avoid casts in scanner.c<br>
><br>
> Changes since v1:<br>
> - several implementation bugs fixed<br>
><br>
> Signed-off-by: Auke Booij <<a href="mailto:auke@tulcod.com">auke@tulcod.com</a>><br>
> ---<br>
> doc/publican/protocol-to-docbook.xsl | 19 +++++++++--<br>
> protocol/wayland.xml | 4 +--<br>
> src/scanner.c | 63 +++++++++++++++++++++++++++---------<br>
> 3 files changed, 65 insertions(+), 21 deletions(-)<br>
><br>
> diff --git a/doc/publican/protocol-to-docbook.xsl b/doc/publican/protocol-to-docbook.xsl<br>
> index fad207a..7e892c3 100644<br>
> --- a/doc/publican/protocol-to-docbook.xsl<br>
> +++ b/doc/publican/protocol-to-docbook.xsl<br>
> @@ -103,9 +103,22 @@<br>
> <listitem><br>
> <simpara><br>
> <xsl:if test="@enum"><br>
> - <link linkend="protocol-spec-{../../@name}-enum-{@enum}"><br>
> - <xsl:value-of select="@enum"/><br>
> - </link><br>
> + <xsl:choose><br>
> + <xsl:when test="contains(@enum, '.')"><br>
> + <link linkend="protocol-spec-{substring-before(@enum, '.')}-enum-{substring-after(@enum, '.')}"><br>
> + <xsl:value-of select="substring-before(@enum, '.')"/><br>
> + <xsl:text>::</xsl:text><br>
> + <xsl:value-of select="substring-after(@enum, '.')"/><br>
> + </link><br>
> + </xsl:when><br>
> + <xsl:otherwise><br>
> + <link linkend="protocol-spec-{../../@name}-enum-{@enum}"><br>
> + <xsl:value-of select="../../@name"/><br>
> + <xsl:text>::</xsl:text><br>
> + <xsl:value-of select="@enum"/><br>
> + </link><br>
> + </xsl:otherwise><br>
> + </xsl:choose><br>
> <xsl:text> </xsl:text><br>
> </xsl:if><br>
> <xsl:value-of select="@type"/><br>
> diff --git a/protocol/wayland.xml b/protocol/wayland.xml<br>
> index f9e6d76..0873553 100644<br>
> --- a/protocol/wayland.xml<br>
> +++ b/protocol/wayland.xml<br>
> @@ -229,7 +229,7 @@<br>
> <arg name="width" type="int"/><br>
> <arg name="height" type="int"/><br>
> <arg name="stride" type="int"/><br>
> - <arg name="format" type="uint"/><br>
> + <arg name="format" type="uint" enum="wl_shm.format"/><br>
> </request><br>
><br>
> <request name="destroy" type="destructor"><br>
> @@ -1292,7 +1292,7 @@<br>
> wl_output.transform enum the invalid_transform protocol error<br>
> is raised.<br>
> </description><br>
> - <arg name="transform" type="int"/><br>
> + <arg name="transform" type="int" enum="wl_output.transform"/><br>
> </request><br>
><br>
> <!-- Version 3 additions --><br>
> diff --git a/src/scanner.c b/src/scanner.c<br>
> index 406519f..85aeea7 100644<br>
> --- a/src/scanner.c<br>
> +++ b/src/scanner.c<br>
> @@ -747,8 +747,8 @@ start_element(void *data, const char *element_name, const char **atts)<br>
> enumeration->bitfield = true;<br>
> else<br>
> fail(&ctx->loc,<br>
> - "invalid value (%s) for bitfield attribute (only true/false are accepted)",<br>
> - bitfield);<br>
> + "invalid value (%s) for bitfield attribute (only true/false are accepted)",<br>
> + bitfield);<br>
><br>
> wl_list_insert(ctx->interface->enumeration_list.prev,<br>
> &enumeration->link);<br>
> @@ -785,32 +785,62 @@ start_element(void *data, const char *element_name, const char **atts)<br>
> }<br>
> }<br>
><br>
> +static struct enumeration *<br>
> +find_enumeration(struct protocol *protocol, struct interface *interface, char *enum_attribute)<br>
> +{<br>
> + struct interface *i;<br>
> + struct enumeration *e;<br>
> + char *enum_name;<br>
> + uint idx = 0, j;<br>
> +<br>
> + for (j = 0; j + 1 < strlen(enum_attribute); j++) {<br>
> + if (enum_attribute[j] == '.') {<br>
> + idx = j;<br>
> + }<br>
> + }<br>
> +<br>
> + if (idx > 0) {<br>
> + enum_name = enum_attribute + idx + 1;<br>
> +<br>
> + wl_list_for_each(i, &protocol->interface_list, link)<br>
> + if (strncmp(i->name, enum_attribute, idx) == 0)<br>
> + wl_list_for_each(e, &i->enumeration_list, link)<br>
> + if(strcmp(e->name, enum_name) == 0)<br>
> + return e;<br>
> + } else if (interface) {<br>
> + enum_name = enum_attribute;<br>
> +<br>
> + wl_list_for_each(e, &interface->enumeration_list, link)<br>
> + if(strcmp(e->name, enum_name) == 0)<br>
> + return e;<br>
> + }<br>
> +<br>
> + return NULL;<br>
> +}<br>
> +<br>
> static void<br>
> -verify_arguments(struct parse_context *ctx, struct wl_list *messages, struct wl_list *enumerations)<br>
> +verify_arguments(struct parse_context *ctx, struct interface *interface, struct wl_list *messages, struct wl_list *enumerations)<br>
> {<br>
> struct message *m;<br>
> wl_list_for_each(m, messages, link) {<br>
> struct arg *a;<br>
> wl_list_for_each(a, &m->arg_list, link) {<br>
> - struct enumeration *e, *f;<br>
> + struct enumeration *e;<br>
><br>
> if (!a->enumeration_name)<br>
> continue;<br>
><br>
> - f = NULL;<br>
> - wl_list_for_each(e, enumerations, link) {<br>
> - if(strcmp(e->name, a->enumeration_name) == 0)<br>
> - f = e;<br>
> - }<br>
><br>
> - if (f == NULL)<br>
> + e = find_enumeration(ctx->protocol, interface, a->enumeration_name);<br>
> +<br>
> + if (e == NULL)<br>
> fail(&ctx->loc,<br>
> "could not find enumeration %s",<br>
> a->enumeration_name);<br>
><br>
> switch (a->type) {<br>
> case INT:<br>
> - if (f->bitfield)<br>
> + if (e->bitfield)<br>
> fail(&ctx->loc,<br>
> "bitfield-style enum must only be referenced by uint");<br>
> break;<br>
> @@ -848,12 +878,13 @@ end_element(void *data, const XML_Char *name)<br>
> ctx->enumeration->name);<br>
> }<br>
> ctx->enumeration = NULL;<br>
> - } else if (strcmp(name, "interface") == 0) {<br>
> - struct interface *i = ctx->interface;<br>
> -<br>
> - verify_arguments(ctx, &i->request_list, &i->enumeration_list);<br>
> - verify_arguments(ctx, &i->event_list, &i->enumeration_list);<br>
> + } else if (strcmp(name, "protocol") == 0) {<br>
> + struct interface *i;<br>
><br>
> + wl_list_for_each(i, &ctx->protocol->interface_list, link) {<br>
> + verify_arguments(ctx, i, &i->request_list, &i->enumeration_list);<br>
> + verify_arguments(ctx, i, &i->event_list, &i->enumeration_list);<br>
> + }<br>
> }<br>
> }<br>
<span class="HOEnZb"><font color="#888888">><br>
> --<br>
> 2.6.2<br>
><br>
</font></span></blockquote></div><br></div>