Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / mapi / glapi / gen / gl_enums.py
index 0caa01030fade818e0f752583457bfd729a89061..041c2f8ddb8ef4649c9d1e41e610a48c11bfa570 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/python2
 # -*- Mode: Python; py-indent-offset: 8 -*-
 
-# (C) Copyright Zack Rusin 2005
-# All Rights Reserved.
+# (C) Copyright Zack Rusin 2005. All Rights Reserved.
+# Copyright (C) 2015 Intel Corporation
 # 
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
 # Authors:
 #    Zack Rusin <zack@kde.org>
 
+import argparse
+
 import license
 import gl_XML
 import sys, getopt
 
 class PrintGlEnums(gl_XML.gl_print_base):
 
-       def __init__(self):
-               gl_XML.gl_print_base.__init__(self)
+    def __init__(self):
+        gl_XML.gl_print_base.__init__(self)
 
-               self.name = "gl_enums.py (from Mesa)"
-               self.license = license.bsd_license_template % ( \
+        self.name = "gl_enums.py (from Mesa)"
+        self.license = license.bsd_license_template % ( \
 """Copyright (C) 1999-2005 Brian Paul All Rights Reserved.""", "BRIAN PAUL")
-               self.enum_table = {}
-
-
-       def printRealHeader(self):
-               print '#include "main/glheader.h"'
-               print '#include "main/mfeatures.h"'
-               print '#include "main/enums.h"'
-               print '#include "main/imports.h"'
-               print ''
-               print 'typedef struct {'
-               print '   size_t offset;'
-               print '   int n;'
-               print '} enum_elt;'
-               print ''
-               return
-
-       def print_code(self):
-               print """
+        self.enum_table = {}
+
+
+    def printRealHeader(self):
+        print '#include "main/glheader.h"'
+        print '#include "main/enums.h"'
+        print '#include "main/imports.h"'
+        print '#include "main/mtypes.h"'
+        print ''
+        print 'typedef struct PACKED {'
+        print '   uint16_t offset;'
+        print '   int n;'
+        print '} enum_elt;'
+        print ''
+        return
+
+    def print_code(self):
+        print """
 typedef int (*cfunc)(const void *, const void *);
 
 /**
- * Compare a key name to an element in the \c all_enums array.
+ * Compare a key enum value to an element in the \c enum_string_table_offsets array.
  *
  * \c bsearch always passes the key as the first parameter and the pointer
  * to the array element as the second parameter.  We can elimiate some
  * extra work by taking advantage of that fact.
  *
  * \param a  Pointer to the desired enum name.
- * \param b  Pointer to an element of the \c all_enums array.
+ * \param b  Pointer into the \c enum_string_table_offsets array.
  */
-static int compar_name( const char *a, const enum_elt *b )
+static int compar_nr( const int *a, enum_elt *b )
 {
-   return strcmp( a, & enum_string_table[ b->offset ] );
-}
-
-/**
- * Compare a key enum value to an element in the \c all_enums array.
- *
- * \c bsearch always passes the key as the first parameter and the pointer
- * to the array element as the second parameter.  We can elimiate some
- * extra work by taking advantage of that fact.
- *
- * \param a  Pointer to the desired enum name.
- * \param b  Pointer to an index into the \c all_enums array.
- */
-static int compar_nr( const int *a, const unsigned *b )
-{
-   return a[0] - all_enums[*b].n;
+   return a[0] - b->n;
 }
 
 
 static char token_tmp[20];
 
-const char *_mesa_lookup_enum_by_nr( int nr )
+const char *_mesa_enum_to_string( int nr )
 {
-   unsigned * i;
+   enum_elt *elt;
+
+   STATIC_ASSERT(sizeof(enum_string_table) < (1 << 16));
 
-   i = (unsigned *) _mesa_bsearch(& nr, reduced_enums,
-                                  Elements(reduced_enums),
-                                  sizeof(reduced_enums[0]),
-                                  (cfunc) compar_nr);
+   elt = bsearch(& nr, enum_string_table_offsets,
+                 ARRAY_SIZE(enum_string_table_offsets),
+                 sizeof(enum_string_table_offsets[0]),
+                 (cfunc) compar_nr);
 
-   if ( i != NULL ) {
-      return & enum_string_table[ all_enums[ *i ].offset ];
+   if (elt != NULL) {
+      return &enum_string_table[elt->offset];
    }
    else {
       /* this is not re-entrant safe, no big deal here */
@@ -111,138 +100,125 @@ const char *_mesa_lookup_enum_by_nr( int nr )
    }
 }
 
+/**
+ * Primitive names
+ */
+static const char *prim_names[PRIM_MAX+3] = {
+   "GL_POINTS",
+   "GL_LINES",
+   "GL_LINE_LOOP",
+   "GL_LINE_STRIP",
+   "GL_TRIANGLES",
+   "GL_TRIANGLE_STRIP",
+   "GL_TRIANGLE_FAN",
+   "GL_QUADS",
+   "GL_QUAD_STRIP",
+   "GL_POLYGON",
+   "GL_LINES_ADJACENCY",
+   "GL_LINE_STRIP_ADJACENCY",
+   "GL_TRIANGLES_ADJACENCY",
+   "GL_TRIANGLE_STRIP_ADJACENCY",
+   "GL_PATCHES",
+   "outside begin/end",
+   "unknown state"
+};
+
+
 /* Get the name of an enum given that it is a primitive type.  Avoids
  * GL_FALSE/GL_POINTS ambiguity and others.
  */
-const char *_mesa_lookup_prim_by_nr( int nr )
+const char *
+_mesa_lookup_prim_by_nr(GLuint nr)
 {
-   switch (nr) {
-   case GL_POINTS: return "GL_POINTS";
-   case GL_LINES: return "GL_LINES";
-   case GL_LINE_STRIP: return "GL_LINE_STRIP";
-   case GL_LINE_LOOP: return "GL_LINE_LOOP";
-   case GL_TRIANGLES: return "GL_TRIANGLES";
-   case GL_TRIANGLE_STRIP: return "GL_TRIANGLE_STRIP";
-   case GL_TRIANGLE_FAN: return "GL_TRIANGLE_FAN";
-   case GL_QUADS: return "GL_QUADS";
-   case GL_QUAD_STRIP: return "GL_QUAD_STRIP";
-   case GL_POLYGON: return "GL_POLYGON";
-   case GL_POLYGON+1: return "OUTSIDE_BEGIN_END";
-   default: return "<invalid>";
-   }
+   if (nr < ARRAY_SIZE(prim_names))
+      return prim_names[nr];
+   else
+      return "invalid mode";
 }
 
 
-
-int _mesa_lookup_enum_by_name( const char *symbol )
-{
-   enum_elt * f = NULL;
-
-   if ( symbol != NULL ) {
-      f = (enum_elt *) _mesa_bsearch(symbol, all_enums,
-                                     Elements(all_enums),
-                                     sizeof( enum_elt ),
-                                     (cfunc) compar_name);
-   }
-
-   return (f != NULL) ? f->n : -1;
-}
-
 """
-               return
-
+        return
 
-       def printBody(self, api_list):
-               self.enum_table = {}
-               for api in api_list:
-                       self.process_enums( api )
 
-               keys = self.enum_table.keys()
-               keys.sort()
+    def printBody(self, api_list):
+        self.enum_table = {}
+        for api in api_list:
+            self.process_enums( api )
 
-               name_table = []
-               enum_table = {}
+        enum_table = []
 
-               for enum in keys:
-                       low_pri = 9
-                       for [name, pri] in self.enum_table[ enum ]:
-                               name_table.append( [name, enum] )
+        for enum in sorted(self.enum_table.keys()):
+            low_pri = 9
+            best_name = ''
+            for [name, pri] in self.enum_table[ enum ]:
+                if pri < low_pri:
+                    low_pri = pri
+                    best_name = name
 
-                               if pri < low_pri:
-                                       low_pri = pri
-                                       enum_table[enum] = name
-                                               
+            enum_table.append((enum, best_name))
 
-               name_table.sort()
+        string_offsets = {}
+        i = 0;
+        print '#if defined(__GNUC__)'
+        print '# define LONGSTRING __extension__'
+        print '#else'
+        print '# define LONGSTRING'
+        print '#endif'
+        print ''
+        print 'LONGSTRING static const char enum_string_table[] = '
+        for enum, name in enum_table:
+            print '   "%s\\0"' % (name)
+            string_offsets[ enum ] = i
+            i += len(name) + 1
 
-               string_offsets = {}
-               i = 0;
-               print 'LONGSTRING static const char enum_string_table[] = '
-               for [name, enum] in name_table:
-                       print '   "%s\\0"' % (name)
-                       string_offsets[ name ] = i
-                       i += len(name) + 1
+        print '   ;'
+        print ''
 
-               print '   ;'
-               print ''
 
+        print 'static const enum_elt enum_string_table_offsets[%u] =' % (len(enum_table))
+        print '{'
+        for enum, name in enum_table:
+            print '   { %5u, 0x%08X }, /* %s */' % (string_offsets[enum], enum, name)
+        print '};'
+        print ''
 
-               print 'static const enum_elt all_enums[%u] =' % (len(name_table))
-               print '{'
-               for [name, enum] in name_table:
-                       print '   { %5u, 0x%08X }, /* %s */' % (string_offsets[name], enum, name)
-               print '};'
-               print ''
+        self.print_code()
+        return
 
-               print 'static const unsigned reduced_enums[%u] =' % (len(keys))
-               print '{'
-               for enum in keys:
-                       name = enum_table[ enum ]
-                       if [name, enum] not in name_table:
-                               print '      /* Error! %s, 0x%04x */ 0,' % (name, enum)
-                       else:
-                               i = name_table.index( [name, enum] )
 
-                               print '      %4u, /* %s */' % (i, name)
-               print '};'
+    def process_enums(self, api):
+        for obj in api.enumIterateByName():
+            if obj.value not in self.enum_table:
+                self.enum_table[ obj.value ] = []
 
 
-               self.print_code()
-               return
+            enum = self.enum_table[ obj.value ]
+            name = "GL_" + obj.name
+            priority = obj.priority()
+            already_in = False;
+            for n, p in enum:
+                if n == name:
+                    already_in = True
+            if not already_in:
+                enum.append( [name, priority] )
 
 
-       def process_enums(self, api):
-               for obj in api.enumIterateByName():
-                       if obj.value not in self.enum_table:
-                               self.enum_table[ obj.value ] = []
+def _parser():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-f', '--input_file',
+                        required=True,
+                        help="Choose an xml file to parse.")
+    return parser.parse_args()
 
 
-                       enum = self.enum_table[ obj.value ]
-                       name = "GL_" + obj.name
-                       priority = obj.priority()
-                       already_in = False;
-                       for n, p in enum:
-                               if n == name:
-                                       already_in = True
-                       if not already_in:
-                               enum.append( [name, priority] )
+def main():
+    args = _parser()
+    api_list = [gl_XML.parse_GL_API(args.input_file)]
 
+    printer = PrintGlEnums()
+    printer.Print(api_list)
 
-def show_usage():
-       print "Usage: %s [-f input_file_name]" % sys.argv[0]
-       sys.exit(1)
 
 if __name__ == '__main__':
-       try:
-               (args, trail) = getopt.getopt(sys.argv[1:], "f:")
-       except Exception,e:
-               show_usage()
-
-       api_list = []
-       for (arg,val) in args:
-               if arg == "-f":
-                       api = gl_XML.parse_GL_API( val )
-                       api_list.append(api);
-
-       printer = PrintGlEnums()
-       printer.Print( api_list )
+    main()