[Xcb] parametrized structs

Christian Linhart chris at DemoRecorder.com
Tue Aug 26 03:40:21 PDT 2014


Hi Daniel,

On 08/26/14 10:10, Daniel Martin wrote:
> Sorry for jumping in to/that late.
No problem. Thank you very much for your input.
> 
> Imho, you shouldn't stress yourself to much with this request.
Actually, I need it for an application where I use another
generator to generate code which does several things including 
byte-order stuff.
And that application has to support legacy XI 1...
So I really have no choice but to implement support for that.

>> What do you think?
> 
> I would vote for the inline struct. 
I have thought more about inline.

The major advantage of inline is more intuitive xml.

Some disadvantages are 
* that the generator needs to create artificial names in the C-code.
  These names can become quite long and cumbersome to use, 
  especially if there's more nesting.

* inline does not allow code-reuse in the xml.
  (in RandR there is an example where code-reuse will be useful,
  more about that further below)

* inline seems to be more complicated to implement in the generator.
  But I may be wrong on that, and I'll see it when I do the implementation.

So it is not clear whether inline is better or not...

> There's another request where this
> could be usefull (skip the API-compatibility for this thought):
>     RandR/GetScreenResources
>     http://cgit.freedesktop.org/xcb/proto/tree/src/randr.xml#n220
> 
> With inlined structs it could be changed somehow like:
> 
> <request name="GetScreenResources" opcode="8">
>   <field type="WINDOW" name="window" />
>   <reply>
>     <pad bytes="1" />
>     ...
>     <list name="modes">
>       <struct name="ModeInfo">
>         ...
>         <field type="CARD16" name="name_len" />
>       </struct>
>       <fieldref>num_modes</fieldref>
>     </list>
>     <list name="names">
>       <list type="char" name="mode_name"> <!-- nest into a struct? -->
>         <fieldref>name_len</fieldref>
>       </list>
>       <fieldref>num_modes</fieldref>
>     </list>
>   </reply>
> </request>

Thank you for this example.

It is even more complicated than the XInput example:
There are two parallel lists: "modeinfos", "mode_names".
The length of a string in "mode_names" is determined by the
name_len-field of the corresponding entry in "modeinfos".

Therefore this is beyond the capabilities and scope
of the previous examples in this thread.
(That's good because it can provide further insight.)

This will need an additional mechanism to access members of 
structs in another list with the same index
and moving up and down the scoping hierachy for resolving
names. 
All of this could be made implicitly by the parser/generator
but maybe that's too much implicit magic?

When we want to avoid too much implicit stuff, 
I suggest something like the following,
which would make the cross-list access more explicit.

This will, e.g., need three additional expression-tags:
	<listelement>list-expression index-expression</listelement>
		access one element of a list.

		We can also use <op op="[]"> for this construct
		instead of naming it <listelement>.

	<memberaccess>: specify the object where to apply nested fieldref etc
		<memberaccess> is similar to the "." or "->" operators in C.
		This avoids automatic moving up and down the scoping hierarchy.

		We can also use <op op="."> for this construct
		instead of naming it <memberaccess>.

	<listindex/> : index of the current list-element inside a <list> or <sumof> scope.
		It can have an optional attribute which selects the list in case of nested lists.
		If no list is specified then the innermost list is used.

Below is your RandR-example rewritten with these constructs.
I have provided an inline and non-inline example variant.

With inline:

====================
<request name="GetScreenResources" opcode="8">
...
   <reply>
     ...
     <list name="modes">
       <struct name="ModeInfo">
         ...
         <field type="CARD16" name="name_len" />
       </struct>
       <fieldref>num_modes</fieldref>
     </list>
     <list name="names">
       <list type="char" name="mode_name"> <!-- nest into a struct? -->
	     <memberaccess>
		<listelement>
		    <fieldref>modes</fieldref>
		    <listindex/>
		</listelement>
		<fieldref>name_len</fieldref>
	     </memberaccess>
       </list>
       <fieldref>num_modes</fieldref>
     </list>
====================

Without inline:

====================
<struct name="StringWithExternalLength">
	<list type="BYTE" name="name">
		<paramref type="CARD16">len</paramref>
	</list>
</struct>

<request name="GetScreenResources" opcode="8">
...
   <reply>
	...
	<list type="ModeInfo" name="modes">
	    <fieldref>num_modes</fieldref>
	</list>
	<list name="names" type="StringWithExternalLength">
	    <typearg name="len"><!--compute value of the StringWithExternalLength-parameter "len" below -->
		<memberaccess>
		    <listelement>
		        <fieldref>modes</fieldref>
		        <listindex/>
		    </listelement>
		    <fieldref>name_len</fieldref>
		</memberaccess>
	    </typearg>
	    <fieldref>num_modes</fieldref>
	</list>
====================

The example "without inline" has the advantage that there won't be 
code-duplication of "ModeInfo" which is used in another place, too:
namely in request "CreateMode".

The struct "StringWithExternalLength" can also be reused for the
"name"-member of request "CreateMode".

Here's request "CreateMode" in the none-inline variant:

====================
	<request name="CreateMode" opcode="16">
		<field type="WINDOW" name="window" />
		<field type="ModeInfo" name="mode_info" />
		<field type="StringWithExternalLength" name="name">
			<typearg name="len"><!--compute value of the StringWithExternalLength-parameter "len" below -->
				<memberaccess><!-- mode_info.name_len -->
					<fieldref>mode_info</fieldref>
					<fieldref>name_len</fieldref>
				</memberaccess>
			</typearg>
		</field>
		<pad align="4"/>
		<reply>
			<pad bytes="1" />
			<field type="MODE" name="mode" />
			<pad bytes="20" />
		</reply>
	</request>
====================

So, non-inline may be useful here.

What do you think?

Chris


> 
> 
> Cheers,
>     Daniel Martin
> _______________________________________________
> Xcb mailing list
> Xcb at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xcb
> 



More information about the Xcb mailing list