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