%.spec %.tm:
wget -N http://www.opengl.org/registry/api/$@
-glapi.py: spec.py gl.tm gl.spec
- python spec.py gl gl.tm gl.spec > $@
+glapi.py: glspec.py gl.tm gl.spec
+ python glspec.py gl gl.tm gl.spec > $@
-glxapi.py: spec.py glx.tm glx.spec glxext.spec
- python spec.py glX glx.tm glx.spec glxext.spec > $@
+glxapi.py: glspec.py glx.tm glx.spec glxext.spec
+ python glspec.py glX glx.tm glx.spec glxext.spec > $@
-wglapi.py: spec.py wgl.tm wgl.spec wglext.spec
- python spec.py wgl wgl.tm wgl.spec wglext.spec > $@
+wglapi.py: glspec.py wgl.tm wgl.spec wglext.spec
+ python glspec.py wgl wgl.tm wgl.spec wglext.spec > $@
.PRECIOUS: %.spec %.tm
--- /dev/null
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 2010 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+
+import sys
+import re
+import optparse
+
+
+def stderr(x):
+ sys.stderr.write(str(x) + '\n')
+
+
+class Parser:
+
+ def __init__(self, stream):
+ pass
+
+
+class LineParser:
+ """Base class for parsers that read line-based formats."""
+
+ def __init__(self, stream):
+ self._stream = stream
+ self._line = None
+ self._eof = False
+ # read lookahead
+ self.readline()
+
+ def parse(self):
+ raise NotImplementedError
+
+ def readline(self):
+ line = self._stream.readline()
+ if not line:
+ self._line = ''
+ self._eof = True
+ self._line = line.rstrip('\r\n')
+
+ def lookahead(self):
+ assert self._line is not None
+ return self._line
+
+ def consume(self):
+ assert self._line is not None
+ line = self._line
+ self.readline()
+ return line
+
+ def eof(self):
+ assert self._line is not None
+ return self._eof
+
+ def skip_whitespace(self):
+ while not self.eof() and self.match_whitespace() or self.match_comment():
+ self.consume()
+
+ def match_whitespace(self):
+ line = self.lookahead()
+ return not line.strip()
+
+ def match_comment(self):
+ return False
+
+
+class TypemapParser(LineParser):
+
+ def parse(self):
+ typemap = {}
+ self.skip_whitespace()
+ while not self.eof():
+ line = self.consume()
+ fields = [field.strip() for field in line.split(',')]
+ src = fields[0]
+ dst = fields[3]
+ if dst != '*':
+ typemap[src] = dst
+ self.skip_whitespace()
+ return typemap
+
+ def match_comment(self):
+ line = self.lookahead()
+ return line.startswith('#')
+
+
+class SpecParser(LineParser):
+
+ property_re = re.compile(r'^\w+:')
+ prototype_re = re.compile(r'^(\w+)\((.*)\)$')
+
+ def __init__(self, stream, prefix='', typemap = None):
+ LineParser.__init__(self, stream)
+ if typemap is None:
+ self.typemap = {}
+ else:
+ self.typemap = typemap
+ self.prefix = prefix
+ self.category = None
+
+ def parse(self):
+ self.skip_whitespace()
+ while not self.eof():
+ line = self.lookahead()
+ if self.property_re.match(line):
+ self.parse_property()
+ elif self.prototype_re.match(line):
+ self.parse_prototype()
+ else:
+ self.consume()
+ self.skip_whitespace()
+
+ def parse_property(self):
+ line = self.consume()
+ name, value = line.split(':', 1)
+ if name == 'category':
+ values = value.split()
+ #self.prefix = values[0]
+
+ get_function_re = re.compile(r'^Get[A-Z]\w+')
+
+ def parse_prototype(self):
+ line = self.consume()
+ mo = self.prototype_re.match(line)
+ function_name, arg_names = mo.groups()
+ arg_names = [arg_name.strip() for arg_name in arg_names.split(',') if arg_name.strip()]
+
+ extra = ''
+ if self.get_function_re.match(function_name):
+ extra += ', sideeffects=False'
+ function_name = self.prefix + function_name
+
+ ret_type = 'Void'
+ arg_types = {}
+ category = None
+ line = self.lookahead()
+ while line.startswith('\t'):
+ fields = line.split(None, 2)
+ if fields[0] == 'return':
+ ret_type = self.parse_type(fields[1])
+ elif fields[0] == 'param':
+ arg_name, arg_type = fields[1:3]
+ arg_types[fields[1]] = self.parse_arg(function_name, arg_name, arg_type)
+ elif fields[0] == 'category':
+ category = fields[1]
+ else:
+ pass
+ self.consume()
+ line = self.lookahead()
+ self.consume()
+ args = [arg_types[arg_name] for arg_name in arg_names]
+
+ if category is not None:
+ if category == self.prefix:
+ category = self.prefix.upper()
+ else:
+ category = self.prefix.upper() + '_' + category
+ if category != self.category:
+ if self.category is not None:
+ print
+ print ' # %s' % category
+ self.category = category
+
+ if self.prefix == 'wgl':
+ constructor = 'StdFunction'
+ else:
+ constructor = 'GlFunction'
+
+ print ' %s(%s, "%s", [%s]%s),' % (constructor, ret_type, function_name, ', '.join(args), extra)
+
+ array_re = re.compile(r'^array\s+\[(.*)\]$')
+
+ string_typemap = {
+ 'GLchar': 'GLstring',
+ 'GLcharARB': 'GLstringARB',
+ }
+
+ def parse_arg(self, function_name, arg_name, arg_type):
+ orig_type, inout, kind = arg_type.split(' ', 2)
+
+ base_type = self.parse_type(orig_type)
+
+ if kind == 'value':
+ arg_type = base_type
+ elif kind == 'reference':
+ arg_type = 'Pointer(%s)' % base_type
+ if inout == 'in':
+ arg_type = 'Const(%s)' % arg_type
+ elif kind.startswith("array"):
+ arg_type = 'OpaquePointer(%s)' % base_type
+
+ mo = self.array_re.match(kind)
+ if mo:
+ length = mo.group(1).strip()
+ if length == '':
+ try:
+ arg_type = self.string_typemap[base_type]
+ except KeyError:
+ pass
+ elif length == '1':
+ arg_type = 'Pointer(%s)' % base_type
+ elif length.find("COMPSIZE") == -1:
+ arg_type = 'Array(%s, "%s")' % (base_type, length)
+ else:
+ # XXX: Handle COMPSIZE better
+ length = length.replace("COMPSIZE", "__%s_size" % function_name)
+ length = length.replace("/", ",")
+ arg_type = 'Array(%s, "%s")' % (base_type, length)
+ if inout == 'in':
+ arg_type = 'Const(%s)' % arg_type
+ else:
+ assert False
+
+ arg = '(%s, "%s")' % (arg_type, arg_name)
+ if inout == 'out':
+ arg = 'Out' + arg
+ return arg
+
+ semantic_typemap = {
+ 'String': 'CString',
+ 'Texture': 'GLtexture',
+ }
+
+ post_typemap = {
+ 'void': 'Void',
+ 'int': 'Int',
+ 'float': 'Float',
+ }
+
+ def parse_type(self, type):
+ try:
+ return self.semantic_typemap[type]
+ except KeyError:
+ pass
+ type = self.typemap.get(type, type)
+ type = self.post_typemap.get(type, type)
+ return type
+
+ def match_comment(self):
+ line = self.lookahead()
+ return line.startswith('#')
+
+
+def main():
+ prefix = sys.argv[1]
+
+ parser = TypemapParser(open(sys.argv[2], 'rt'))
+ typemap = parser.parse()
+
+ for arg in sys.argv[3:]:
+ parser = SpecParser(open(arg, 'rt'), prefix=prefix, typemap=typemap)
+ parser.parse()
+
+
+if __name__ == '__main__':
+ main()
+++ /dev/null
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2010 VMware, Inc.
-# All Rights Reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-##########################################################################/
-
-
-import sys
-import re
-import optparse
-
-
-def stderr(x):
- sys.stderr.write(str(x) + '\n')
-
-
-class Parser:
-
- def __init__(self, stream):
- pass
-
-
-class LineParser:
- """Base class for parsers that read line-based formats."""
-
- def __init__(self, stream):
- self._stream = stream
- self._line = None
- self._eof = False
- # read lookahead
- self.readline()
-
- def parse(self):
- raise NotImplementedError
-
- def readline(self):
- line = self._stream.readline()
- if not line:
- self._line = ''
- self._eof = True
- self._line = line.rstrip('\r\n')
-
- def lookahead(self):
- assert self._line is not None
- return self._line
-
- def consume(self):
- assert self._line is not None
- line = self._line
- self.readline()
- return line
-
- def eof(self):
- assert self._line is not None
- return self._eof
-
- def skip_whitespace(self):
- while not self.eof() and self.match_whitespace() or self.match_comment():
- self.consume()
-
- def match_whitespace(self):
- line = self.lookahead()
- return not line.strip()
-
- def match_comment(self):
- return False
-
-
-class TypemapParser(LineParser):
-
- def parse(self):
- typemap = {}
- self.skip_whitespace()
- while not self.eof():
- line = self.consume()
- fields = [field.strip() for field in line.split(',')]
- src = fields[0]
- dst = fields[3]
- if dst != '*':
- typemap[src] = dst
- self.skip_whitespace()
- return typemap
-
- def match_comment(self):
- line = self.lookahead()
- return line.startswith('#')
-
-
-class SpecParser(LineParser):
-
- property_re = re.compile(r'^\w+:')
- prototype_re = re.compile(r'^(\w+)\((.*)\)$')
-
- def __init__(self, stream, prefix='', typemap = None):
- LineParser.__init__(self, stream)
- if typemap is None:
- self.typemap = {}
- else:
- self.typemap = typemap
- self.prefix = prefix
- self.category = None
-
- def parse(self):
- self.skip_whitespace()
- while not self.eof():
- line = self.lookahead()
- if self.property_re.match(line):
- self.parse_property()
- elif self.prototype_re.match(line):
- self.parse_prototype()
- else:
- self.consume()
- self.skip_whitespace()
-
- def parse_property(self):
- line = self.consume()
- name, value = line.split(':', 1)
- if name == 'category':
- values = value.split()
- #self.prefix = values[0]
-
- get_function_re = re.compile(r'^Get[A-Z]\w+')
-
- def parse_prototype(self):
- line = self.consume()
- mo = self.prototype_re.match(line)
- function_name, arg_names = mo.groups()
- arg_names = [arg_name.strip() for arg_name in arg_names.split(',') if arg_name.strip()]
-
- extra = ''
- if self.get_function_re.match(function_name):
- extra += ', sideeffects=False'
- function_name = self.prefix + function_name
-
- ret_type = 'Void'
- arg_types = {}
- category = None
- line = self.lookahead()
- while line.startswith('\t'):
- fields = line.split(None, 2)
- if fields[0] == 'return':
- ret_type = self.parse_type(fields[1])
- elif fields[0] == 'param':
- arg_name, arg_type = fields[1:3]
- arg_types[fields[1]] = self.parse_arg(function_name, arg_name, arg_type)
- elif fields[0] == 'category':
- category = fields[1]
- else:
- pass
- self.consume()
- line = self.lookahead()
- self.consume()
- args = [arg_types[arg_name] for arg_name in arg_names]
-
- if category is not None:
- if category == self.prefix:
- category = self.prefix.upper()
- else:
- category = self.prefix.upper() + '_' + category
- if category != self.category:
- if self.category is not None:
- print
- print ' # %s' % category
- self.category = category
-
- if self.prefix == 'wgl':
- constructor = 'StdFunction'
- else:
- constructor = 'GlFunction'
-
- print ' %s(%s, "%s", [%s]%s),' % (constructor, ret_type, function_name, ', '.join(args), extra)
-
- array_re = re.compile(r'^array\s+\[(.*)\]$')
-
- string_typemap = {
- 'GLchar': 'GLstring',
- 'GLcharARB': 'GLstringARB',
- }
-
- def parse_arg(self, function_name, arg_name, arg_type):
- orig_type, inout, kind = arg_type.split(' ', 2)
-
- base_type = self.parse_type(orig_type)
-
- if kind == 'value':
- arg_type = base_type
- elif kind == 'reference':
- arg_type = 'Pointer(%s)' % base_type
- if inout == 'in':
- arg_type = 'Const(%s)' % arg_type
- elif kind.startswith("array"):
- arg_type = 'OpaquePointer(%s)' % base_type
-
- mo = self.array_re.match(kind)
- if mo:
- length = mo.group(1).strip()
- if length == '':
- try:
- arg_type = self.string_typemap[base_type]
- except KeyError:
- pass
- elif length == '1':
- arg_type = 'Pointer(%s)' % base_type
- elif length.find("COMPSIZE") == -1:
- arg_type = 'Array(%s, "%s")' % (base_type, length)
- else:
- # XXX: Handle COMPSIZE better
- length = length.replace("COMPSIZE", "__%s_size" % function_name)
- length = length.replace("/", ",")
- arg_type = 'Array(%s, "%s")' % (base_type, length)
- if inout == 'in':
- arg_type = 'Const(%s)' % arg_type
- else:
- assert False
-
- arg = '(%s, "%s")' % (arg_type, arg_name)
- if inout == 'out':
- arg = 'Out' + arg
- return arg
-
- semantic_typemap = {
- 'String': 'CString',
- 'Texture': 'GLtexture',
- }
-
- post_typemap = {
- 'void': 'Void',
- 'int': 'Int',
- 'float': 'Float',
- }
-
- def parse_type(self, type):
- try:
- return self.semantic_typemap[type]
- except KeyError:
- pass
- type = self.typemap.get(type, type)
- type = self.post_typemap.get(type, type)
- return type
-
- def match_comment(self):
- line = self.lookahead()
- return line.startswith('#')
-
-
-def main():
- prefix = sys.argv[1]
-
- parser = TypemapParser(open(sys.argv[2], 'rt'))
- typemap = parser.parse()
-
- for arg in sys.argv[3:]:
- parser = SpecParser(open(arg, 'rt'), prefix=prefix, typemap=typemap)
- parser.parse()
-
-
-if __name__ == '__main__':
- main()