2 ##########################################################################
4 # Copyright 2010 VMware, Inc.
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:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
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
25 ##########################################################################/
28 """Parser for OpenGL .txt extensions specification."""
37 sys.stderr.write(str(x) + '\n')
42 def __init__(self, stream):
47 """Base class for parsers that read line-based formats."""
49 def __init__(self, stream):
57 raise NotImplementedError
60 line = self._stream.readline()
64 self._line = line.rstrip('\r\n')
67 assert self._line is not None
71 assert self._line is not None
77 assert self._line is not None
80 def skip_whitespace(self):
81 while not self.eof() and self.match_whitespace() or self.match_comment():
84 def match_whitespace(self):
85 line = self.lookahead()
86 return not line.strip()
88 def match_comment(self):
92 class TxtParser(LineParser):
94 property_re = re.compile(r'^\w+:')
95 prototype_re = re.compile(r'^(\w+)\((.*)\)$')
97 def __init__(self, stream, prefix=''):
98 LineParser.__init__(self, stream)
102 line = self.consume()
103 while not line.startswith("New Procedures and Functions"):
104 line = self.consume()
107 def parse_procs(self):
110 line = self.consume()
113 if not line.startswith(' '):
115 lines.append(line.strip())
116 if line.endswith(';'):
117 self.parse_proc(' '.join(lines))
120 token_re = re.compile(r'(\w+|\s+|.)')
121 get_function_re = re.compile(r'^Get[A-Z]\w+')
123 def parse_proc(self, prototype):
125 tokens = self.token_re.split(prototype)
126 self.tokens = [token for token in tokens if token.strip()]
129 ret = self.parse_type()
131 name = self.tokens.pop(0)
133 if self.get_function_re.match(name):
134 extra += ', sideeffects=False'
135 name = self.prefix + name
137 assert self.tokens.pop(0) == '('
139 while self.tokens[0] != ')':
140 arg = self.parse_arg()
142 if self.tokens[0] == ',':
144 print ' GlFunction(%s, "%s", [%s]%s),' % (ret, name, ', '.join(args), extra)
147 type = self.parse_type()
148 name = self.tokens.pop(0)
149 return '(%s, "%s")' % (type, name)
151 def parse_type(self):
152 token = self.tokens.pop(0)
154 return 'Const(%s)' % self.parse_type()
159 while self.tokens[0] == '*':
160 type = 'OpaquePointer(%s)' % type
166 for arg in sys.argv[1:]:
167 parser = TxtParser(open(arg, 'rt'), prefix='gl')
171 if __name__ == '__main__':