mapi: Silence many "warning: unused parameter"
[mesa.git] / src / mapi / mapi / mapi_abi.py
1 #!/usr/bin/env python
2
3 # Mesa 3-D graphics library
4 # Version: 7.9
5 #
6 # Copyright (C) 2010 LunarG Inc.
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the "Software"),
10 # to deal in the Software without restriction, including without limitation
11 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 # and/or sell copies of the Software, and to permit persons to whom the
13 # Software is furnished to do so, subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 # DEALINGS IN THE SOFTWARE.
25 #
26 # Authors:
27 # Chia-I Wu <olv@lunarg.com>
28
29 import sys
30 # make it possible to import glapi
31 import os
32 GLAPI = "./%s/../glapi/gen" % (os.path.dirname(sys.argv[0]))
33 sys.path.append(GLAPI)
34
35 import re
36 from optparse import OptionParser
37
38 # number of dynamic entries
39 ABI_NUM_DYNAMIC_ENTRIES = 256
40
41 class ABIEntry(object):
42 """Represent an ABI entry."""
43
44 _match_c_param = re.compile(
45 '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
46
47 def __init__(self, cols, attrs):
48 self._parse(cols)
49
50 self.slot = attrs['slot']
51 self.hidden = attrs['hidden']
52 self.alias = attrs['alias']
53 self.handcode = attrs['handcode']
54
55 def c_prototype(self):
56 return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
57
58 def c_return(self):
59 ret = self.ret
60 if not ret:
61 ret = 'void'
62
63 return ret
64
65 def c_params(self):
66 """Return the parameter list used in the entry prototype."""
67 c_params = []
68 for t, n, a in self.params:
69 sep = '' if t.endswith('*') else ' '
70 arr = '[%d]' % a if a else ''
71 c_params.append(t + sep + n + arr)
72 if not c_params:
73 c_params.append('void')
74
75 return ", ".join(c_params)
76
77 def c_args(self):
78 """Return the argument list used in the entry invocation."""
79 c_args = []
80 for t, n, a in self.params:
81 c_args.append(n)
82
83 return ", ".join(c_args)
84
85 def _parse(self, cols):
86 ret = cols.pop(0)
87 if ret == 'void':
88 ret = None
89
90 name = cols.pop(0)
91
92 params = []
93 if not cols:
94 raise Exception(cols)
95 elif len(cols) == 1 and cols[0] == 'void':
96 pass
97 else:
98 for val in cols:
99 params.append(self._parse_param(val))
100
101 self.ret = ret
102 self.name = name
103 self.params = params
104
105 def _parse_param(self, c_param):
106 m = self._match_c_param.match(c_param)
107 if not m:
108 raise Exception('unrecognized param ' + c_param)
109
110 c_type = m.group('type').strip()
111 c_name = m.group('name')
112 c_array = m.group('array')
113 c_array = int(c_array) if c_array else 0
114
115 return (c_type, c_name, c_array)
116
117 def __str__(self):
118 return self.c_prototype()
119
120 def __cmp__(self, other):
121 # compare slot, alias, and then name
122 res = cmp(self.slot, other.slot)
123 if not res:
124 if not self.alias:
125 res = -1
126 elif not other.alias:
127 res = 1
128
129 if not res:
130 res = cmp(self.name, other.name)
131
132 return res
133
134 def abi_parse_xml(xml):
135 """Parse a GLAPI XML file for ABI entries."""
136 import gl_XML, glX_XML
137
138 api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
139
140 entry_dict = {}
141 for func in api.functionIterateByOffset():
142 # make sure func.name appear first
143 entry_points = func.entry_points[:]
144 entry_points.remove(func.name)
145 entry_points.insert(0, func.name)
146
147 for name in entry_points:
148 attrs = {
149 'slot': func.offset,
150 'hidden': not func.is_static_entry_point(name),
151 'alias': None if name == func.name else func.name,
152 'handcode': bool(func.has_different_protocol(name)),
153 }
154
155 # post-process attrs
156 if attrs['alias']:
157 try:
158 alias = entry_dict[attrs['alias']]
159 except KeyError:
160 raise Exception('failed to alias %s' % attrs['alias'])
161 if alias.alias:
162 raise Exception('recursive alias %s' % ent.name)
163 attrs['alias'] = alias
164 if attrs['handcode']:
165 attrs['handcode'] = func.static_glx_name(name)
166 else:
167 attrs['handcode'] = None
168
169 if entry_dict.has_key(name):
170 raise Exception('%s is duplicated' % (name))
171
172 cols = []
173 cols.append(func.return_type)
174 cols.append(name)
175 params = func.get_parameter_string(name)
176 cols.extend([p.strip() for p in params.split(',')])
177
178 ent = ABIEntry(cols, attrs)
179 entry_dict[ent.name] = ent
180
181 entries = entry_dict.values()
182 entries.sort()
183
184 return entries
185
186 def abi_parse_line(line):
187 cols = [col.strip() for col in line.split(',')]
188
189 attrs = {
190 'slot': -1,
191 'hidden': False,
192 'alias': None,
193 'handcode': None,
194 }
195
196 # extract attributes from the first column
197 vals = cols[0].split(':')
198 while len(vals) > 1:
199 val = vals.pop(0)
200 if val.startswith('slot='):
201 attrs['slot'] = int(val[5:])
202 elif val == 'hidden':
203 attrs['hidden'] = True
204 elif val.startswith('alias='):
205 attrs['alias'] = val[6:]
206 elif val.startswith('handcode='):
207 attrs['handcode'] = val[9:]
208 elif not val:
209 pass
210 else:
211 raise Exception('unknown attribute %s' % val)
212 cols[0] = vals[0]
213
214 return (attrs, cols)
215
216 def abi_parse(filename):
217 """Parse a CSV file for ABI entries."""
218 fp = open(filename) if filename != '-' else sys.stdin
219 lines = [line.strip() for line in fp.readlines()
220 if not line.startswith('#') and line.strip()]
221
222 entry_dict = {}
223 next_slot = 0
224 for line in lines:
225 attrs, cols = abi_parse_line(line)
226
227 # post-process attributes
228 if attrs['alias']:
229 try:
230 alias = entry_dict[attrs['alias']]
231 except KeyError:
232 raise Exception('failed to alias %s' % attrs['alias'])
233 if alias.alias:
234 raise Exception('recursive alias %s' % ent.name)
235 slot = alias.slot
236 attrs['alias'] = alias
237 else:
238 slot = next_slot
239 next_slot += 1
240
241 if attrs['slot'] < 0:
242 attrs['slot'] = slot
243 elif attrs['slot'] != slot:
244 raise Exception('invalid slot in %s' % (line))
245
246 ent = ABIEntry(cols, attrs)
247 if entry_dict.has_key(ent.name):
248 raise Exception('%s is duplicated' % (ent.name))
249 entry_dict[ent.name] = ent
250
251 entries = entry_dict.values()
252 entries.sort()
253
254 return entries
255
256 def abi_sanity_check(entries):
257 if not entries:
258 return
259
260 all_names = []
261 last_slot = entries[-1].slot
262 i = 0
263 for slot in xrange(last_slot + 1):
264 if entries[i].slot != slot:
265 raise Exception('entries are not ordered by slots')
266 if entries[i].alias:
267 raise Exception('first entry of slot %d aliases %s'
268 % (slot, entries[i].alias.name))
269 handcode = None
270 while i < len(entries) and entries[i].slot == slot:
271 ent = entries[i]
272 if not handcode and ent.handcode:
273 handcode = ent.handcode
274 elif ent.handcode != handcode:
275 raise Exception('two aliases with handcode %s != %s',
276 ent.handcode, handcode)
277
278 if ent.name in all_names:
279 raise Exception('%s is duplicated' % (ent.name))
280 if ent.alias and ent.alias.name not in all_names:
281 raise Exception('failed to alias %s' % (ent.alias.name))
282 all_names.append(ent.name)
283 i += 1
284 if i < len(entries):
285 raise Exception('there are %d invalid entries' % (len(entries) - 1))
286
287 class ABIPrinter(object):
288 """MAPI Printer"""
289
290 def __init__(self, entries):
291 self.entries = entries
292
293 # sort entries by their names
294 self.entries_sorted_by_names = self.entries[:]
295 self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
296
297 self.indent = ' ' * 3
298 self.noop_warn = 'noop_warn'
299 self.noop_generic = 'noop_generic'
300 self.current_get = 'entry_current_get'
301
302 self.api_defines = []
303 self.api_headers = ['"KHR/khrplatform.h"']
304 self.api_call = 'KHRONOS_APICALL'
305 self.api_entry = 'KHRONOS_APIENTRY'
306 self.api_attrs = 'KHRONOS_APIATTRIBUTES'
307
308 self.c_header = ''
309
310 self.lib_need_table_size = True
311 self.lib_need_noop_array = True
312 self.lib_need_stubs = True
313 self.lib_need_all_entries = True
314 self.lib_need_non_hidden_entries = False
315
316 def c_notice(self):
317 return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
318
319 def c_public_includes(self):
320 """Return includes of the client API headers."""
321 defines = ['#define ' + d for d in self.api_defines]
322 includes = ['#include ' + h for h in self.api_headers]
323 return "\n".join(defines + includes)
324
325 def need_entry_point(self, ent):
326 """Return True if an entry point is needed for the entry."""
327 # non-handcode hidden aliases may share the entry they alias
328 use_alias = (ent.hidden and ent.alias and not ent.handcode)
329 return not use_alias
330
331 def c_public_declarations(self, prefix):
332 """Return the declarations of public entry points."""
333 decls = []
334 for ent in self.entries:
335 if not self.need_entry_point(ent):
336 continue
337 export = self.api_call if not ent.hidden else ''
338 decls.append(self._c_decl(ent, prefix, True, export) + ';')
339
340 return "\n".join(decls)
341
342 def c_mapi_table(self):
343 """Return defines of the dispatch table size."""
344 num_static_entries = self.entries[-1].slot + 1
345 return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
346 '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
347 num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
348
349 def c_mapi_table_initializer(self, prefix):
350 """Return the array initializer for mapi_table_fill."""
351 entries = [self._c_function(ent, prefix)
352 for ent in self.entries if not ent.alias]
353 pre = self.indent + '(mapi_proc) '
354 return pre + (',\n' + pre).join(entries)
355
356 def c_mapi_table_spec(self):
357 """Return the spec for mapi_init."""
358 specv1 = []
359 line = '"1'
360 for ent in self.entries:
361 if not ent.alias:
362 line += '\\0"\n'
363 specv1.append(line)
364 line = '"'
365 line += '%s\\0' % ent.name
366 line += '";'
367 specv1.append(line)
368
369 return self.indent + self.indent.join(specv1)
370
371 def _c_function(self, ent, prefix, mangle=False, stringify=False):
372 """Return the function name of an entry."""
373 formats = {
374 True: { True: '%s_STR(%s)', False: '%s(%s)' },
375 False: { True: '"%s%s"', False: '%s%s' },
376 }
377 fmt = formats[prefix.isupper()][stringify]
378 name = ent.name
379 if mangle and ent.hidden:
380 name = '_dispatch_stub_' + str(ent.slot)
381 return fmt % (prefix, name)
382
383 def _c_function_call(self, ent, prefix):
384 """Return the function name used for calling."""
385 if ent.handcode:
386 # _c_function does not handle this case
387 formats = { True: '%s(%s)', False: '%s%s' }
388 fmt = formats[prefix.isupper()]
389 name = fmt % (prefix, ent.handcode)
390 elif self.need_entry_point(ent):
391 name = self._c_function(ent, prefix, True)
392 else:
393 name = self._c_function(ent.alias, prefix, True)
394 return name
395
396 def _c_decl(self, ent, prefix, mangle=False, export=''):
397 """Return the C declaration for the entry."""
398 decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry,
399 self._c_function(ent, prefix, mangle), ent.c_params())
400 if export:
401 decl = export + ' ' + decl
402 if self.api_attrs:
403 decl += ' ' + self.api_attrs
404
405 return decl
406
407 def _c_cast(self, ent):
408 """Return the C cast for the entry."""
409 cast = '%s (%s *)(%s)' % (
410 ent.c_return(), self.api_entry, ent.c_params())
411
412 return cast
413
414 def c_private_declarations(self, prefix):
415 """Return the declarations of private functions."""
416 decls = [self._c_decl(ent, prefix) + ';'
417 for ent in self.entries if not ent.alias]
418
419 return "\n".join(decls)
420
421 def c_public_dispatches(self, prefix, no_hidden):
422 """Return the public dispatch functions."""
423 dispatches = []
424 for ent in self.entries:
425 if ent.hidden and no_hidden:
426 continue
427
428 if not self.need_entry_point(ent):
429 continue
430
431 export = self.api_call if not ent.hidden else ''
432
433 proto = self._c_decl(ent, prefix, True, export)
434 cast = self._c_cast(ent)
435
436 ret = ''
437 if ent.ret:
438 ret = 'return '
439 stmt1 = self.indent
440 stmt1 += 'const struct mapi_table *_tbl = %s();' % (
441 self.current_get)
442 stmt2 = self.indent
443 stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
444 ent.slot)
445 stmt3 = self.indent
446 stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args())
447
448 disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
449
450 if ent.handcode:
451 disp = '#if 0\n' + disp + '\n#endif'
452
453 dispatches.append(disp)
454
455 return '\n\n'.join(dispatches)
456
457 def c_public_initializer(self, prefix):
458 """Return the initializer for public dispatch functions."""
459 names = []
460 for ent in self.entries:
461 if ent.alias:
462 continue
463
464 name = '%s(mapi_func) %s' % (self.indent,
465 self._c_function_call(ent, prefix))
466 names.append(name)
467
468 return ',\n'.join(names)
469
470 def c_stub_string_pool(self):
471 """Return the string pool for use by stubs."""
472 # sort entries by their names
473 sorted_entries = self.entries[:]
474 sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
475
476 pool = []
477 offsets = {}
478 count = 0
479 for ent in sorted_entries:
480 offsets[ent] = count
481 pool.append('%s' % (ent.name))
482 count += len(ent.name) + 1
483
484 pool_str = self.indent + '"' + \
485 ('\\0"\n' + self.indent + '"').join(pool) + '";'
486 return (pool_str, offsets)
487
488 def c_stub_initializer(self, prefix, pool_offsets):
489 """Return the initializer for struct mapi_stub array."""
490 stubs = []
491 for ent in self.entries_sorted_by_names:
492 stubs.append('%s{ (void *) %d, %d, NULL }' % (
493 self.indent, pool_offsets[ent], ent.slot))
494
495 return ',\n'.join(stubs)
496
497 def c_noop_functions(self, prefix, warn_prefix):
498 """Return the noop functions."""
499 noops = []
500 for ent in self.entries:
501 if ent.alias:
502 continue
503
504 proto = self._c_decl(ent, prefix, False, 'static')
505
506 stmt1 = self.indent;
507 space = ''
508 for t, n, a in ent.params:
509 stmt1 += "%s(void) %s;" % (space, n)
510 space = ' '
511
512 if ent.params:
513 stmt1 += '\n';
514
515 stmt1 += self.indent + '%s(%s);' % (self.noop_warn,
516 self._c_function(ent, warn_prefix, False, True))
517
518 if ent.ret:
519 stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
520 noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
521 else:
522 noop = '%s\n{\n%s\n}' % (proto, stmt1)
523
524 noops.append(noop)
525
526 return '\n\n'.join(noops)
527
528 def c_noop_initializer(self, prefix, use_generic):
529 """Return an initializer for the noop dispatch table."""
530 entries = [self._c_function(ent, prefix)
531 for ent in self.entries if not ent.alias]
532 if use_generic:
533 entries = [self.noop_generic] * len(entries)
534
535 entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
536
537 pre = self.indent + '(mapi_func) '
538 return pre + (',\n' + pre).join(entries)
539
540 def c_asm_gcc(self, prefix, no_hidden):
541 asm = []
542
543 for ent in self.entries:
544 if ent.hidden and no_hidden:
545 continue
546
547 if not self.need_entry_point(ent):
548 continue
549
550 name = self._c_function(ent, prefix, True, True)
551
552 if ent.handcode:
553 asm.append('#if 0')
554
555 if ent.hidden:
556 asm.append('".hidden "%s"\\n"' % (name))
557
558 if ent.alias and not (ent.alias.hidden and no_hidden):
559 asm.append('".globl "%s"\\n"' % (name))
560 asm.append('".set "%s", "%s"\\n"' % (name,
561 self._c_function(ent.alias, prefix, True, True)))
562 else:
563 asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name))
564 asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
565
566 if ent.handcode:
567 asm.append('#endif')
568 asm.append('')
569
570 return "\n".join(asm)
571
572 def output_for_lib(self):
573 print self.c_notice()
574
575 if self.c_header:
576 print
577 print self.c_header
578
579 print
580 print '#ifdef MAPI_TMP_DEFINES'
581 print self.c_public_includes()
582 print
583 print self.c_public_declarations(self.prefix_lib)
584 print '#undef MAPI_TMP_DEFINES'
585 print '#endif /* MAPI_TMP_DEFINES */'
586
587 if self.lib_need_table_size:
588 print
589 print '#ifdef MAPI_TMP_TABLE'
590 print self.c_mapi_table()
591 print '#undef MAPI_TMP_TABLE'
592 print '#endif /* MAPI_TMP_TABLE */'
593
594 if self.lib_need_noop_array:
595 print
596 print '#ifdef MAPI_TMP_NOOP_ARRAY'
597 print '#ifdef DEBUG'
598 print
599 print self.c_noop_functions(self.prefix_noop, self.prefix_warn)
600 print
601 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
602 print self.c_noop_initializer(self.prefix_noop, False)
603 print '};'
604 print
605 print '#else /* DEBUG */'
606 print
607 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
608 print self.c_noop_initializer(self.prefix_noop, True)
609 print '};'
610 print
611 print '#endif /* DEBUG */'
612 print '#undef MAPI_TMP_NOOP_ARRAY'
613 print '#endif /* MAPI_TMP_NOOP_ARRAY */'
614
615 if self.lib_need_stubs:
616 pool, pool_offsets = self.c_stub_string_pool()
617 print
618 print '#ifdef MAPI_TMP_PUBLIC_STUBS'
619 print 'static const char public_string_pool[] ='
620 print pool
621 print
622 print 'static const struct mapi_stub public_stubs[] = {'
623 print self.c_stub_initializer(self.prefix_lib, pool_offsets)
624 print '};'
625 print '#undef MAPI_TMP_PUBLIC_STUBS'
626 print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
627
628 if self.lib_need_all_entries:
629 print
630 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
631 print self.c_public_dispatches(self.prefix_lib, False)
632 print
633 print 'static const mapi_func public_entries[] = {'
634 print self.c_public_initializer(self.prefix_lib)
635 print '};'
636 print '#undef MAPI_TMP_PUBLIC_ENTRIES'
637 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
638
639 print
640 print '#ifdef MAPI_TMP_STUB_ASM_GCC'
641 print '__asm__('
642 print self.c_asm_gcc(self.prefix_lib, False)
643 print ');'
644 print '#undef MAPI_TMP_STUB_ASM_GCC'
645 print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
646
647 if self.lib_need_non_hidden_entries:
648 all_hidden = True
649 for ent in self.entries:
650 if not ent.hidden:
651 all_hidden = False
652 break
653 if not all_hidden:
654 print
655 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
656 print self.c_public_dispatches(self.prefix_lib, True)
657 print
658 print '/* does not need public_entries */'
659 print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
660 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
661
662 print
663 print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
664 print '__asm__('
665 print self.c_asm_gcc(self.prefix_lib, True)
666 print ');'
667 print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
668 print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
669
670 def output_for_app(self):
671 print self.c_notice()
672 print
673 print self.c_private_declarations(self.prefix_app)
674 print
675 print '#ifdef API_TMP_DEFINE_SPEC'
676 print
677 print 'static const char %s_spec[] =' % (self.prefix_app)
678 print self.c_mapi_table_spec()
679 print
680 print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
681 print self.c_mapi_table_initializer(self.prefix_app)
682 print '};'
683 print
684 print '#endif /* API_TMP_DEFINE_SPEC */'
685
686 class GLAPIPrinter(ABIPrinter):
687 """OpenGL API Printer"""
688
689 def __init__(self, entries, api=None):
690 api_entries = self._get_api_entries(entries, api)
691 super(GLAPIPrinter, self).__init__(api_entries)
692
693 self.api_defines = ['GL_GLEXT_PROTOTYPES']
694 self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
695 self.api_call = 'GLAPI'
696 self.api_entry = 'APIENTRY'
697 self.api_attrs = ''
698
699 self.lib_need_table_size = False
700 self.lib_need_noop_array = False
701 self.lib_need_stubs = False
702 self.lib_need_all_entries = False
703 self.lib_need_non_hidden_entries = True
704
705 self.prefix_lib = 'GLAPI_PREFIX'
706 self.prefix_app = '_mesa_'
707 self.prefix_noop = 'noop'
708 self.prefix_warn = self.prefix_lib
709
710 self.c_header = self._get_c_header()
711
712 def _get_api_entries(self, entries, api):
713 """Override the entry attributes according to API."""
714 import copy
715
716 # no override
717 if api is None:
718 return entries
719
720 api_entries = {}
721 for ent in entries:
722 ent = copy.copy(ent)
723
724 # override 'hidden' and 'handcode'
725 ent.hidden = ent.name not in api
726 ent.handcode = False
727 if ent.alias:
728 ent.alias = api_entries[ent.alias.name]
729
730 api_entries[ent.name] = ent
731
732 # sanity check
733 missed = [name for name in api if name not in api_entries]
734 if missed:
735 raise Exception('%s is missing' % str(missed))
736
737 entries = api_entries.values()
738 entries.sort()
739
740 return entries
741
742 def _get_c_header(self):
743 header = """#ifndef _GLAPI_TMP_H_
744 #define _GLAPI_TMP_H_
745 #ifdef USE_MGL_NAMESPACE
746 #define GLAPI_PREFIX(func) mgl##func
747 #define GLAPI_PREFIX_STR(func) "mgl"#func
748 #else
749 #define GLAPI_PREFIX(func) gl##func
750 #define GLAPI_PREFIX_STR(func) "gl"#func
751 #endif /* USE_MGL_NAMESPACE */
752
753 typedef int GLfixed;
754 typedef int GLclampx;
755 #endif /* _GLAPI_TMP_H_ */"""
756
757 return header
758
759 class ES1APIPrinter(GLAPIPrinter):
760 """OpenGL ES 1.x API Printer"""
761
762 def __init__(self, entries):
763 from gles_api import es1_api
764
765 super(ES1APIPrinter, self).__init__(entries, es1_api)
766 self.prefix_lib = 'gl'
767 self.prefix_warn = 'gl'
768
769 def _get_c_header(self):
770 header = """#ifndef _GLAPI_TMP_H_
771 #define _GLAPI_TMP_H_
772 typedef int GLfixed;
773 typedef int GLclampx;
774 #endif /* _GLAPI_TMP_H_ */"""
775
776 return header
777
778 class ES2APIPrinter(GLAPIPrinter):
779 """OpenGL ES 2.x API Printer"""
780
781 def __init__(self, entries):
782 from gles_api import es2_api
783
784 super(ES2APIPrinter, self).__init__(entries, es2_api)
785 self.prefix_lib = 'gl'
786 self.prefix_warn = 'gl'
787
788 def _get_c_header(self):
789 header = """#ifndef _GLAPI_TMP_H_
790 #define _GLAPI_TMP_H_
791 typedef int GLfixed;
792 typedef int GLclampx;
793 #endif /* _GLAPI_TMP_H_ */"""
794
795 return header
796
797 class SharedGLAPIPrinter(GLAPIPrinter):
798 """Shared GLAPI API Printer"""
799
800 def __init__(self, entries):
801 super(SharedGLAPIPrinter, self).__init__(entries, [])
802
803 self.lib_need_table_size = True
804 self.lib_need_noop_array = True
805 self.lib_need_stubs = True
806 self.lib_need_all_entries = True
807 self.lib_need_non_hidden_entries = False
808
809 self.prefix_lib = 'shared'
810 self.prefix_warn = 'gl'
811
812 def _get_c_header(self):
813 header = """#ifndef _GLAPI_TMP_H_
814 #define _GLAPI_TMP_H_
815 typedef int GLfixed;
816 typedef int GLclampx;
817 #endif /* _GLAPI_TMP_H_ */"""
818
819 return header
820
821 class VGAPIPrinter(ABIPrinter):
822 """OpenVG API Printer"""
823
824 def __init__(self, entries):
825 super(VGAPIPrinter, self).__init__(entries)
826
827 self.api_defines = ['VG_VGEXT_PROTOTYPES']
828 self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
829 self.api_call = 'VG_API_CALL'
830 self.api_entry = 'VG_API_ENTRY'
831 self.api_attrs = 'VG_API_EXIT'
832
833 self.prefix_lib = 'vg'
834 self.prefix_app = 'vega'
835 self.prefix_noop = 'noop'
836 self.prefix_warn = 'vg'
837
838 def parse_args():
839 printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
840 modes = ['lib', 'app']
841
842 parser = OptionParser(usage='usage: %prog [options] <filename>')
843 parser.add_option('-p', '--printer', dest='printer',
844 help='printer to use: %s' % (", ".join(printers)))
845 parser.add_option('-m', '--mode', dest='mode',
846 help='target user: %s' % (", ".join(modes)))
847
848 options, args = parser.parse_args()
849 if not args or options.printer not in printers or \
850 options.mode not in modes:
851 parser.print_help()
852 sys.exit(1)
853
854 return (args[0], options)
855
856 def main():
857 printers = {
858 'vgapi': VGAPIPrinter,
859 'glapi': GLAPIPrinter,
860 'es1api': ES1APIPrinter,
861 'es2api': ES2APIPrinter,
862 'shared-glapi': SharedGLAPIPrinter,
863 }
864
865 filename, options = parse_args()
866
867 if filename.endswith('.xml'):
868 entries = abi_parse_xml(filename)
869 else:
870 entries = abi_parse(filename)
871 abi_sanity_check(entries)
872
873 printer = printers[options.printer](entries)
874 if options.mode == 'lib':
875 printer.output_for_lib()
876 else:
877 printer.output_for_app()
878
879 if __name__ == '__main__':
880 main()