3 # Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>
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:
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
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
24 Minimal apiutil.py interface for use by es_generator.py.
36 def _ParseXML(filename
, apiname
):
39 'GLfloat': [ 'GLdouble' ],
40 'GLclampf': [ 'GLclampd' ],
41 'GLubyte': [ 'GLfloat', 'GLdouble' ],
42 'GLint': [ 'GLfloat', 'GLdouble' ],
43 'GLfixed': [ 'GLfloat', 'GLdouble' ],
44 'GLclampx': [ 'GLclampf', 'GLclampd' ],
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
)
59 for func
in api
.functions
:
60 alias
, need_conv
= impl
.match(func
, conversions
)
62 # external functions are manually dispatched
63 if not func
.is_external
:
64 print >>sys
.stderr
, "Error: unable to dispatch %s" % func
.name
68 __functions
[func
.name
] = func
69 __aliases
[func
.name
] = (alias
, need_conv
)
72 def AllSpecials(notused
=None):
73 """Return a list of all external functions in the API."""
77 for func
in api
.functions
:
79 specials
.append(func
.name
)
84 def GetAllFunctions(filename
, api
):
85 """Return sorted list of all functions in the API."""
87 _ParseXML(filename
, api
)
91 for func
in api
.functions
:
92 names
.append(func
.name
)
97 def ReturnType(funcname
):
98 """Return the C return type of named function."""
99 func
= __functions
[funcname
]
100 return func
.return_type
103 def Properties(funcname
):
104 """Return list of properties of the named GL function."""
105 func
= __functions
[funcname
]
106 return [func
.direction
]
109 def _ValidValues(func
, param
):
110 """Return the valid values of a parameter."""
112 switch
= func
.checker
.switches
.get(param
.name
, [])
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))
120 items
= desc
.checker
.switches
.items()
122 print >>sys
.stderr
, "%s: more than one parameter depend on %s" % \
123 (func
.name
, desc
.name
)
124 dep_name
, dep_switch
= items
[0]
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
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
))
139 def _Conversion(func
, src_param
):
140 """Return the destination type of the conversion, or None."""
141 alias
, need_conv
= __aliases
[func
.name
]
143 dst_param
= alias
.get_param(src_param
.name
)
144 if src_param
.type == dst_param
.type:
147 return (None, "none")
149 converts
= { True: 0, False: 0 }
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
):
157 for desc
in func
.checker
.flatten(src_param
.name
):
158 converts
[desc
.convert
] += 1
159 if converts
[True] and converts
[False]:
162 # it should be "never", "sometimes", and "always"...
171 return (dst_param
.base_type(), conversion
)
174 def _MaxVecSize(func
, param
):
175 """Return the largest possible size of a vector."""
176 if not param
.is_vector
:
181 # need to look at all descriptions
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
)
189 need_conv
= __aliases
[func
.name
][1]
191 print >>sys
.stderr
, \
192 "Error: unable to dicide the max size of %s in %s" % \
193 (param
.name
, func
.name
)
197 def _ParameterTuple(func
, param
):
198 """Return a parameter tuple.
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
205 [5] -- how often does the conversion happen
208 vec_size
= _MaxVecSize(func
, param
)
209 dst_type
, conversion
= _Conversion(func
, param
)
210 valid_values
= _ValidValues(func
, param
)
212 return (param
.name
, param
.type, vec_size
, dst_type
, valid_values
, conversion
)
215 def Parameters(funcname
):
216 """Return list of tuples of function parameters."""
217 func
= __functions
[funcname
]
219 for param
in func
.params
:
220 params
.append(_ParameterTuple(func
, param
))
225 def FunctionPrefix(funcname
):
226 """Return function specific prefix."""
227 func
= __functions
[funcname
]
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
:
240 def MakeDeclarationString(params
):
241 """Return a C-style parameter declaration string."""
244 sep
= "" if p
[1].endswith("*") else " "
245 string
.append("%s%s%s" % (p
[1], sep
, p
[0]))
248 return ", ".join(string
)
251 def AliasPrefix(funcname
):
252 """Return the prefix of the function the named function is an alias of."""
253 alias
= __aliases
[funcname
][0]
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
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
269 def Categories(funcname
):
270 """Return all the categories of the named GL function."""