2017-09-04 15:08:36 +10:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
import xml.etree.ElementTree as ET
|
2017-09-06 12:11:20 +10:00
|
|
|
import re
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
def camel_to_snake(name):
|
|
|
|
name = re.sub('([a-z])([A-Z])', r'\1_\2', name)
|
|
|
|
return name.lower()
|
|
|
|
|
|
|
|
|
|
|
|
def remove_namespace(name):
|
|
|
|
name = re.sub('^VK_', '', name)
|
|
|
|
name = re.sub('^[vV][kK]', '', name)
|
|
|
|
return name
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
def rename(name):
|
|
|
|
return name
|
|
|
|
name = remove_namespace(name)
|
|
|
|
name = camel_to_snake(name)
|
|
|
|
return name
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
def rename_enum(type, value):
|
|
|
|
return value
|
|
|
|
value = rename(value)
|
|
|
|
value = re.sub("^%s_" % type, '', value)
|
|
|
|
return value
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
class type(object):
|
|
|
|
def __init__(self, name):
|
|
|
|
self.name = name
|
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
return []
|
|
|
|
|
|
|
|
def declare(self):
|
|
|
|
return ""
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self,types):
|
2017-09-04 15:08:36 +10:00
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class basetype(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == 'type')
|
|
|
|
assert(node.attrib['category'] == 'basetype')
|
|
|
|
|
|
|
|
super().__init__(node.find('name').text)
|
|
|
|
self._type = node.find('type').text
|
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
return [self._type]
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self, types):
|
|
|
|
return "using %(name)s = %(type)s;" % {
|
|
|
|
'name': rename(self.name),
|
|
|
|
'type': self._type
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class handle(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert (node.tag == "type")
|
|
|
|
assert (node.attrib['category'] == 'handle')
|
|
|
|
|
|
|
|
super().__init__(node.find('name').text)
|
|
|
|
|
|
|
|
def declare(self):
|
2017-09-06 12:11:20 +10:00
|
|
|
return "using %(name)s = struct _%(name)s*;" % {
|
|
|
|
'name': rename(self.name)
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class constant(type):
|
|
|
|
def __init__(self,node):
|
|
|
|
assert(node.tag == 'enum')
|
|
|
|
|
|
|
|
super().__init__(node.attrib['name'])
|
|
|
|
|
|
|
|
self._value = node.attrib['value']
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self, types):
|
|
|
|
return "constexpr auto %(name)s = %(value)s;" % {
|
|
|
|
'name': self.name,
|
|
|
|
'value': self._value
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
# a high level 'bitmask' enum that doesn't necessarily define anything.
|
|
|
|
# inherits the values from something else instead. super fucking weird..
|
|
|
|
class bitmask(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == 'type')
|
|
|
|
assert(node.attrib['category'] == 'bitmask')
|
|
|
|
|
|
|
|
super().__init__(node.find('name').text)
|
|
|
|
|
|
|
|
self._requires = node.attrib.get('requires', None)
|
|
|
|
self._type = node.find('type').text
|
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
if self._requires:
|
|
|
|
return [self._type, self._requires]
|
|
|
|
else:
|
|
|
|
return [self._type]
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def declare(self):
|
|
|
|
return ""
|
|
|
|
|
|
|
|
def define(self, types):
|
|
|
|
if not self._requires:
|
|
|
|
return "using %(name)s = %(type)s;" % {
|
|
|
|
'name': rename(self.name),
|
|
|
|
'type': rename(self._type)
|
|
|
|
}
|
|
|
|
|
|
|
|
return "using %(name)s = %(requires)s;" % {
|
|
|
|
'name': rename(self.name),
|
|
|
|
'requires': rename(self._requires)
|
|
|
|
}
|
|
|
|
|
|
|
|
members = types[self._requires].values
|
|
|
|
|
|
|
|
return "enum class %(name)s : %(type)s { %(members)s };" % {
|
|
|
|
'name': rename(self.name),
|
|
|
|
'type': rename(self._type),
|
|
|
|
'members': "\n".join("%(name)s = %(value)s," % x for x in members)
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
# an enum with bit values that will be used by a bitmask enum. weirdly...
|
|
|
|
class bitflag(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == "enums")
|
|
|
|
assert(node.attrib['type'] == 'bitmask')
|
|
|
|
|
|
|
|
name = node.attrib['name']
|
|
|
|
super ().__init__(name)
|
|
|
|
|
|
|
|
self._depends = node.attrib.get('requires', None)
|
|
|
|
|
|
|
|
self.values = []
|
|
|
|
for v in node.findall("./enum"):
|
|
|
|
if 'value' in v.attrib:
|
2017-09-05 17:19:51 +10:00
|
|
|
self.add(v.attrib['name'], v.attrib['value'])
|
2017-09-04 15:08:36 +10:00
|
|
|
elif 'bitpos' in v.attrib:
|
2017-09-05 17:19:51 +10:00
|
|
|
self.add(v.attrib['name'], '1 << %s' % v.attrib['bitpos'])
|
2017-09-04 15:08:36 +10:00
|
|
|
else:
|
|
|
|
assert False, "unhandled bitmask type"
|
|
|
|
|
2017-09-05 17:19:51 +10:00
|
|
|
def add(self, name, value=None):
|
|
|
|
self.values.append({'name': name, 'value': value})
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def values(self):
|
|
|
|
return self.values
|
|
|
|
|
2017-09-04 15:08:36 +10:00
|
|
|
def depends(self):
|
|
|
|
if self._depends:
|
2017-09-06 12:11:20 +10:00
|
|
|
return ['VkFlags',self._depends]
|
2017-09-04 15:08:36 +10:00
|
|
|
else:
|
2017-09-06 12:11:20 +10:00
|
|
|
return ['VkFlags']
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
def declare(self):
|
|
|
|
return ""
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self,types):
|
2017-09-05 17:19:51 +10:00
|
|
|
values = []
|
|
|
|
for v in self.values:
|
|
|
|
if 'value' in v:
|
2017-09-06 12:11:20 +10:00
|
|
|
values.append(
|
|
|
|
"%(name)s = %(value)s" % {
|
|
|
|
'name': rename(v['name']),
|
|
|
|
'value': v['value']
|
|
|
|
}
|
|
|
|
)
|
2017-09-05 17:19:51 +10:00
|
|
|
else:
|
2017-09-06 12:11:20 +10:00
|
|
|
values.append(rename(v['name']))
|
|
|
|
|
|
|
|
return """
|
|
|
|
enum %(name)s : %(vkflags)s { %(members)s };
|
|
|
|
""" % {
|
|
|
|
'name': rename(self.name),
|
|
|
|
'vkflags': rename('VkFlags'),
|
|
|
|
'members': ", ".join(values)
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class enum(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == "enums")
|
|
|
|
|
|
|
|
name = node.attrib['name']
|
|
|
|
super().__init__(name)
|
|
|
|
|
2017-09-05 17:19:51 +10:00
|
|
|
self.values = list(map(
|
2017-09-04 15:08:36 +10:00
|
|
|
lambda x: {
|
|
|
|
'name' : x.attrib['name'],
|
|
|
|
'value': x.attrib['value']
|
|
|
|
},
|
|
|
|
node.findall('./enum')
|
2017-09-05 17:19:51 +10:00
|
|
|
))
|
|
|
|
|
|
|
|
def add(self,name,value=None):
|
|
|
|
self.values.append({'name': name, 'value': value})
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
def declare(self):
|
|
|
|
return ""
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self,types):
|
2017-09-05 17:19:51 +10:00
|
|
|
values = []
|
|
|
|
for v in self.values:
|
|
|
|
if v['value']:
|
2017-09-06 12:11:20 +10:00
|
|
|
values.append(
|
|
|
|
"%(name)s = %(value)s" % {
|
|
|
|
'name': rename(v['name']),
|
|
|
|
'value': v['value']
|
|
|
|
}
|
|
|
|
)
|
2017-09-05 17:19:51 +10:00
|
|
|
else:
|
2017-09-06 12:11:20 +10:00
|
|
|
values.append(rename(v['name']))
|
2017-09-04 15:08:36 +10:00
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
attribute = '[[nodiscard]]' if self.name == 'VkResult' else ''
|
|
|
|
|
|
|
|
return "enum %(attribute)s %(name)s : int32_t { %(values)s };" % ({
|
|
|
|
'name': rename(self.name),
|
|
|
|
'attribute': attribute,
|
|
|
|
'values': ", ".join(values),
|
|
|
|
})
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class funcpointer(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == 'type')
|
|
|
|
assert(node.attrib['category'] == "funcpointer")
|
|
|
|
|
|
|
|
name = node.find('name').text
|
|
|
|
super().__init__(name)
|
|
|
|
self.params = list(map(lambda x: x.text, node.findall('./type')))
|
|
|
|
self.text = "".join(node.itertext())
|
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
return ['VkBool32'] + self.params
|
|
|
|
|
|
|
|
def declare(self):
|
|
|
|
return self.text
|
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self,types):
|
2017-09-04 15:08:36 +10:00
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class pod(type):
|
|
|
|
def __init__(self,node):
|
|
|
|
assert(node.tag == 'type')
|
|
|
|
assert(node.attrib['category'] in ['struct', 'union'])
|
|
|
|
|
|
|
|
super().__init__(node.attrib['name'])
|
2017-09-06 12:11:20 +10:00
|
|
|
self._node = node
|
2017-09-04 15:08:36 +10:00
|
|
|
self._category = node.attrib['category']
|
|
|
|
|
|
|
|
# sometimes there are enums hiding in the member fields being used as array sizes
|
|
|
|
self._depends = []
|
|
|
|
self._depends += list(e.text for e in node.findall('.//enum'))
|
|
|
|
self._depends += list(t.text for t in node.findall('.//type'))
|
|
|
|
|
2017-09-07 15:46:07 +10:00
|
|
|
self._members = []
|
|
|
|
|
|
|
|
for member in node.findall('./member'):
|
|
|
|
type = member.find('type').text
|
|
|
|
name = member.find('name').text
|
|
|
|
|
|
|
|
comment = member.find('comment')
|
|
|
|
if not comment is None:
|
|
|
|
member.remove(comment)
|
|
|
|
code = " ".join(member.itertext())
|
|
|
|
|
|
|
|
#code = member.iter()
|
|
|
|
#code = filter(lambda x: x.tag != 'comment', code)
|
|
|
|
#code = map(lambda x: x.itertext(), code)
|
|
|
|
#code = map(lambda x: "".join(x), code)
|
|
|
|
#code = "".join(code)
|
|
|
|
|
|
|
|
self._members.append({'code': code, 'type': type, 'name': name})
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
return self._depends
|
|
|
|
|
|
|
|
def declare(self):
|
2017-09-06 12:11:20 +10:00
|
|
|
return "%(category)s %(name)s;" % {
|
|
|
|
'category': self._category,
|
|
|
|
'name': rename(self.name)
|
|
|
|
}
|
2017-09-04 15:08:36 +10:00
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
def define(self,types):
|
2017-09-06 00:14:18 +10:00
|
|
|
return "%(category)s %(name)s {\n%(members)s\n};" % {
|
2017-09-04 15:08:36 +10:00
|
|
|
'category': self._category,
|
2017-09-06 12:11:20 +10:00
|
|
|
'name': rename(self.name),
|
2017-09-04 15:08:36 +10:00
|
|
|
'members': "\n".join(m['code'] + ';' for m in self._members)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class struct(pod):
|
|
|
|
def __init__(self,node):
|
|
|
|
super().__init__(node)
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
class union(pod):
|
|
|
|
def __init__(self,node):
|
|
|
|
super().__init__(node)
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
def parse_types(nodes):
|
|
|
|
types = []
|
|
|
|
|
|
|
|
for n in nodes:
|
|
|
|
# we need to parse too much unstructured text to actually do anything
|
|
|
|
# useful with these declarations
|
|
|
|
for t in n.findall("./type[@category='handle']"):
|
|
|
|
types.append(handle(t))
|
|
|
|
|
|
|
|
for t in n.findall('./type[@category="bitmask"]'):
|
|
|
|
types.append(bitmask(t))
|
|
|
|
|
|
|
|
for t in n.findall('./type[@category="basetype"]'):
|
|
|
|
types.append(basetype(t))
|
|
|
|
|
|
|
|
for t in n.findall("./type[@category='funcpointer']"):
|
|
|
|
types.append(funcpointer(t))
|
|
|
|
|
|
|
|
for t in n.findall("./type[@category='union']"):
|
|
|
|
types.append(union(t))
|
|
|
|
|
|
|
|
for t in n.findall("./type[@category='struct']"):
|
|
|
|
types.append(struct(t))
|
|
|
|
|
|
|
|
return types
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
def parse_enums(nodes):
|
|
|
|
enums = []
|
|
|
|
|
|
|
|
for n in nodes:
|
|
|
|
if n.attrib['name'] == "API Constants":
|
|
|
|
for c in n.findall('./enum'):
|
|
|
|
enums.append(constant(c))
|
|
|
|
elif n.attrib['type'] == 'bitmask':
|
|
|
|
enums.append(bitflag(n))
|
|
|
|
elif n.attrib['type'] == 'enum':
|
|
|
|
enums.append(enum(n))
|
|
|
|
else:
|
|
|
|
assert False, "unhandled enum type"
|
|
|
|
|
|
|
|
return enums
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
class command(type):
|
|
|
|
def __init__(self, node):
|
|
|
|
assert(node.tag == "command")
|
|
|
|
proto = node.find('proto')
|
|
|
|
super().__init__(proto.find('name').text)
|
|
|
|
|
|
|
|
self._result = proto.find('type').text
|
|
|
|
self._params = []
|
|
|
|
self._depends = []
|
|
|
|
for p in node.findall('./param'):
|
|
|
|
self._depends.append(p.find('type').text)
|
|
|
|
self._params.append("".join(p.itertext()))
|
|
|
|
|
|
|
|
def depends(self):
|
|
|
|
return [self._result] + self._depends
|
|
|
|
|
|
|
|
def declare(self):
|
|
|
|
return "%(result)s %(name)s (%(params)s) noexcept;" % {
|
2017-09-06 12:11:20 +10:00
|
|
|
'name': rename(self.name),
|
2017-09-04 15:08:36 +10:00
|
|
|
'result': self._result,
|
|
|
|
'params': ", ".join(self._params)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
def parse_commands(nodes):
|
|
|
|
commands = []
|
|
|
|
|
|
|
|
for n in nodes:
|
|
|
|
for c in n.findall('./command'):
|
|
|
|
commands.append(command(c))
|
|
|
|
|
|
|
|
return commands
|
|
|
|
|
|
|
|
|
2017-09-05 17:19:51 +10:00
|
|
|
###############################################################################
|
|
|
|
def parse_extension(types, node):
|
|
|
|
r = node.find('require')
|
|
|
|
|
|
|
|
for enum in r.findall('./enum'):
|
|
|
|
if 'extends' in enum.attrib:
|
|
|
|
types[enum.attrib['extends']].add(name=enum.attrib['name'])
|
|
|
|
for command in r.findall('./command'):
|
|
|
|
if not command.attrib['name'] in types:
|
|
|
|
raise "unknown command"
|
|
|
|
|
|
|
|
|
2017-09-04 15:08:36 +10:00
|
|
|
###############################################################################
|
2017-09-06 12:11:20 +10:00
|
|
|
def write_type(dst, all, pending, t):
|
2017-09-04 15:08:36 +10:00
|
|
|
logging.info("writing: %s", t.name)
|
|
|
|
|
|
|
|
for d in t.depends():
|
2017-09-06 12:11:20 +10:00
|
|
|
if d in pending:
|
|
|
|
write_type(dst, all, pending, pending[d])
|
2017-09-04 15:08:36 +10:00
|
|
|
|
2017-09-06 12:11:20 +10:00
|
|
|
if t.name in pending:
|
2017-09-04 15:08:36 +10:00
|
|
|
dst.write(t.declare())
|
2017-09-06 00:14:18 +10:00
|
|
|
dst.write('\n')
|
2017-09-06 12:11:20 +10:00
|
|
|
dst.write(t.define(all))
|
2017-09-04 15:08:36 +10:00
|
|
|
dst.write('\n')
|
2017-09-06 12:11:20 +10:00
|
|
|
del pending[t.name]
|
2017-09-04 15:08:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
2017-09-06 12:11:20 +10:00
|
|
|
import copy
|
2017-09-04 15:08:36 +10:00
|
|
|
def write_types(dst, types):
|
2017-09-06 12:11:20 +10:00
|
|
|
all = types
|
|
|
|
pending = copy.deepcopy(types)
|
2017-09-04 15:08:36 +10:00
|
|
|
keys = list(types.keys())
|
|
|
|
|
|
|
|
for k in keys:
|
|
|
|
if k in types:
|
2017-09-06 12:11:20 +10:00
|
|
|
write_type(dst, all, pending, types[k])
|
2017-09-05 17:19:51 +10:00
|
|
|
|
|
|
|
|
2017-09-04 15:08:36 +10:00
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
def write_root(dst, node):
|
|
|
|
dst.write ("""
|
|
|
|
#ifndef __VK_HPP
|
|
|
|
#define __VK_HPP
|
2017-09-06 12:11:20 +10:00
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct enable_bitops : public std::false_type { };
|
|
|
|
|
2017-09-04 15:08:36 +10:00
|
|
|
#include <cstdint>
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct Display;
|
|
|
|
struct VisualID;
|
|
|
|
using Window = unsigned long;
|
|
|
|
|
|
|
|
struct ANativeWindow;
|
|
|
|
|
|
|
|
struct MirConnection;
|
|
|
|
struct MirSurface;
|
|
|
|
|
|
|
|
struct wl_display;
|
|
|
|
struct wl_surface;
|
|
|
|
|
|
|
|
using HANDLE = void*;
|
|
|
|
using HINSTANCE = HANDLE;
|
|
|
|
using HWND = HANDLE;
|
|
|
|
|
|
|
|
using SECURITY_ATTRIBUTES = HANDLE;
|
|
|
|
using DWORD = uint32_t;
|
|
|
|
using LPCWSTR = char16_t*;
|
|
|
|
|
|
|
|
struct xcb_connection_t;
|
|
|
|
struct xcb_visualid_t;
|
|
|
|
using xcb_window_t = uint32_t;
|
|
|
|
using XID = unsigned long;
|
|
|
|
using RROutput = XID;
|
|
|
|
|
|
|
|
#define VKAPI_PTR /*VKAPI_PTR*/
|
|
|
|
|
|
|
|
// because, in its wisdom, the spec doesn't actually allow us to
|
|
|
|
// extract the value for VK_NULL_HANDLE from the XML we'll just
|
|
|
|
// hard code it here.
|
2017-09-06 00:14:18 +10:00
|
|
|
#define VK_NULL_HANDLE nullptr
|
2017-09-06 12:11:20 +10:00
|
|
|
|
2017-09-05 17:19:51 +10:00
|
|
|
// TODO: make this correspond to a required version
|
|
|
|
#define VK_VERSION_1_0
|
2017-09-04 15:08:36 +10:00
|
|
|
""")
|
|
|
|
|
|
|
|
types = []
|
|
|
|
types += parse_types(node.findall('./types'))
|
|
|
|
types += parse_enums(node.findall('./enums'))
|
|
|
|
types += parse_commands(node.findall('./commands'))
|
|
|
|
|
|
|
|
types = dict((t.name,t) for t in types)
|
|
|
|
|
2017-09-05 17:19:51 +10:00
|
|
|
for n in node.findall('./extensions/extension'):
|
|
|
|
parse_extension(types, n)
|
|
|
|
|
2017-09-04 15:08:36 +10:00
|
|
|
write_types(dst, types)
|
|
|
|
|
|
|
|
#dst.writelines("\n".join(map(lambda x: x.declare(), types)))
|
|
|
|
#dst.writelines("\n".join(map(lambda x: x.define(), types)))
|
|
|
|
#dst.writelines("\n".join(map(lambda x: x.declare(), commands)))
|
|
|
|
|
|
|
|
dst.write ("""
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
}
|
|
|
|
#endif
|
2017-09-06 12:11:20 +10:00
|
|
|
""")
|
|
|
|
|
|
|
|
for x in types.values():
|
|
|
|
if isinstance(x,bitflag):
|
|
|
|
dst.write("""
|
|
|
|
template <>
|
|
|
|
struct enable_bitops<%(name)s> :
|
|
|
|
public std::true_type
|
|
|
|
{ };
|
|
|
|
""" % { 'name': x.name }
|
|
|
|
)
|
|
|
|
|
|
|
|
dst.write("""
|
|
|
|
template <typename T>
|
|
|
|
std::enable_if_t<enable_bitops<T>::value, T>
|
|
|
|
operator| (T a, T b)
|
|
|
|
{
|
|
|
|
return T (
|
|
|
|
static_cast<std::underlying_type_t<T>> (a) |
|
|
|
|
static_cast<std::underlying_type_t<T>> (b)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2017-09-04 15:08:36 +10:00
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
|
|
|
|
##-----------------------------------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
|
|
#logging.getLogger().setLevel(logging.INFO)
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='Transform XML API specification into C++ headers')
|
|
|
|
parser.add_argument('src', type=str, help='the path to the XML file to transform')
|
|
|
|
parser.add_argument('dst', type=str, help='the output path for the result')
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
src = open(args.src, 'r')
|
|
|
|
dst = open(args.dst, 'w')
|
|
|
|
|
|
|
|
tree = ET.parse(src)
|
|
|
|
root = tree.getroot()
|
|
|
|
|
|
|
|
write_root(dst, root)
|