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