]> git.cworth.org Git - apitrace/blobdiff - specs/scripts/cdecl.py
Minimal D3D11 support.
[apitrace] / specs / scripts / cdecl.py
index d6ee05850df2159ff0e7b2246ed9be3e650c8220..013dec0db4ba6b7add8911e0c49a4d45c3c7b813 100755 (executable)
@@ -97,8 +97,8 @@ class DeclParser:
             self.parse_define()
         elif self.match('enum'):
             self.parse_enum()
-        elif self.match('interface'):
-            self.parse_interface()
+        elif self.match('class', 'interface'):
+            self.parse_interface(self.lookahead())
         elif self.match('mask'):
             self.parse_value('mask', 'Flags')
         elif self.match('struct'):
@@ -122,7 +122,7 @@ class DeclParser:
                     self.consume()
                     type = 'Pointer(%s)' % type
                 name = self.consume()
-                print '%s = Alias("%s", %s)' % (name, name, type)
+                print '%s = Alias(%r, %s)' % (name, name, type)
                 if self.match(','):
                     self.consume()
                 else:
@@ -136,7 +136,7 @@ class DeclParser:
         name = self.consume()
         self.consume('{')
 
-        print '%s = Enum("%s", [' % (name, name)
+        print '%s = Enum(%r, [' % (name, name)
 
         #value = 0
         while self.lookahead() != '}':
@@ -147,8 +147,8 @@ class DeclParser:
             if self.match(','):
                 self.consume(',')
             tags = self.parse_tags()
-            #print '    "%s",\t# %s' % (name, value) 
-            print '    "%s",' % (name,) 
+            #print '    %r,\t# %s' % (name, value) 
+            print '    %r,' % (name,) 
             #value += 1
         self.consume('}')
 
@@ -175,59 +175,81 @@ class DeclParser:
         self.consume('define')
         name = self.consume()
         value = self.consume()
-        #print '    "%s",\t# %s' % (name, value) 
-        print '    "%s",' % (name,) 
+        #print '    %r,\t# %s' % (name, value) 
+        print '    %r,' % (name,) 
         return name, value
 
     def parse_struct(self):
         self.consume('struct')
         name = self.consume()
-        self.consume('{')
 
-        print '%s = Struct("%s", [' % (name, name)
+        print '%s = Struct(%r, [' % (name, name)
+        for type, name in self.parse_members():
+            print '    (%s, %r),' % (type, name)
+        print '])'
+        print
+
+    def parse_union(self):
+        self.consume('union')
+        if not self.match('{'):
+            name = self.consume()
+        else:
+            name = None
+        members = self.parse_members()
+        return 'Union(%r, [%s])' % (name, ', '.join('%s, %r' % member for member in members))
 
-        value = 0
+    def parse_members(self):
+        members = []
+        self.consume('{')
         while self.lookahead() != '}':
             type, name = self.parse_named_type()
+
+            if self.match(':'):
+                self.consume()
+                self.consume()
+
             if self.match(','):
                 self.consume(',')
             self.consume(';')
-            print '    (%s, "%s"),' % (type, name) 
-            value += 1
+            members.append((type, name))
         self.consume('}')
+        return members
 
-        print '])'
-        print
-
-    def parse_interface(self):
-        self.consume('interface')
+    def parse_interface(self, ref_token):
+        self.consume(ref_token)
         name = self.consume()
         if self.match(';'):
             return
         self.consume(':')
+        if self.lookahead() in ('public', 'protected'):
+            self.consume()
         base = self.consume()
         self.consume('{')
 
-        print '%s = Interface("%s", %s)' % (name, name, base)
+        print '%s = Interface(%r, %s)' % (name, name, base)
         print '%s.methods += [' % (name,)
 
         while self.lookahead() != '}':
-            self.parse_prototype('Method')
-            self.consume(';')
+            if self.lookahead() in ('public', 'private'):
+                self.consume()
+                self.consume(':')
+            else:
+                self.parse_prototype('Method')
+                self.consume(';')
         self.consume('}')
 
         print ']'
         print
 
     def parse_prototype(self, creator = 'Function'):
-        if self.match('extern'):
+        if self.match('extern', 'virtual'):
             self.consume()
 
         ret = self.parse_type()
 
-        if self.match('__stdcall'):
+        if self.match('__stdcall', 'WINAPI'):
             self.consume()
-            creator = 'StdFunction'
+            creator = 'Std' + creator
 
         name = self.consume()
         extra = ''
@@ -244,18 +266,31 @@ class DeclParser:
             args.append(arg)
             if self.match(','):
                 self.consume()
-        self.consume() == ')'
+        self.consume(')')
+        if self.match('const', 'CONST'):
+            self.consume()
+            extra = ', const=True' + extra
+
+        if self.lookahead() == '=':
+            self.consume()
+            self.consume('0')
         
-        print '    %s(%s, "%s", [%s]%s),' % (creator, ret, name, ', '.join(args), extra)
+        print '    %s(%s, %r, [%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 = '(%s, %r)' % (type, name)
+        if 'out' in tags or 'inout' in tags:
             arg = 'Out' + arg
+
+        if self.match('='):
+            self.consume()
+            while not self.match(',', ')'):
+                self.consume()
+
         return arg
 
     def parse_tags(self):
@@ -266,20 +301,34 @@ class DeclParser:
                 tag = self.consume()
                 tags.append(tag)
             self.consume(']')
+        if self.lookahead().startswith('__'):
+            # Parse __in, __out, etc tags
+            tag = self.consume()[2:]
+            args = []
+            if self.match('('):
+                self.consume()
+                while not self.match(')'):
+                    self.consume()
+                self.consume(')')
+            tags.extend(tag.split('_'))
         return tags
 
     def parse_named_type(self):
         type = self.parse_type()
-        name = self.consume()
-        if self.match('['):
-            self.consume()
-            length = self.consume()
-            self.consume(']')
-            try:
-                int(length)
-            except ValueError:
-                length = "%s" % length
-            type = 'Array(%s, %s)' % (type, length)
+        
+        if self.match(',', ';', '}', ')'):
+            name = None
+        else:
+            name = self.consume()
+            if self.match('['):
+                self.consume()
+                length = self.consume()
+                self.consume(']')
+                try:
+                    int(length)
+                except ValueError:
+                    length = repr(length)
+                type = 'Array(%s, %s)' % (type, length)
         return type, name
 
     int_tokens = ('unsigned', 'signed', 'int', 'long', 'short', 'char')
@@ -299,19 +348,22 @@ class DeclParser:
 
     def parse_type(self):
         const = False
-        token = self.consume()
-        if token == 'const':
-            token = self.consume()
+        if self.match('const', 'CONST'):
+            self.consume()
             const = True
-        if token == 'void':
+        if self.match('void'):
+            self.consume()
             type = 'Void'
-        elif token in self.int_tokens:
+        elif self.match('union'):
+            type = self.parse_union()
+        elif self.match(*self.int_tokens):
             unsigned = False
             signed = False
             long = 0
             short = 0
             char = False
-            while token in self.int_tokens:
+            while self.match(*self.int_tokens):
+                token = self.consume()
                 if token == 'unsigned':
                     unsigned = True
                 if token == 'signed':
@@ -322,10 +374,6 @@ class DeclParser:
                     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:
@@ -339,15 +387,16 @@ class DeclParser:
             if unsigned:
                 type = 'U' + type
         else:
+            token = self.consume()
             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 = 'Pointer(%s)' % type
+            elif self.match('const', 'CONST'):
+                self.consume()
                 type = 'Const(%s)' % type
             else:
                 break