Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #!/usr/bin/python
  2. #
  3. # Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>
  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. Minimal apiutil.py interface for use by es_generator.py.
  25. """
  26.  
  27. import sys
  28. import libxml2
  29.  
  30. import APIspec
  31.  
  32. __spec = {}
  33. __functions = {}
  34. __aliases = {}
  35.  
  36. def _ParseXML(filename, apiname):
  37.     conversions = {
  38.         # from           to
  39.         'GLfloat':  [ 'GLdouble' ],
  40.         'GLclampf': [ 'GLclampd' ],
  41.         'GLubyte':  [ 'GLfloat', 'GLdouble' ],
  42.         'GLint':    [ 'GLfloat', 'GLdouble' ],
  43.         'GLfixed':  [ 'GLfloat', 'GLdouble' ],
  44.         'GLclampx': [ 'GLclampf', 'GLclampd' ],
  45.     }
  46.  
  47.     doc = libxml2.readFile(filename, None,
  48.             libxml2.XML_PARSE_DTDLOAD +
  49.             libxml2.XML_PARSE_DTDVALID +
  50.             libxml2.XML_PARSE_NOBLANKS)
  51.     spec = APIspec.Spec(doc)
  52.     impl = spec.get_impl()
  53.     api = spec.get_api(apiname)
  54.     doc.freeDoc()
  55.  
  56.     __spec["impl"] = impl
  57.     __spec["api"] = api
  58.  
  59.     for func in api.functions:
  60.         alias, need_conv = impl.match(func, conversions)
  61.         if not alias:
  62.             # external functions are manually dispatched
  63.             if not func.is_external:
  64.                 print >>sys.stderr, "Error: unable to dispatch %s" % func.name
  65.             alias = func
  66.             need_conv = False
  67.  
  68.         __functions[func.name] = func
  69.         __aliases[func.name] = (alias, need_conv)
  70.  
  71.  
  72. def AllSpecials(notused=None):
  73.     """Return a list of all external functions in the API."""
  74.     api = __spec["api"]
  75.  
  76.     specials = []
  77.     for func in api.functions:
  78.         if func.is_external:
  79.             specials.append(func.name)
  80.  
  81.     return specials
  82.  
  83.  
  84. def GetAllFunctions(filename, api):
  85.     """Return sorted list of all functions in the API."""
  86.     if not __spec:
  87.         _ParseXML(filename, api)
  88.  
  89.     api = __spec["api"]
  90.     names = []
  91.     for func in api.functions:
  92.         names.append(func.name)
  93.     names.sort()
  94.     return names
  95.  
  96.  
  97. def ReturnType(funcname):
  98.     """Return the C return type of named function."""
  99.     func = __functions[funcname]
  100.     return func.return_type
  101.  
  102.  
  103. def Properties(funcname):
  104.     """Return list of properties of the named GL function."""
  105.     func = __functions[funcname]
  106.     return [func.direction]
  107.  
  108.  
  109. def _ValidValues(func, param):
  110.     """Return the valid values of a parameter."""
  111.     valid_values = []
  112.     switch = func.checker.switches.get(param.name, [])
  113.     for desc in switch:
  114.         # no dependent vector
  115.         if not desc.checker.switches:
  116.             for val in desc.values:
  117.                 valid_values.append((val, None, None, [], desc.error, None))
  118.             continue
  119.  
  120.         items = desc.checker.switches.items()
  121.         if len(items) > 1:
  122.             print >>sys.stderr, "%s: more than one parameter depend on %s" % \
  123.                     (func.name, desc.name)
  124.         dep_name, dep_switch = items[0]
  125.  
  126.         for dep_desc in dep_switch:
  127.             if dep_desc.index >= 0 and dep_desc.index != 0:
  128.                 print >>sys.stderr, "%s: not first element of a vector" % func.name
  129.             if dep_desc.checker.switches:
  130.                 print >>sys.stderr, "%s: deep nested dependence" % func.name
  131.  
  132.             convert = None if dep_desc.convert else "noconvert"
  133.             for val in desc.values:
  134.                 valid_values.append((val, dep_desc.size_str, dep_desc.name,
  135.                                      dep_desc.values, dep_desc.error, convert))
  136.     return valid_values
  137.  
  138.  
  139. def _Conversion(func, src_param):
  140.     """Return the destination type of the conversion, or None."""
  141.     alias, need_conv = __aliases[func.name]
  142.     if need_conv:
  143.         dst_param = alias.get_param(src_param.name)
  144.         if src_param.type == dst_param.type:
  145.             need_conv = False
  146.     if not need_conv:
  147.         return (None, "none")
  148.  
  149.     converts = { True: 0, False: 0 }
  150.  
  151.     # In Fogx, for example,  pname may be GL_FOG_DENSITY/GL_FOG_START/GL_FOG_END
  152.     # or GL_FOG_MODE.  In the former three cases, param is not checked and the
  153.     # default is to convert.
  154.     if not func.checker.always_check(src_param.name):
  155.         converts[True] += 1
  156.  
  157.     for desc in func.checker.flatten(src_param.name):
  158.         converts[desc.convert] += 1
  159.         if converts[True] and converts[False]:
  160.             break
  161.  
  162.     # it should be "never", "sometimes", and "always"...
  163.     if converts[False]:
  164.         if converts[True]:
  165.             conversion = "some"
  166.         else:
  167.             conversion = "none"
  168.     else:
  169.         conversion = "all"
  170.  
  171.     return (dst_param.base_type(), conversion)
  172.  
  173.  
  174. def _MaxVecSize(func, param):
  175.     """Return the largest possible size of a vector."""
  176.     if not param.is_vector:
  177.         return 0
  178.     if param.size:
  179.         return param.size
  180.  
  181.     # need to look at all descriptions
  182.     size = 0
  183.     for desc in func.checker.flatten(param.name):
  184.         if desc.size_str and desc.size_str.isdigit():
  185.             s = int(desc.size_str)
  186.             if s > size:
  187.                 size = s
  188.     if not size:
  189.         need_conv = __aliases[func.name][1]
  190.         if need_conv:
  191.             print >>sys.stderr, \
  192.                     "Error: unable to dicide the max size of %s in %s" % \
  193.                     (param.name, func.name)
  194.     return size
  195.  
  196.  
  197. def _ParameterTuple(func, param):
  198.     """Return a parameter tuple.
  199.  
  200.    [0] -- parameter name
  201.    [1] -- parameter type
  202.    [2] -- max vector size or 0
  203.    [3] -- dest type the parameter converts to, or None
  204.    [4] -- valid values
  205.    [5] -- how often does the conversion happen
  206.  
  207.    """
  208.     vec_size = _MaxVecSize(func, param)
  209.     dst_type, conversion = _Conversion(func, param)
  210.     valid_values = _ValidValues(func, param)
  211.  
  212.     return (param.name, param.type, vec_size, dst_type, valid_values, conversion)
  213.  
  214.  
  215. def Parameters(funcname):
  216.     """Return list of tuples of function parameters."""
  217.     func = __functions[funcname]
  218.     params = []
  219.     for param in func.params:
  220.         params.append(_ParameterTuple(func, param))
  221.  
  222.     return params
  223.  
  224.  
  225. def FunctionPrefix(funcname):
  226.     """Return function specific prefix."""
  227.     func = __functions[funcname]
  228.  
  229.     return func.prefix
  230.  
  231.  
  232. def FindParamIndex(params, paramname):
  233.     """Find the index of a named parameter."""
  234.     for i in xrange(len(params)):
  235.         if params[i][0] == paramname:
  236.             return i
  237.     return None
  238.  
  239.  
  240. def MakeDeclarationString(params):
  241.     """Return a C-style parameter declaration string."""
  242.     string = []
  243.     for p in params:
  244.         sep = "" if p[1].endswith("*") else " "
  245.         string.append("%s%s%s" % (p[1], sep, p[0]))
  246.     if not string:
  247.         return "void"
  248.     return ", ".join(string)
  249.  
  250.  
  251. def AliasPrefix(funcname):
  252.     """Return the prefix of the function the named function is an alias of."""
  253.     alias = __aliases[funcname][0]
  254.     return alias.prefix
  255.  
  256.  
  257. def Alias(funcname):
  258.     """Return the name of the function the named function is an alias of."""
  259.     alias, need_conv = __aliases[funcname]
  260.     return alias.name if not need_conv else None
  261.  
  262.  
  263. def ConversionFunction(funcname):
  264.     """Return the name of the function the named function converts to."""
  265.     alias, need_conv = __aliases[funcname]
  266.     return alias.name if need_conv else None
  267.  
  268.  
  269. def Categories(funcname):
  270.     """Return all the categories of the named GL function."""
  271.     api = __spec["api"]
  272.     return [api.name]
  273.