Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / mesa / src / mapi / glapi / gen / gl_XML.py
blobc8e692017dafa847f16513f8693212f9af023fc5
1 #!/usr/bin/env python
3 # (C) Copyright IBM Corporation 2004, 2005
4 # All Rights Reserved.
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
15 # 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 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.
25 # Authors:
26 # Ian Romanick <idr@us.ibm.com>
28 import libxml2
29 import re, sys, string
30 import typeexpr
33 def parse_GL_API( file_name, factory = None ):
34 doc = libxml2.readFile( file_name, None, libxml2.XML_PARSE_XINCLUDE + libxml2.XML_PARSE_NOBLANKS + libxml2.XML_PARSE_DTDVALID + libxml2.XML_PARSE_DTDATTR + libxml2.XML_PARSE_DTDLOAD + libxml2.XML_PARSE_NOENT )
35 ret = doc.xincludeProcess()
37 if not factory:
38 factory = gl_item_factory()
40 api = factory.create_item( "api", None, None )
41 api.process_element( doc )
43 # After the XML has been processed, we need to go back and assign
44 # dispatch offsets to the functions that request that their offsets
45 # be assigned by the scripts. Typically this means all functions
46 # that are not part of the ABI.
48 for func in api.functionIterateByCategory():
49 if func.assign_offset:
50 func.offset = api.next_offset;
51 api.next_offset += 1
53 doc.freeDoc()
55 return api
58 def is_attr_true( element, name ):
59 """Read a name value from an element's attributes.
61 The value read from the attribute list must be either 'true' or
62 'false'. If the value is 'false', zero will be returned. If the
63 value is 'true', non-zero will be returned. An exception will be
64 raised for any other value."""
66 value = element.nsProp( name, None )
67 if value == "true":
68 return 1
69 elif value == "false":
70 return 0
71 else:
72 raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value, name))
75 class gl_print_base:
76 """Base class of all API pretty-printers.
78 In the model-view-controller pattern, this is the view. Any derived
79 class will want to over-ride the printBody, printRealHader, and
80 printRealFooter methods. Some derived classes may want to over-ride
81 printHeader and printFooter, or even Print (though this is unlikely).
82 """
84 def __init__(self):
85 # Name of the script that is generating the output file.
86 # Every derived class should set this to the name of its
87 # source file.
89 self.name = "a"
92 # License on the *generated* source file. This may differ
93 # from the license on the script that is generating the file.
94 # Every derived class should set this to some reasonable
95 # value.
97 # See license.py for an example of a reasonable value.
99 self.license = "The license for this file is unspecified."
102 # The header_tag is the name of the C preprocessor define
103 # used to prevent multiple inclusion. Typically only
104 # generated C header files need this to be set. Setting it
105 # causes code to be generated automatically in printHeader
106 # and printFooter.
108 self.header_tag = None
111 # List of file-private defines that must be undefined at the
112 # end of the file. This can be used in header files to define
113 # names for use in the file, then undefine them at the end of
114 # the header file.
116 self.undef_list = []
117 return
120 def Print(self, api):
121 self.printHeader()
122 self.printBody(api)
123 self.printFooter()
124 return
127 def printHeader(self):
128 """Print the header associated with all files and call the printRealHeader method."""
130 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
131 % (self.name)
132 print ''
133 print '/*'
134 print ' * ' + self.license.replace('\n', '\n * ')
135 print ' */'
136 print ''
137 if self.header_tag:
138 print '#if !defined( %s )' % (self.header_tag)
139 print '# define %s' % (self.header_tag)
140 print ''
141 self.printRealHeader();
142 return
145 def printFooter(self):
146 """Print the header associated with all files and call the printRealFooter method."""
148 self.printRealFooter()
150 if self.undef_list:
151 print ''
152 for u in self.undef_list:
153 print "# undef %s" % (u)
155 if self.header_tag:
156 print ''
157 print '#endif /* !defined( %s ) */' % (self.header_tag)
160 def printRealHeader(self):
161 """Print the "real" header for the created file.
163 In the base class, this function is empty. All derived
164 classes should over-ride this function."""
165 return
168 def printRealFooter(self):
169 """Print the "real" footer for the created file.
171 In the base class, this function is empty. All derived
172 classes should over-ride this function."""
173 return
176 def printPure(self):
177 """Conditionally define `PURE' function attribute.
179 Conditionally defines a preprocessor macro `PURE' that wraps
180 GCC's `pure' function attribute. The conditional code can be
181 easilly adapted to other compilers that support a similar
182 feature.
184 The name is also added to the file's undef_list.
186 self.undef_list.append("PURE")
187 print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
188 # define PURE __attribute__((pure))
189 # else
190 # define PURE
191 # endif"""
192 return
195 def printFastcall(self):
196 """Conditionally define `FASTCALL' function attribute.
198 Conditionally defines a preprocessor macro `FASTCALL' that
199 wraps GCC's `fastcall' function attribute. The conditional
200 code can be easilly adapted to other compilers that support a
201 similar feature.
203 The name is also added to the file's undef_list.
206 self.undef_list.append("FASTCALL")
207 print """# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
208 # define FASTCALL __attribute__((fastcall))
209 # else
210 # define FASTCALL
211 # endif"""
212 return
215 def printVisibility(self, S, s):
216 """Conditionally define visibility function attribute.
218 Conditionally defines a preprocessor macro name S that wraps
219 GCC's visibility function attribute. The visibility used is
220 the parameter s. The conditional code can be easilly adapted
221 to other compilers that support a similar feature.
223 The name is also added to the file's undef_list.
226 self.undef_list.append(S)
227 print """# if (defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) && defined(__ELF__))
228 # define %s __attribute__((visibility("%s")))
229 # else
230 # define %s
231 # endif""" % (S, s, S)
232 return
235 def printNoinline(self):
236 """Conditionally define `NOINLINE' function attribute.
238 Conditionally defines a preprocessor macro `NOINLINE' that
239 wraps GCC's `noinline' function attribute. The conditional
240 code can be easilly adapted to other compilers that support a
241 similar feature.
243 The name is also added to the file's undef_list.
246 self.undef_list.append("NOINLINE")
247 print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
248 # define NOINLINE __attribute__((noinline))
249 # else
250 # define NOINLINE
251 # endif"""
252 return
255 def real_function_name(element):
256 name = element.nsProp( "name", None )
257 alias = element.nsProp( "alias", None )
259 if alias:
260 return alias
261 else:
262 return name
265 def real_category_name(c):
266 if re.compile("[1-9][0-9]*[.][0-9]+").match(c):
267 return "GL_VERSION_" + c.replace(".", "_")
268 else:
269 return c
272 def classify_category(name, number):
273 """Based on the category name and number, select a numerical class for it.
275 Categories are divided into four classes numbered 0 through 3. The
276 classes are:
278 0. Core GL versions, sorted by version number.
279 1. ARB extensions, sorted by extension number.
280 2. Non-ARB extensions, sorted by extension number.
281 3. Un-numbered extensions, sorted by extension name.
284 try:
285 core_version = float(name)
286 except Exception,e:
287 core_version = 0.0
289 if core_version > 0.0:
290 cat_type = 0
291 key = name
292 elif name.startswith("GL_ARB_") or name.startswith("GLX_ARB_") or name.startswith("WGL_ARB_"):
293 cat_type = 1
294 key = int(number)
295 else:
296 if number != None:
297 cat_type = 2
298 key = int(number)
299 else:
300 cat_type = 3
301 key = name
304 return [cat_type, key]
307 def create_parameter_string(parameters, include_names):
308 """Create a parameter string from a list of gl_parameters."""
310 list = []
311 for p in parameters:
312 if p.is_padding:
313 continue
315 if include_names:
316 list.append( p.string() )
317 else:
318 list.append( p.type_string() )
320 if len(list) == 0: list = ["void"]
322 return string.join(list, ", ")
325 class gl_item:
326 def __init__(self, element, context):
327 self.context = context
328 self.name = element.nsProp( "name", None )
329 self.category = real_category_name( element.parent.nsProp( "name", None ) )
330 return
333 class gl_type( gl_item ):
334 def __init__(self, element, context):
335 gl_item.__init__(self, element, context)
336 self.size = int( element.nsProp( "size", None ), 0 )
338 te = typeexpr.type_expression( None )
339 tn = typeexpr.type_node()
340 tn.size = int( element.nsProp( "size", None ), 0 )
341 tn.integer = not is_attr_true( element, "float" )
342 tn.unsigned = is_attr_true( element, "unsigned" )
343 tn.name = "GL" + self.name
344 te.set_base_type_node( tn )
346 self.type_expr = te
347 return
350 def get_type_expression(self):
351 return self.type_expr
354 class gl_enum( gl_item ):
355 def __init__(self, element, context):
356 gl_item.__init__(self, element, context)
357 self.value = int( element.nsProp( "value", None ), 0 )
359 temp = element.nsProp( "count", None )
360 if not temp or temp == "?":
361 self.default_count = -1
362 else:
363 try:
364 c = int(temp)
365 except Exception,e:
366 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
368 self.default_count = c
370 return
373 def priority(self):
374 """Calculate a 'priority' for this enum name.
376 When an enum is looked up by number, there may be many
377 possible names, but only one is the 'prefered' name. The
378 priority is used to select which name is the 'best'.
380 Highest precedence is given to core GL name. ARB extension
381 names have the next highest, followed by EXT extension names.
382 Vendor extension names are the lowest.
385 if self.name.endswith( "_BIT" ):
386 bias = 1
387 else:
388 bias = 0
390 if self.category.startswith( "GL_VERSION_" ):
391 priority = 0
392 elif self.category.startswith( "GL_ARB_" ):
393 priority = 2
394 elif self.category.startswith( "GL_EXT_" ):
395 priority = 4
396 else:
397 priority = 6
399 return priority + bias
403 class gl_parameter:
404 def __init__(self, element, context):
405 self.name = element.nsProp( "name", None )
407 ts = element.nsProp( "type", None )
408 self.type_expr = typeexpr.type_expression( ts, context )
410 temp = element.nsProp( "variable_param", None )
411 if temp:
412 self.count_parameter_list = temp.split( ' ' )
413 else:
414 self.count_parameter_list = []
416 # The count tag can be either a numeric string or the name of
417 # a variable. If it is the name of a variable, the int(c)
418 # statement will throw an exception, and the except block will
419 # take over.
421 c = element.nsProp( "count", None )
422 try:
423 count = int(c)
424 self.count = count
425 self.counter = None
426 except Exception,e:
427 count = 1
428 self.count = 0
429 self.counter = c
431 self.count_scale = int(element.nsProp( "count_scale", None ))
433 elements = (count * self.count_scale)
434 if elements == 1:
435 elements = 0
437 #if ts == "GLdouble":
438 # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size())
439 # print '/* # elements = %u */' % (elements)
440 self.type_expr.set_elements( elements )
441 #if ts == "GLdouble":
442 # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size())
444 self.is_client_only = is_attr_true( element, 'client_only' )
445 self.is_counter = is_attr_true( element, 'counter' )
446 self.is_output = is_attr_true( element, 'output' )
449 # Pixel data has special parameters.
451 self.width = element.nsProp('img_width', None)
452 self.height = element.nsProp('img_height', None)
453 self.depth = element.nsProp('img_depth', None)
454 self.extent = element.nsProp('img_extent', None)
456 self.img_xoff = element.nsProp('img_xoff', None)
457 self.img_yoff = element.nsProp('img_yoff', None)
458 self.img_zoff = element.nsProp('img_zoff', None)
459 self.img_woff = element.nsProp('img_woff', None)
461 self.img_format = element.nsProp('img_format', None)
462 self.img_type = element.nsProp('img_type', None)
463 self.img_target = element.nsProp('img_target', None)
465 self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' )
466 self.img_null_flag = is_attr_true( element, 'img_null_flag' )
467 self.img_send_null = is_attr_true( element, 'img_send_null' )
469 self.is_padding = is_attr_true( element, 'padding' )
470 return
473 def compatible(self, other):
474 return 1
477 def is_array(self):
478 return self.is_pointer()
481 def is_pointer(self):
482 return self.type_expr.is_pointer()
485 def is_image(self):
486 if self.width:
487 return 1
488 else:
489 return 0
492 def is_variable_length(self):
493 return len(self.count_parameter_list) or self.counter
496 def is_64_bit(self):
497 count = self.type_expr.get_element_count()
498 if count:
499 if (self.size() / count) == 8:
500 return 1
501 else:
502 if self.size() == 8:
503 return 1
505 return 0
508 def string(self):
509 return self.type_expr.original_string + " " + self.name
512 def type_string(self):
513 return self.type_expr.original_string
516 def get_base_type_string(self):
517 return self.type_expr.get_base_name()
520 def get_dimensions(self):
521 if not self.width:
522 return [ 0, "0", "0", "0", "0" ]
524 dim = 1
525 w = self.width
526 h = "1"
527 d = "1"
528 e = "1"
530 if self.height:
531 dim = 2
532 h = self.height
534 if self.depth:
535 dim = 3
536 d = self.depth
538 if self.extent:
539 dim = 4
540 e = self.extent
542 return [ dim, w, h, d, e ]
545 def get_stack_size(self):
546 return self.type_expr.get_stack_size()
549 def size(self):
550 if self.is_image():
551 return 0
552 else:
553 return self.type_expr.get_element_size()
556 def get_element_count(self):
557 c = self.type_expr.get_element_count()
558 if c == 0:
559 return 1
561 return c
564 def size_string(self, use_parens = 1):
565 s = self.size()
566 if self.counter or self.count_parameter_list:
567 list = [ "compsize" ]
569 if self.counter and self.count_parameter_list:
570 list.append( self.counter )
571 elif self.counter:
572 list = [ self.counter ]
574 if s > 1:
575 list.append( str(s) )
577 if len(list) > 1 and use_parens :
578 return "(%s)" % (string.join(list, " * "))
579 else:
580 return string.join(list, " * ")
582 elif self.is_image():
583 return "compsize"
584 else:
585 return str(s)
588 def format_string(self):
589 if self.type_expr.original_string == "GLenum":
590 return "0x%x"
591 else:
592 return self.type_expr.format_string()
596 class gl_function( gl_item ):
597 def __init__(self, element, context):
598 self.context = context
599 self.name = None
601 self.entry_points = []
602 self.return_type = "void"
603 self.parameters = []
604 self.offset = -1
605 self.initialized = 0
606 self.images = []
608 self.assign_offset = 0
610 self.static_entry_points = []
612 # Track the parameter string (for the function prototype)
613 # for each entry-point. This is done because some functions
614 # change their prototype slightly when promoted from extension
615 # to ARB extension to core. glTexImage3DEXT and glTexImage3D
616 # are good examples of this. Scripts that need to generate
617 # code for these differing aliases need to real prototype
618 # for each entry-point. Otherwise, they may generate code
619 # that won't compile.
621 self.parameter_strings = {}
623 self.process_element( element )
625 return
628 def process_element(self, element):
629 name = element.nsProp( "name", None )
630 alias = element.nsProp( "alias", None )
632 # if is_attr_true(element, "static_dispatch"):
633 # AROS version requires all entry points to be available in library base
634 self.static_entry_points.append( name )
636 self.entry_points.append( name )
637 if alias:
638 true_name = alias
639 else:
640 true_name = name
642 # Only try to set the offset when a non-alias
643 # entry-point is being processes.
645 offset = element.nsProp( "offset", None )
646 if offset:
647 try:
648 o = int( offset )
649 self.offset = o
650 except Exception, e:
651 self.offset = -1
652 if offset == "assign":
653 self.assign_offset = 1
656 if not self.name:
657 self.name = true_name
658 elif self.name != true_name:
659 raise RuntimeError("Function true name redefined. Was %s, now %s." % (self.name, true_name))
662 # There are two possible cases. The first time an entry-point
663 # with data is seen, self.initialized will be 0. On that
664 # pass, we just fill in the data. The next time an
665 # entry-point with data is seen, self.initialized will be 1.
666 # On that pass we have to make that the new values match the
667 # valuse from the previous entry-point.
669 parameters = []
670 return_type = "void"
671 child = element.children
672 while child:
673 if child.type == "element":
674 if child.name == "return":
675 return_type = child.nsProp( "type", None )
676 elif child.name == "param":
677 param = self.context.factory.create_item( "parameter", child, self.context)
678 parameters.append( param )
680 child = child.next
683 if self.initialized:
684 if self.return_type != return_type:
685 raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name, self.return_type, return_type))
687 if len(parameters) != len(self.parameters):
688 raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name, len(self.parameters), len(parameters)))
690 for j in range(0, len(parameters)):
691 p1 = parameters[j]
692 p2 = self.parameters[j]
693 if not p1.compatible( p2 ):
694 raise RuntimeError( 'Parameter type mismatch in %s. "%s" was "%s", now "%s".' % (name, p2.name, p2.type_expr.original_string, p1.type_expr.original_string))
697 if true_name == name or not self.initialized:
698 self.return_type = return_type
699 self.parameters = parameters
701 for param in self.parameters:
702 if param.is_image():
703 self.images.append( param )
705 if element.children:
706 self.initialized = 1
707 self.parameter_strings[name] = create_parameter_string(parameters, 1)
708 else:
709 self.parameter_strings[name] = None
711 return
714 def get_images(self):
715 """Return potentially empty list of input images."""
716 return self.images
719 def parameterIterator(self):
720 return self.parameters.__iter__();
723 def get_parameter_string(self, entrypoint = None):
724 if entrypoint:
725 s = self.parameter_strings[ entrypoint ]
726 if s:
727 return s
729 return create_parameter_string( self.parameters, 1 )
731 def get_called_parameter_string(self):
732 p_string = ""
733 comma = ""
735 for p in self.parameterIterator():
736 p_string = p_string + comma + p.name
737 comma = ", "
739 return p_string
742 def is_abi(self):
743 return (self.offset >= 0 and not self.assign_offset)
745 def is_static_entry_point(self, name):
746 return name in self.static_entry_points
748 def dispatch_name(self):
749 if self.name in self.static_entry_points:
750 return self.name
751 else:
752 return "_dispatch_stub_%u" % (self.offset)
754 def static_name(self, name):
755 if name in self.static_entry_points:
756 return name
757 else:
758 return "_dispatch_stub_%u" % (self.offset)
761 class gl_item_factory:
762 """Factory to create objects derived from gl_item."""
764 def create_item(self, item_name, element, context):
765 if item_name == "function":
766 return gl_function(element, context)
767 if item_name == "type":
768 return gl_type(element, context)
769 elif item_name == "enum":
770 return gl_enum(element, context)
771 elif item_name == "parameter":
772 return gl_parameter(element, context)
773 elif item_name == "api":
774 return gl_api(self)
775 else:
776 return None
779 class gl_api:
780 def __init__(self, factory):
781 self.functions_by_name = {}
782 self.enums_by_name = {}
783 self.types_by_name = {}
785 self.category_dict = {}
786 self.categories = [{}, {}, {}, {}]
788 self.factory = factory
790 self.next_offset = 0
792 typeexpr.create_initial_types()
793 return
796 def process_element(self, doc):
797 element = doc.children
798 while element.type != "element" or element.name != "OpenGLAPI":
799 element = element.next
801 if element:
802 self.process_OpenGLAPI(element)
803 return
806 def process_OpenGLAPI(self, element):
807 child = element.children
808 while child:
809 if child.type == "element":
810 if child.name == "category":
811 self.process_category( child )
812 elif child.name == "OpenGLAPI":
813 self.process_OpenGLAPI( child )
815 child = child.next
817 return
820 def process_category(self, cat):
821 cat_name = cat.nsProp( "name", None )
822 cat_number = cat.nsProp( "number", None )
824 [cat_type, key] = classify_category(cat_name, cat_number)
825 self.categories[cat_type][key] = [cat_name, cat_number]
827 child = cat.children
828 while child:
829 if child.type == "element":
830 if child.name == "function":
831 func_name = real_function_name( child )
833 temp_name = child.nsProp( "name", None )
834 self.category_dict[ temp_name ] = [cat_name, cat_number]
836 if self.functions_by_name.has_key( func_name ):
837 func = self.functions_by_name[ func_name ]
838 func.process_element( child )
839 else:
840 func = self.factory.create_item( "function", child, self )
841 self.functions_by_name[ func_name ] = func
843 if func.offset >= self.next_offset:
844 self.next_offset = func.offset + 1
847 elif child.name == "enum":
848 enum = self.factory.create_item( "enum", child, self )
849 self.enums_by_name[ enum.name ] = enum
850 elif child.name == "type":
851 t = self.factory.create_item( "type", child, self )
852 self.types_by_name[ "GL" + t.name ] = t
855 child = child.next
857 return
860 def functionIterateByCategory(self, cat = None):
861 """Iterate over functions by category.
863 If cat is None, all known functions are iterated in category
864 order. See classify_category for details of the ordering.
865 Within a category, functions are sorted by name. If cat is
866 not None, then only functions in that category are iterated.
868 lists = [{}, {}, {}, {}]
870 for func in self.functionIterateAll():
871 [cat_name, cat_number] = self.category_dict[func.name]
873 if (cat == None) or (cat == cat_name):
874 [func_cat_type, key] = classify_category(cat_name, cat_number)
876 if not lists[func_cat_type].has_key(key):
877 lists[func_cat_type][key] = {}
879 lists[func_cat_type][key][func.name] = func
882 functions = []
883 for func_cat_type in range(0,4):
884 keys = lists[func_cat_type].keys()
885 keys.sort()
887 for key in keys:
888 names = lists[func_cat_type][key].keys()
889 names.sort()
891 for name in names:
892 functions.append(lists[func_cat_type][key][name])
894 return functions.__iter__()
897 def functionIterateByOffset(self):
898 max_offset = -1
899 for func in self.functions_by_name.itervalues():
900 if func.offset > max_offset:
901 max_offset = func.offset
904 temp = [None for i in range(0, max_offset + 1)]
905 for func in self.functions_by_name.itervalues():
906 if func.offset != -1:
907 temp[ func.offset ] = func
910 list = []
911 for i in range(0, max_offset + 1):
912 if temp[i]:
913 list.append(temp[i])
915 return list.__iter__();
918 def functionIterateAll(self):
919 return self.functions_by_name.itervalues()
922 def enumIterateByName(self):
923 keys = self.enums_by_name.keys()
924 keys.sort()
926 list = []
927 for enum in keys:
928 list.append( self.enums_by_name[ enum ] )
930 return list.__iter__()
933 def categoryIterate(self):
934 """Iterate over categories.
936 Iterate over all known categories in the order specified by
937 classify_category. Each iterated value is a tuple of the
938 name and number (which may be None) of the category.
941 list = []
942 for cat_type in range(0,4):
943 keys = self.categories[cat_type].keys()
944 keys.sort()
946 for key in keys:
947 list.append(self.categories[cat_type][key])
949 return list.__iter__()
952 def get_category_for_name( self, name ):
953 if self.category_dict.has_key(name):
954 return self.category_dict[name]
955 else:
956 return ["<unknown category>", None]
959 def typeIterate(self):
960 return self.types_by_name.itervalues()
963 def find_type( self, type_name ):
964 if type_name in self.types_by_name:
965 return self.types_by_name[ type_name ].type_expr
966 else:
967 print "Unable to find base type matching \"%s\"." % (type_name)
968 return None