]> git.cworth.org Git - apitrace/commitdiff
Minor cleanups and better documentation for the spec generation scripts.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 1 Dec 2011 09:00:50 +0000 (09:00 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 1 Dec 2011 09:01:38 +0000 (09:01 +0000)
common/os_win32.cpp
specs/scripts/README [deleted file]
specs/scripts/README.markdown [new file with mode: 0644]
specs/scripts/cdecl.py
specs/scripts/gltxt.py

index 13dd4f890a7f5b8ea2788eb4a2dc9182697ecc58..0b7243305a8408152d3308f797d75b5b2458829b 100644 (file)
@@ -196,6 +196,7 @@ int execute(char * const * args)
                         &processInformation
                         )) {
         log("error: failed to execute %s\n", arg0);
+        return -1;
     }
 
     WaitForSingleObject(processInformation.hProcess, INFINITE);
diff --git a/specs/scripts/README b/specs/scripts/README
deleted file mode 100644 (file)
index 6df2a3d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-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/README.markdown b/specs/scripts/README.markdown
new file mode 100644 (file)
index 0000000..66f9faa
--- /dev/null
@@ -0,0 +1,54 @@
+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 directly.  However the scripts in this directory
+usually get 90% of the work done automatically.
+
+
+OpenGL
+======
+
+For OpenGL the typical procedure is to run
+
+    make -B
+
+which will generate several python scripts with prototypes and defines from the
+Khronos `.spec` files:
+    
+* glapi.py
+
+* glparams.py 
+
+* glxapi.py 
+
+* wglapi.py
+
+* wglenum.py
+
+and then manually crossport new functions / enums to the identically named
+files in the parent dir via a side-by-side diff tool, such as gvimdiff.
+
+
+OpenGL ES
+=========
+
+Khronos doesn't provide `.spec` files for OpenGL ES.  But the `gltxt.py` script
+can extract and convert prototypes for the `.txt` extension specifications:
+
+    $ ./gltxt.py http://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt
+        # GL_OES_mapbuffer
+        GlFunction(Void, "glGetBufferPointervOES", [(GLenum, "target"), (GLenum, "pname"), (OpaquePointer(OpaquePointer(Void)), "params")], sideeffects=False),
+        GlFunction(OpaquePointer(Void), "glMapBufferOES", [(GLenum, "target"), (GLenum, "access")]),
+        GlFunction(GLboolean, "glUnmapBufferOES", [(GLenum, "target")]),
+
+
+Generic
+=======
+
+When the domain specific scripts don't work the fallback solution is `cdecl.py`, which can parse most C declarations:
+
+    $ echo 'void *memcpy(void *dest, const void *src, size_t n);' | ./cdecl.py 
+        Function(OpaquePointer(Void), "memcpy", [(OpaquePointer(Void), "dest"), (OpaquePointer(Const(Void)), "src"), (size_t, "n")]),
+
+
index 613561c9f72fdd10d46f57a360e7428994b61513..d6ee05850df2159ff0e7b2246ed9be3e650c8220 100755 (executable)
@@ -34,7 +34,7 @@ import re
 import optparse
 
 
-class Parser:
+class DeclParser:
 
     token_re = re.compile(r'(\d[x0-9a-fA-F.UL]*|\w+|\s+|.)')
 
@@ -354,14 +354,15 @@ class Parser:
         return type
 
 
-
-        
-
-
 def main():
-    parser = Parser()
-    for arg in sys.argv[1:]:
-        parser.parse(open(arg, 'rt').read())
+    args = sys.argv[1:]
+
+    parser = DeclParser()
+    if args:
+        for arg in args:
+            parser.parse(open(arg, 'rt').read())
+    else:
+        parser.parse(sys.stdin.read())
     
 
 if __name__ == '__main__':
index 7fc62f557f0823c2ee6949c58943a79bc11af478..4ce92320114b1d52ba101739310a78baf7837b40 100755 (executable)
@@ -31,6 +31,7 @@
 import sys
 import re
 import optparse
+from urllib2 import urlopen
 
 
 def stderr(x):
@@ -91,6 +92,8 @@ class LineParser:
 
 class TxtParser(LineParser):
 
+    section_re = re.compile(r'^([A-Z]\w+)( \w+)*$')
+
     property_re = re.compile(r'^\w+:')
     prototype_re = re.compile(r'^(\w+)\((.*)\)$')
 
@@ -99,22 +102,51 @@ class TxtParser(LineParser):
         self.prefix = prefix
 
     def parse(self):
-        line = self.consume()
-        while not line.startswith("New Procedures and Functions"):
+        while  not self.eof():
+            while not self.eof():
+                line = self.lookahead()
+                if self.eof():
+                    return
+                mo = self.section_re.match(line)
+                if mo:
+                    break
+                self.consume()
             line = self.consume()
-        self.parse_procs()
+            self.parse_section(line)
+        print
+
+    def parse_section(self, name):
+        if name == 'Name Strings':
+            self.parse_strings()
+        if name == 'New Procedures and Functions':
+            self.parse_procs()
+
+    def parse_strings(self):
+        while not self.eof():
+            line = self.lookahead()
+            if not line.strip():
+                self.consume()
+                continue
+            if not line.startswith(' '):
+                break
+            self.consume()
+            name = line.strip()
+            print '    # %s' % name
 
     def parse_procs(self):
         lines = []
-        while True:
-            line = self.consume()
+        while not self.eof():
+            line = self.lookahead()
             if not line.strip():
+                self.consume()
                 continue
             if not line.startswith(' '):
                 break
+            self.consume()
             lines.append(line.strip())
-            if line.endswith(';'):
-                self.parse_proc(' '.join(lines))
+            if line[-1] in (';', ')'):
+                prototype = ' '.join(lines)
+                self.parse_proc(prototype)
                 lines = []
 
     token_re = re.compile(r'(\w+|\s+|.)')
@@ -163,8 +195,21 @@ class TxtParser(LineParser):
 
 
 def main():
-    for arg in sys.argv[1:]:
-        parser = TxtParser(open(arg, 'rt'), prefix='gl')
+    optparser = optparse.OptionParser(
+        usage="\n\t%prog [options] [SPEC] ")
+    optparser.add_option(
+        '-p', '--prefix', metavar='STRING',
+        type="string", dest="prefix", default='gl',
+        help="function prefix [default: %default]")
+
+    (options, args) = optparser.parse_args(sys.argv[1:])
+
+    for arg in args:
+        if arg.startswith('http://'):
+            stream = urlopen(arg, 'rt')
+        else:
+            stream = open(arg, 'rt')
+        parser = TxtParser(stream, prefix = options.prefix)
         parser.parse()