[PATCH wayland v3] protocol: add support for cross-interface enum attributes

Pekka Paalanen ppaalanen at gmail.com
Tue May 3 12:04:41 UTC 2016


On Sat,  5 Dec 2015 12:39:12 +0000
Auke Booij <auke at tulcod.com> wrote:

> 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 at tulcod.com>
> ---
>  doc/publican/protocol-to-docbook.xsl | 19 +++++++++--
>  protocol/wayland.xml                 |  4 +--
>  src/scanner.c                        | 63 +++++++++++++++++++++++++++---------
>  3 files changed, 65 insertions(+), 21 deletions(-)
> 
> diff --git a/doc/publican/protocol-to-docbook.xsl b/doc/publican/protocol-to-docbook.xsl
> index fad207a..7e892c3 100644
> --- a/doc/publican/protocol-to-docbook.xsl
> +++ b/doc/publican/protocol-to-docbook.xsl
> @@ -103,9 +103,22 @@
>      <listitem>
>          <simpara>
>            <xsl:if test="@enum">
> -            <link linkend="protocol-spec-{../../@name}-enum-{@enum}">
> -              <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:text> </xsl:text>
>            </xsl:if>
>            <xsl:value-of select="@type"/>

Hi,

thanks for this.

This XSL snippet does not work when the enum is defined in a different
XML file, does it? Just making sure I know what the expected behaviour
is.

> diff --git a/protocol/wayland.xml b/protocol/wayland.xml
> index f9e6d76..0873553 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">
> @@ -1292,7 +1292,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>
>  

These look good.

>      <!-- Version 3 additions -->
> diff --git a/src/scanner.c b/src/scanner.c
> index 406519f..85aeea7 100644
> --- a/src/scanner.c
> +++ b/src/scanner.c
> @@ -747,8 +747,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);

This looks like a spurious change for this patch, but I let it pass.

>  
>  		wl_list_insert(ctx->interface->enumeration_list.prev,
>  			       &enumeration->link);
> @@ -785,32 +785,62 @@ 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)

Wrap long lines.

> +{
> +	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;
> +		}
> +	}

Please use strchr() instead.

> +
> +	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;

Missing a space after keyword in both copies.

I'd recommend factoring that to a new function
static struct enumeration *
interface_find_enumeration(const struct *interface, const char *enum_name)
or just reordering to avoid the duplicate code.

> +	}
> +
> +	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)

Wrap long line.

>  {
>  	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);

Ok, so we do not support enums in different XML files. Those will have
to go without a reference for now.

>  
>  			switch (a->type) {
>  			case INT:
> -				if (f->bitfield)
> +				if (e->bitfield)
>  					fail(&ctx->loc,
>  					     "bitfield-style enum must only be referenced by uint");
>  				break;
> @@ -848,12 +878,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);
> +		}
>  	}
>  }
>  

Ok, there would be quite some things to polish, but since this patch
has waited for so long so I just rebased the xsl hunk myself, made some
whitespace fixes and pushed it:
   e21aeb5..7ccf35d  master -> master

Please have a look at the merged patch in case I missed something.

If you want to do more clean-ups, those can land after the alpha release.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160503/9c15abaa/attachment.sig>


More information about the wayland-devel mailing list