3 # (C) Copyright IBM Corporation 2005
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:
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
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
26 # Ian Romanick <idr@us.ibm.com>
37 # If elements is set to non-zero, then field is an array.
62 s
+= "%s " % (self
.name
)
69 self
.types_by_name
= {}
73 def add_type(self
, type_expr
):
74 self
.types_by_name
[ type_expr
.get_base_name() ] = type_expr
78 def find_type(self
, name
):
79 if name
in self
.types_by_name
:
80 return self
.types_by_name
[ name
]
85 def create_initial_types():
88 basic_types
= [ ["char", 1, 1], \
97 for [type_name
, type_size
, integer
] in basic_types
:
98 te
= type_expression(None)
106 type_expression
.built_in_types
= tt
110 class type_expression
:
111 built_in_types
= None
113 def __init__(self
, type_string
, extra_types
= None):
116 if not type_string
: return
118 self
.original_string
= type_string
120 if not type_expression
.built_in_types
:
121 raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
124 elements
= string
.split( string
.replace( type_string
, "*", " * " ) )
139 elif i
== "unsigned":
142 # This is a quirky special-case because of the
143 # way the C works for types. If 'unsigned' is
144 # specified all by itself, it is treated the
145 # same as "unsigned int".
148 self
.set_base_type( "int", signed
, unsigned
, const
, extra_types
)
154 raise RuntimeError("Invalid type expression (dangling pointer)")
157 raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
161 self
.expr
.append( t
)
164 raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self
.original_string
))
166 self
.set_base_type( i
, signed
, unsigned
, const
, extra_types
)
171 if signed
and unsigned
:
172 raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
176 raise RuntimeError("Invalid type expression (dangling const)")
179 raise RuntimeError("Invalid type expression (dangling signed)")
182 raise RuntimeError("Invalid type expression (dangling unsigned)")
187 def set_base_type(self
, type_name
, signed
, unsigned
, const
, extra_types
):
188 te
= type_expression
.built_in_types
.find_type( type_name
)
190 te
= extra_types
.find_type( type_name
)
193 raise RuntimeError('Unknown base type "%s".' % (type_name
))
195 self
.expr
= copy
.deepcopy(te
.expr
)
197 t
= self
.expr
[ len(self
.expr
) - 1 ]
205 def set_base_type_node(self
, tn
):
210 def set_elements(self
, count
):
225 def get_base_type_node(self
):
229 def get_base_name(self
):
231 return self
.expr
[0].name
236 def get_element_size(self
):
240 return tn
.elements
* tn
.size
245 def get_element_count(self
):
250 def get_stack_size(self
):
251 tn
= self
.expr
[ len(self
.expr
) - 1 ]
253 if tn
.elements
or tn
.pointer
:
261 def is_pointer(self
):
262 tn
= self
.expr
[ len(self
.expr
) - 1 ]
266 def format_string(self
):
267 tn
= self
.expr
[ len(self
.expr
) - 1 ]
277 if __name__
== '__main__':
279 types_to_try
= [ "int", "int *", "const int *", "int * const", "const int * const", \
280 "unsigned * const *", \
281 "float", "const double", "double * const"]
283 create_initial_types()
285 for t
in types_to_try
:
286 print 'Trying "%s"...' % (t
)
287 te
= type_expression( t
)
288 print 'Got "%s" (%u, %u).' % (te
.string(), te
.get_stack_size(), te
.get_element_size())