diff options
Diffstat (limited to 'specs/scripts')
-rw-r--r-- | specs/scripts/.gitignore | 7 | ||||
-rw-r--r-- | specs/scripts/Makefile | 51 | ||||
-rw-r--r-- | specs/scripts/README | 12 | ||||
-rwxr-xr-x | specs/scripts/cdecl.py | 358 | ||||
-rw-r--r-- | specs/scripts/glparams.sed | 2 | ||||
-rwxr-xr-x | specs/scripts/glspec.py | 283 | ||||
-rwxr-xr-x | specs/scripts/gltxt.py | 169 | ||||
-rwxr-xr-x | specs/scripts/reference-opengl-arb.sh | 30 | ||||
-rwxr-xr-x | specs/scripts/reference-opengl-man.sh | 8 | ||||
-rwxr-xr-x | specs/scripts/sort.sh | 2 | ||||
-rwxr-xr-x | specs/scripts/wglenum.sh | 5 |
11 files changed, 927 insertions, 0 deletions
diff --git a/specs/scripts/.gitignore b/specs/scripts/.gitignore new file mode 100644 index 0000000..1dbc0cf --- /dev/null +++ b/specs/scripts/.gitignore @@ -0,0 +1,7 @@ +*.spec +*.tm +*.txt +*api.py +glparams.py +wglenum.py +!Makefile diff --git a/specs/scripts/Makefile b/specs/scripts/Makefile new file mode 100644 index 0000000..2ea2066 --- /dev/null +++ b/specs/scripts/Makefile @@ -0,0 +1,51 @@ + +all: \ + download \ + glapi.py glxapi.py wglapi.py \ + glparams.py wglenum.py + +download: \ + enum.spec \ + enumext.spec \ + gl.spec \ + gl.tm \ + glxenum.spec \ + glxenumext.spec \ + glx.spec \ + glxext.spec \ + glx.tm \ + wglenum.spec \ + wglenumext.spec \ + wgl.spec \ + wglext.spec \ + wgl.tm + +%.spec: + wget -N http://www.opengl.org/registry/api/$@ + +%.tm: + wget -N http://www.opengl.org/registry/api/$@ + +glapi.py: glspec.py gl.tm gl.spec + python glspec.py gl gl.tm gl.spec > $@ + +glxapi.py: glspec.py glx.tm glx.spec glxext.spec + python glspec.py glX glx.tm glx.spec glxext.spec > $@ + +wglapi.py: glspec.py wgl.tm wgl.spec wglext.spec + python glspec.py wgl wgl.tm wgl.spec wglext.spec > $@ + +glparams.py: glparams.sed enum.spec sort.sh + sed -n -f glparams.sed enum.spec | ./sort.sh > $@ + +wglenum.py: wglenum.sh wglenumext.spec + ./wglenum.sh wglenumext.spec > $@ + +clean: + rm -f \ + glapi.py glxapi.py wglapi.py \ + glparams.py wglenum.py + +.PRECIOUS: %.spec %.tm + +.PHONY: download clean diff --git a/specs/scripts/README b/specs/scripts/README new file mode 100644 index 0000000..6df2a3d --- /dev/null +++ b/specs/scripts/README @@ -0,0 +1,12 @@ +This directory contains several helper scripts that facilitate the generation +of the API descriptions from specs and/or header files. + +The specs/headers are not expressive enough, which is why we can't just code +generate everything from them. + +For GL the typical procedure is to run + + make -B + +and then manually crossport new functions / enums to the files in the top dir +via a side-by-side diff tool, such as gvimdiff. diff --git a/specs/scripts/cdecl.py b/specs/scripts/cdecl.py new file mode 100755 index 0000000..4f36b3c --- /dev/null +++ b/specs/scripts/cdecl.py @@ -0,0 +1,358 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2011 Jose Fonseca +# 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. +# +##########################################################################/ + + +'''Script to parse C declarations and spew API definitions. +''' + + +import sys +import re +import optparse + + +class Parser: + + token_re = re.compile(r'(\w+|\s+|.)') + + multi_comment_re = re.compile(r'/\*.*?\*/', flags = re.DOTALL) + single_comment_re = re.compile(r'//.*',) + + def __init__(self): + self.tokens = [] + + def has_side_effects(self, name): + return True + + + def tokenize(self, s): + s = self.multi_comment_re.sub('', s) + s = self.single_comment_re.sub('', s) + self.tokens = self.token_re.split(s) + self.tokens = [token for token in self.tokens if self.filter_token(token)] + + def filter_token(self, token): + if not token or token.isspace(): + return False + if token.startswith('AVAILABLE_') or token.startswith('DEPRECATED_'): + return False + if token in ['FAR']: + return False + return True + + def lookahead(self, index = 0): + try: + return self.tokens[index] + except KeyError: + return None + + def match(self, *ref_tokens): + return self.lookahead() in ref_tokens + + def consume(self, *ref_tokens): + if not self.tokens: + raise Exception('unexpected EOF') + token = self.tokens.pop(0) + if ref_tokens and token not in ref_tokens: + raise Exception('token mismatch', token, ref_tokens) + return token + + def eof(self): + return not self.tokens + + + def parse(self, s): + self.tokenize(s) + + while not self.eof(): + #print self.tokens[0:10] + self.parse_declaration() + + def parse_declaration(self): + self.parse_tags() + if self.match('enum'): + self.parse_enum() + elif self.match('interface'): + self.parse_interface() + elif self.match('mask'): + self.parse_value('mask', 'Flags') + elif self.match('struct'): + self.parse_struct() + elif self.match('value'): + self.parse_value('value', 'FakeEnum') + elif self.match('typedef'): + self.parse_typedef() + else: + self.parse_prototype() + if not self.eof() and self.match(';'): + self.consume(';') + + def parse_typedef(self): + self.consume('typedef') + if self.lookahead(2) in (';', ','): + base_type = self.consume() + while True: + type = base_type + if self.match('*'): + self.consume() + type = 'Pointer(%s)' % type + name = self.consume() + print '%s = Alias("%s", %s)' % (name, name, type) + if self.match(','): + self.consume() + else: + break + else: + self.parse_declaration() + self.consume() + + def parse_enum(self): + self.consume('enum') + name = self.consume() + self.consume('{') + + print '%s = Enum("%s", [' % (name, name) + + #value = 0 + while self.lookahead() != '}': + name = self.consume() + if self.match('='): + self.consume('=') + value = self.consume() + if self.match(','): + self.consume(',') + tags = self.parse_tags() + #print ' "%s",\t# %s' % (name, value) + print ' "%s",' % (name,) + #value += 1 + self.consume('}') + + print '])' + print + + def parse_value(self, ref_token, constructor): + self.consume(ref_token) + type = self.consume() + name = self.consume() + self.consume('{') + + print '%s = %s(%s, [' % (name, constructor, type) + + while self.lookahead() != '}': + self.consume('#') + self.consume('define') + name = self.consume() + value = self.consume() + #print ' "%s",\t# %s' % (name, value) + print ' "%s",' % (name,) + self.consume('}') + + print '])' + print + + def parse_struct(self): + self.consume('struct') + name = self.consume() + self.consume('{') + + print '%s = Struct("%s", [' % (name, name) + + value = 0 + while self.lookahead() != '}': + type, name = self.parse_named_type() + if self.match(','): + self.consume(',') + self.consume(';') + print ' (%s, "%s"),' % (type, name) + value += 1 + self.consume('}') + + print '])' + print + + def parse_interface(self): + self.consume('interface') + name = self.consume() + if self.match(';'): + return + self.consume(':') + base = self.consume() + self.consume('{') + + print '%s = Interface("%s", %s)' % (name, name, base) + print '%s.methods += [' % (name,) + + while self.lookahead() != '}': + self.parse_prototype('Method') + self.consume(';') + self.consume('}') + + print ']' + print + + def parse_prototype(self, creator = 'Function'): + if self.match('extern'): + self.consume() + + ret = self.parse_type() + + if self.match('__stdcall'): + self.consume() + creator = 'StdFunction' + + name = self.consume() + extra = '' + if not self.has_side_effects(name): + extra += ', sideeffects=False' + name = name + + self.consume('(') + args = [] + if self.match('void') and self.tokens[1] == ')': + self.consume() + while self.lookahead() != ')': + arg = self.parse_arg() + args.append(arg) + if self.match(','): + self.consume() + self.consume() == ')' + + print ' %s(%s, "%s", [%s]%s),' % (creator, ret, name, ', '.join(args), extra) + + def parse_arg(self): + tags = self.parse_tags() + + type, name = self.parse_named_type() + + arg = '(%s, "%s")' % (type, name) + if 'out' in tags: + arg = 'Out' + arg + return arg + + def parse_tags(self): + tags = [] + if self.match('['): + self.consume() + while not self.match(']'): + tag = self.consume() + tags.append(tag) + self.consume(']') + return tags + + def parse_named_type(self): + type = self.parse_type() + name = self.consume() + if self.match('['): + self.consume() + length = self.consume() + self.consume(']') + type = 'Array(%s, "%s")' % (type, length) + return type, name + + int_tokens = ('unsigned', 'signed', 'int', 'long', 'short', 'char') + + type_table = { + 'float': 'Float', + 'double': 'Double', + 'int8_t': 'Int8', + 'uint8_t': 'UInt8', + 'int16_t': 'Int16', + 'uint16_t': 'UInt16', + 'int32_t': 'Int32', + 'uint32_t': 'UInt32', + 'int64_t' : 'Int64', + 'uint64_t': 'UInt64', + } + + def parse_type(self): + const = False + token = self.consume() + if token == 'const': + token = self.consume() + const = True + if token == 'void': + type = 'Void' + elif token in self.int_tokens: + unsigned = False + signed = False + long = 0 + short = 0 + char = False + while token in self.int_tokens: + if token == 'unsigned': + unsigned = True + if token == 'signed': + signed = True + if token == 'long': + long += 1 + if token == 'short': + short += 1 + if token == 'char': + char = False + if self.lookahead() in self.int_tokens: + token = self.consume() + else: + token = None + if char: + type = 'Char' + if signed: + type = 'S' + type + elif short: + type = 'Short' + elif long: + type = 'Long' * long + else: + type = 'Int' + if unsigned: + type = 'U' + type + else: + type = self.type_table.get(token, token) + if const: + type = 'Const(%s)' % type + while True: + if self.match('*'): + self.consume('*') + type = 'OpaquePointer(%s)' % type + elif self.match('const'): + self.consume('const') + type = 'Const(%s)' % type + else: + break + return type + + + + + + +def main(): + parser = Parser() + for arg in sys.argv[1:]: + parser.parse(open(arg, 'rt').read()) + + +if __name__ == '__main__': + main() diff --git a/specs/scripts/glparams.sed b/specs/scripts/glparams.sed new file mode 100644 index 0000000..8afde64 --- /dev/null +++ b/specs/scripts/glparams.sed @@ -0,0 +1,2 @@ +s/^\s\+\(\w\+\)\s*=\s*\(0x\w\+\)\s\+#\s\+\([0-9]\+\)\s\+\([IF]\)\s*\(#.*\)\?$/ ("glGet",\t\4,\t\3,\t"GL_\1"),\t# \2/p +s/^\s\+\(\w\+\)\s*=\s*\(0x\w\+\)\s*\(#.*\)\?$/ ("",\tX,\t1,\t"GL_\1"),\t# \2/p diff --git a/specs/scripts/glspec.py b/specs/scripts/glspec.py new file mode 100755 index 0000000..dbd20ce --- /dev/null +++ b/specs/scripts/glspec.py @@ -0,0 +1,283 @@ +#!/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|Is|Are)[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': + if inout == 'in': + base_type = 'Const(%s)' % base_type + arg_type = 'Pointer(%s)' % base_type + elif kind.startswith("array"): + if inout == 'in': + base_type = 'Const(%s)' % base_type + + arg_type = 'OpaquePointer(%s)' % base_type + + if base_type in ('Void', 'void', 'GLvoid'): + constructor = 'Blob' + else: + constructor = 'Array' + + 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 = '%s(%s, "%s")' % (constructor, base_type, length) + else: + length = length.replace("COMPSIZE", "__%s_size" % function_name) + length = length.replace("/", ", ") + arg_type = 'Opaque%s(%s, "%s")' % (constructor, base_type, length) + 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() diff --git a/specs/scripts/gltxt.py b/specs/scripts/gltxt.py new file mode 100755 index 0000000..c6be7c1 --- /dev/null +++ b/specs/scripts/gltxt.py @@ -0,0 +1,169 @@ +#!/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 TxtParser(LineParser): + + property_re = re.compile(r'^\w+:') + prototype_re = re.compile(r'^(\w+)\((.*)\)$') + + def __init__(self, stream, prefix=''): + LineParser.__init__(self, stream) + self.prefix = prefix + + def parse(self): + line = self.consume() + while not line.startswith("New Procedures and Functions"): + line = self.consume() + self.parse_procs() + + def parse_procs(self): + lines = [] + while True: + line = self.consume() + if not line.strip(): + continue + if not line.startswith(' '): + break + lines.append(line.strip()) + if line.endswith(';'): + self.parse_proc(' '.join(lines)) + lines = [] + + token_re = re.compile(r'(\w+|\s+|.)') + get_function_re = re.compile(r'^Get[A-Z]\w+') + + def parse_proc(self, prototype): + #print prototype + tokens = self.token_re.split(prototype) + self.tokens = [token for token in tokens if token.strip()] + #print self.tokens + + ret = self.parse_type() + + name = self.tokens.pop(0) + extra = '' + if self.get_function_re.match(name): + extra += ', sideeffects=False' + name = self.prefix + name + + assert self.tokens.pop(0) == '(' + args = [] + while self.tokens[0] != ')': + arg = self.parse_arg() + args.append(arg) + if self.tokens[0] == ',': + self.tokens.pop(0) + print ' GlFunction(%s, "%s", [%s]%s),' % (ret, name, ', '.join(args), extra) + + def parse_arg(self): + type = self.parse_type() + name = self.tokens.pop(0) + return '(%s, "%s")' % (type, name) + + def parse_type(self): + token = self.tokens.pop(0) + if token == 'const': + return 'Const(%s)' % self.parse_type() + if token == 'void': + type = 'Void' + else: + type = 'GL' + token + while self.tokens[0] == '*': + type = 'OpaquePointer(%s)' % type + self.tokens.pop(0) + return type + + +def main(): + for arg in sys.argv[1:]: + parser = TxtParser(open(arg, 'rt'), prefix='gl') + parser.parse() + + +if __name__ == '__main__': + main() diff --git a/specs/scripts/reference-opengl-arb.sh b/specs/scripts/reference-opengl-arb.sh new file mode 100755 index 0000000..670ba17 --- /dev/null +++ b/specs/scripts/reference-opengl-arb.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Script to extract reference URLs for functions documented in OpenGL ARB specs + +extract_urls () { + for URL + do + lynx -dump "$URL" | sed -n -e '/^References$/,$s/^ *[0-9]\+\. \+//p' | sed -e 's/ /%20/g' + done +} + +extract_functions () { + sed -n -e '/^New Procedures and Functions$/,/^\w/ s/.* \(\w\+\)(.*$/\1/p' "$@" \ + | sed -e '/^[A-Z]/s/^/gl/' +} + +extract_urls http://www.opengl.org/registry/ \ +| grep '^http://www\.opengl\.org/registry/specs/ARB/.*\.txt$' \ +| sort -u \ +| while read URL +do + wget --quiet -O - $URL \ + | extract_functions \ + | while read FUNCTION + do + echo "$FUNCTION $URL" + done +done + + + diff --git a/specs/scripts/reference-opengl-man.sh b/specs/scripts/reference-opengl-man.sh new file mode 100755 index 0000000..20bdaa6 --- /dev/null +++ b/specs/scripts/reference-opengl-man.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# Script to extract reference URLS for functions documented in OpenGL man pages + +wget -N -r -np http://www.opengl.org/sdk/docs/{man,man2,man3,man4}/ + +find www.opengl.org -type f -name '*.xml' \ +| xargs grep -o '<b class="fsfunc">[^<]*</b>' \ +| sed -e 's/<[^>]*>//g' -e 's@^\(.*\):\(.*\)$@\2\thttp://\1@' diff --git a/specs/scripts/sort.sh b/specs/scripts/sort.sh new file mode 100755 index 0000000..5cdc6a4 --- /dev/null +++ b/specs/scripts/sort.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sed -e 's/\(^.*#\) \(0x\w\+\)$/\2 \1/' "$@" | sort | sed -e 's/\(0x\w\+\) \(.*#\)$/\2 \1/' diff --git a/specs/scripts/wglenum.sh b/specs/scripts/wglenum.sh new file mode 100755 index 0000000..97f969d --- /dev/null +++ b/specs/scripts/wglenum.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +sed -n -e 's/^\s\+\(WGL_\S\+\)\s*=\s*\(0x2\w\w\w\)\s*$/\2 \1/p' "$@" \ +| sort -u \ +| sed -e 's/\(\S\+\)\s\+\(\S\+\)/ "\2",\t\t# \1/' |