mesa: add KHR_no_error support to glDrawBuffer()
[mesa.git] / src / mapi / glapi / gen / typeexpr.py
1
2 # (C) Copyright IBM Corporation 2005
3 # All Rights Reserved.
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # on the rights to use, copy, modify, merge, publish, distribute, sub
9 # license, and/or sell copies of the Software, and to permit persons to whom
10 # the Software is furnished to do so, subject to the following conditions:
11 #
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
14 # Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 # IN THE SOFTWARE.
23 #
24 # Authors:
25 # Ian Romanick <idr@us.ibm.com>
26
27 import string, copy
28
29 class type_node(object):
30 def __init__(self):
31 self.pointer = 0 # bool
32 self.const = 0 # bool
33 self.signed = 1 # bool
34 self.integer = 1 # bool
35
36 # If elements is set to non-zero, then field is an array.
37 self.elements = 0
38
39 self.name = None
40 self.size = 0 # type's size in bytes
41 return
42
43
44 def string(self):
45 """Return string representation of this type_node."""
46 s = ""
47
48 if self.pointer:
49 s = "* "
50
51 if self.const:
52 s += "const "
53
54 if not self.pointer:
55 if self.integer:
56 if self.signed:
57 s += "signed "
58 else:
59 s += "unsigned "
60
61 if self.name:
62 s += "%s " % (self.name)
63
64 return s
65
66
67 class type_table(object):
68 def __init__(self):
69 self.types_by_name = {}
70 return
71
72
73 def add_type(self, type_expr):
74 self.types_by_name[ type_expr.get_base_name() ] = type_expr
75 return
76
77
78 def find_type(self, name):
79 if name in self.types_by_name:
80 return self.types_by_name[ name ]
81 else:
82 return None
83
84
85 def create_initial_types():
86 tt = type_table()
87
88 basic_types = [
89 ("char", 1, 1),
90 ("short", 2, 1),
91 ("int", 4, 1),
92 ("long", 4, 1),
93 ("float", 4, 0),
94 ("double", 8, 0),
95 ("enum", 4, 1)
96 ]
97
98 for (type_name, type_size, integer) in basic_types:
99 te = type_expression(None)
100 tn = type_node()
101 tn.name = type_name
102 tn.size = type_size
103 tn.integer = integer
104 te.expr.append(tn)
105 tt.add_type( te )
106
107 type_expression.built_in_types = tt
108 return
109
110
111 class type_expression(object):
112 built_in_types = None
113
114 def __init__(self, type_string, extra_types = None):
115 self.expr = []
116
117 if not type_string:
118 return
119
120 self.original_string = type_string
121
122 if not type_expression.built_in_types:
123 raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
124
125 # Replace '*' with ' * ' in type_string. Then, split the string
126 # into tokens, separated by spaces.
127 tokens = string.split( string.replace( type_string, "*", " * " ) )
128
129 const = 0
130 t = None
131 signed = 0
132 unsigned = 0
133
134 for i in tokens:
135 if i == "const":
136 if t and t.pointer:
137 t.const = 1
138 else:
139 const = 1
140 elif i == "signed":
141 signed = 1
142 elif i == "unsigned":
143 unsigned = 1
144 elif i == "*":
145 # This is a quirky special-case because of the
146 # way the C works for types. If 'unsigned' is
147 # specified all by itself, it is treated the
148 # same as "unsigned int".
149
150 if unsigned:
151 self.set_base_type( "int", signed, unsigned, const, extra_types )
152 const = 0
153 signed = 0
154 unsigned = 0
155
156 if not self.expr:
157 raise RuntimeError("Invalid type expression (dangling pointer)")
158
159 if signed:
160 raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
161
162 t = type_node()
163 t.pointer = 1
164 self.expr.append( t )
165 else:
166 if self.expr:
167 raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
168
169 self.set_base_type( i, signed, unsigned, const, extra_types )
170 const = 0
171 signed = 0
172 unsigned = 0
173
174 if signed and unsigned:
175 raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
176
177
178 if const:
179 raise RuntimeError("Invalid type expression (dangling const)")
180
181 if unsigned:
182 raise RuntimeError("Invalid type expression (dangling signed)")
183
184 if signed:
185 raise RuntimeError("Invalid type expression (dangling unsigned)")
186
187 return
188
189
190 def set_base_type(self, type_name, signed, unsigned, const, extra_types):
191 te = type_expression.built_in_types.find_type( type_name )
192 if not te:
193 te = extra_types.find_type( type_name )
194
195 if not te:
196 raise RuntimeError('Unknown base type "%s".' % (type_name))
197
198 self.expr = copy.deepcopy(te.expr)
199
200 t = self.expr[ len(self.expr) - 1 ]
201 t.const = const
202 if signed:
203 t.signed = 1
204 elif unsigned:
205 t.signed = 0
206
207
208 def set_base_type_node(self, tn):
209 self.expr = [tn]
210 return
211
212
213 def set_elements(self, count):
214 tn = self.expr[0]
215
216 tn.elements = count
217 return
218
219
220 def string(self):
221 s = ""
222 for t in self.expr:
223 s += t.string()
224
225 return s
226
227
228 def get_base_type_node(self):
229 return self.expr[0]
230
231
232 def get_base_name(self):
233 if len(self.expr):
234 return self.expr[0].name
235 else:
236 return None
237
238
239 def get_element_size(self):
240 tn = self.expr[0]
241
242 if tn.elements:
243 return tn.elements * tn.size
244 else:
245 return tn.size
246
247
248 def get_element_count(self):
249 tn = self.expr[0]
250 return tn.elements
251
252
253 def get_stack_size(self):
254 tn = self.expr[ -1 ]
255
256 if tn.elements or tn.pointer:
257 return 4
258 elif not tn.integer:
259 return tn.size
260 else:
261 return 4
262
263
264 def is_pointer(self):
265 tn = self.expr[ -1 ]
266 return tn.pointer
267
268
269 def format_string(self):
270 tn = self.expr[ -1 ]
271 if tn.pointer:
272 return "%p"
273 elif not tn.integer:
274 return "%f"
275 else:
276 return "%d"
277
278
279
280 if __name__ == '__main__':
281
282 types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
283 "unsigned * const *", \
284 "float", "const double", "double * const"]
285
286 create_initial_types()
287
288 for t in types_to_try:
289 print 'Trying "%s"...' % (t)
290 te = type_expression( t )
291 print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size())