]> git.cworth.org Git - apitrace/blob - specs/scripts/gltxt.py
7fc62f557f0823c2ee6949c58943a79bc11af478
[apitrace] / specs / scripts / gltxt.py
1 #!/usr/bin/env python
2 ##########################################################################
3 #
4 # Copyright 2010 VMware, Inc.
5 # All Rights Reserved.
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 # THE SOFTWARE.
24 #
25 ##########################################################################/
26
27
28 """Parser for OpenGL .txt extensions specification."""
29
30
31 import sys
32 import re
33 import optparse
34
35
36 def stderr(x):
37     sys.stderr.write(str(x) + '\n')
38
39
40 class Parser:
41
42     def __init__(self, stream):
43         pass
44
45
46 class LineParser:
47     """Base class for parsers that read line-based formats."""
48
49     def __init__(self, stream):
50         self._stream = stream
51         self._line = None
52         self._eof = False
53         # read lookahead
54         self.readline()
55     
56     def parse(self):
57         raise NotImplementedError
58
59     def readline(self):
60         line = self._stream.readline()
61         if not line:
62             self._line = ''
63             self._eof = True
64         self._line = line.rstrip('\r\n')
65
66     def lookahead(self):
67         assert self._line is not None
68         return self._line
69
70     def consume(self):
71         assert self._line is not None
72         line = self._line
73         self.readline()
74         return line
75
76     def eof(self):
77         assert self._line is not None
78         return self._eof
79     
80     def skip_whitespace(self):
81         while not self.eof() and self.match_whitespace() or self.match_comment():
82             self.consume()
83
84     def match_whitespace(self):
85         line = self.lookahead()
86         return not line.strip()
87
88     def match_comment(self):
89         return False
90
91
92 class TxtParser(LineParser):
93
94     property_re = re.compile(r'^\w+:')
95     prototype_re = re.compile(r'^(\w+)\((.*)\)$')
96
97     def __init__(self, stream, prefix=''):
98         LineParser.__init__(self, stream)
99         self.prefix = prefix
100
101     def parse(self):
102         line = self.consume()
103         while not line.startswith("New Procedures and Functions"):
104             line = self.consume()
105         self.parse_procs()
106
107     def parse_procs(self):
108         lines = []
109         while True:
110             line = self.consume()
111             if not line.strip():
112                 continue
113             if not line.startswith(' '):
114                 break
115             lines.append(line.strip())
116             if line.endswith(';'):
117                 self.parse_proc(' '.join(lines))
118                 lines = []
119
120     token_re = re.compile(r'(\w+|\s+|.)')
121     get_function_re = re.compile(r'^Get[A-Z]\w+')
122
123     def parse_proc(self, prototype):
124         #print prototype
125         tokens = self.token_re.split(prototype)
126         self.tokens = [token for token in tokens if token.strip()]
127         #print self.tokens
128
129         ret = self.parse_type()
130
131         name = self.tokens.pop(0)
132         extra = ''
133         if self.get_function_re.match(name):
134             extra += ', sideeffects=False'
135         name = self.prefix + name
136
137         assert self.tokens.pop(0) == '('
138         args = []
139         while self.tokens[0] != ')':
140             arg = self.parse_arg()
141             args.append(arg)
142             if self.tokens[0] == ',':
143                 self.tokens.pop(0)
144         print '    GlFunction(%s, "%s", [%s]%s),' % (ret, name, ', '.join(args), extra)
145
146     def parse_arg(self):
147         type = self.parse_type()
148         name = self.tokens.pop(0)
149         return '(%s, "%s")' % (type, name)
150
151     def parse_type(self):
152         token = self.tokens.pop(0)
153         if token == 'const':
154             return 'Const(%s)' % self.parse_type()
155         if token == 'void':
156             type = 'Void'
157         else:
158             type = 'GL' + token
159         while self.tokens[0] == '*':
160             type = 'OpaquePointer(%s)' % type
161             self.tokens.pop(0)
162         return type
163
164
165 def main():
166     for arg in sys.argv[1:]:
167         parser = TxtParser(open(arg, 'rt'), prefix='gl')
168         parser.parse()
169     
170
171 if __name__ == '__main__':
172     main()