vk.xml

ZombineDev via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Feb 21 07:18:44 PST 2016


On Sunday, 21 February 2016 at 12:52:33 UTC, Nicholas Wilson 
wrote:
> So I was going through the vulcan spec to try to create a 
> better D bindings for it. (pointer /len pairs to arrays 
> adhering to D naming conventions and prettying up the *Create 
> functions functions like vkResult *Create( arg ,&arg, retptr) 
> to a fancy throw on misuse struct with constructors and that 
> kind of stuff.)
>
>  the structure of the registry is as follows.
>
>
> struct KHR_registry
> {
> <snip>
> }
>

I'm glad to see more people looking to create a D binding from 
vk.xml!
I was also working on this 
(http://forum.dlang.org/post/ygylvtuwwiwyqtcnlejh@forum.dlang.org), unfortunately I won't be able to continue my work until early March, so I hope you'll do a good job in the mean time ;)

Unfortunately the spec is written in a very C specific way so we 
need to have a bunch of special cases for parsing the C code 
that's interleaved with the XML tags.

I haven't used std.xml yet, but I hope I may be able to help you.

> where "string content" is the string between the tags (does 
> this have a name?) and thing with @Tag are always in the tag 
> (although it is also inconsistent). I tried looking at the docs 
> for std.xml but they were not very helpful.

May be you can use
http://dlang.org/phobos/std_xml#.Element.text in combination with
http://dlang.org/phobos/std_xml#.Element.elements

> To further complicate things not all of the fields are present 
> in all cases also I need to keep track of the number of '*' 
> (see fields named indirections) after a tag has closed  for 
> pointer type declarations in function signatures and structs.

You mean things like:
<param><type>void</type>** <name>ppData</name></param>
(from the vkMapMemory command) ?

Yeah this is extremely ugly.
One way to do it is to go to the "param" XML element
and check if the size of it's elements matches it's text size. In 
the case above everything between <param>  and </param> is 39 
characters and the two tags are
17 and 19 character respectively (total 36) which leaves 3 chars 
for the indirections. If we make a pass to remove all whitespace 
between tags (between ">" and "<") we should get exactly 2 
characters which is the number of indirection we're looking for.

Another way is to just strip the tags and leave only their 
internal text. In the above example the result should be:
<param>void** ppData</param>
which is valid D code and we can leave it that way for now.

> Also is there a way to do sane cross referencing without having 
> internal pointers everywhere.

I am no XML expert (so there may be an easier way), but I think 
it would be easier if we use associative arrays, instead of plain 
arrays. That way we can check for example:

if ("VkBuffer" in types && "VkDevice" in types)
     types["VkBuffer"].parent = types["VkDevice"];

> I'm sure there should be a very elegant way to do this by 
> recursing down through the sub-structs

The simplest solution, IMO, is to insert all the types, commands, 
enums, etc. in associative arrays first and then do 
cross-referencing.

E.g.

Type[string] types;
struct Type
{
    // ... other members

    // Set to string first, and later change
    // to the proper Type, after the whole `types` table has been 
read.
    Algebraic(string, Type*) parent;

    // ... more members
}

Otherwise the only sane way to do forward reference resolution is 
to use D Fibers. I have used fibers in some of my projects, but 
the extra complications are not worth it for this task as the xml 
is only 5100 lines and the performance benefits probably would 
not be very large.

> Many thanks
> Nic

BTW if you run into some other issues with std.xml, you can also 
check
http://arsdnet.net/web.d/dom.html and
https://github.com/burner/std.xml2

Also don't forget to use unittests extensively!


More information about the Digitalmars-d-learn mailing list