3 # Mesa 3-D graphics library
5 # Copyright (C) 2010 LunarG Inc.
7 # Permission is hereby granted, free of charge, to any person obtaining a
8 # copy of this software and associated documentation files (the "Software"),
9 # to deal in the Software without restriction, including without limitation
10 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 # and/or sell copies of the Software, and to permit persons to whom the
12 # Software is furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice shall be included
15 # in all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 # DEALINGS IN THE SOFTWARE.
26 # Chia-I Wu <olv@lunarg.com>
29 # make it possible to import glapi
31 GLAPI
= os
.path
.join(".", os
.path
.dirname(sys
.argv
[0]), "glapi/gen")
32 sys
.path
.append(GLAPI
)
35 from optparse
import OptionParser
40 # number of dynamic entries
41 ABI_NUM_DYNAMIC_ENTRIES
= 256
43 class ABIEntry(object):
44 """Represent an ABI entry."""
46 _match_c_param
= re
.compile(
47 '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
49 def __init__(self
, cols
, attrs
, xml_data
= None):
52 self
.slot
= attrs
['slot']
53 self
.hidden
= attrs
['hidden']
54 self
.alias
= attrs
['alias']
55 self
.handcode
= attrs
['handcode']
56 self
.xml_data
= xml_data
58 def c_prototype(self
):
59 return '%s %s(%s)' % (self
.c_return(), self
.name
, self
.c_params())
69 """Return the parameter list used in the entry prototype."""
71 for t
, n
, a
in self
.params
:
72 sep
= '' if t
.endswith('*') else ' '
73 arr
= '[%d]' % a
if a
else ''
74 c_params
.append(t
+ sep
+ n
+ arr
)
76 c_params
.append('void')
78 return ", ".join(c_params
)
81 """Return the argument list used in the entry invocation."""
83 for t
, n
, a
in self
.params
:
86 return ", ".join(c_args
)
88 def _parse(self
, cols
):
98 elif len(cols
) == 1 and cols
[0] == 'void':
102 params
.append(self
._parse
_param
(val
))
108 def _parse_param(self
, c_param
):
109 m
= self
._match
_c
_param
.match(c_param
)
111 raise Exception('unrecognized param ' + c_param
)
113 c_type
= m
.group('type').strip()
114 c_name
= m
.group('name')
115 c_array
= m
.group('array')
116 c_array
= int(c_array
) if c_array
else 0
118 return (c_type
, c_name
, c_array
)
121 return self
.c_prototype()
123 def __cmp__(self
, other
):
124 # compare slot, alias, and then name
125 res
= cmp(self
.slot
, other
.slot
)
129 elif not other
.alias
:
133 res
= cmp(self
.name
, other
.name
)
137 def abi_parse_xml(xml
):
138 """Parse a GLAPI XML file for ABI entries."""
139 api
= gl_XML
.parse_GL_API(xml
, glX_XML
.glx_item_factory())
142 for func
in api
.functionIterateByOffset():
143 # make sure func.name appear first
144 entry_points
= func
.entry_points
[:]
145 entry_points
.remove(func
.name
)
146 entry_points
.insert(0, func
.name
)
148 for name
in entry_points
:
151 'hidden': not func
.is_static_entry_point(name
),
152 'alias': None if name
== func
.name
else func
.name
,
153 'handcode': bool(func
.has_different_protocol(name
)),
159 alias
= entry_dict
[attrs
['alias']]
161 raise Exception('failed to alias %s' % attrs
['alias'])
163 raise Exception('recursive alias %s' % ent
.name
)
164 attrs
['alias'] = alias
165 if attrs
['handcode']:
166 attrs
['handcode'] = func
.static_glx_name(name
)
168 attrs
['handcode'] = None
170 if entry_dict
.has_key(name
):
171 raise Exception('%s is duplicated' % (name
))
174 cols
.append(func
.return_type
)
176 params
= func
.get_parameter_string(name
)
177 cols
.extend([p
.strip() for p
in params
.split(',')])
179 ent
= ABIEntry(cols
, attrs
, func
)
180 entry_dict
[ent
.name
] = ent
182 entries
= entry_dict
.values()
187 def abi_parse_line(line
):
188 cols
= [col
.strip() for col
in line
.split(',')]
197 # extract attributes from the first column
198 vals
= cols
[0].split(':')
201 if val
.startswith('slot='):
202 attrs
['slot'] = int(val
[5:])
203 elif val
== 'hidden':
204 attrs
['hidden'] = True
205 elif val
.startswith('alias='):
206 attrs
['alias'] = val
[6:]
207 elif val
.startswith('handcode='):
208 attrs
['handcode'] = val
[9:]
212 raise Exception('unknown attribute %s' % val
)
217 def abi_parse(filename
):
218 """Parse a CSV file for ABI entries."""
219 fp
= open(filename
) if filename
!= '-' else sys
.stdin
220 lines
= [line
.strip() for line
in fp
.readlines()
221 if not line
.startswith('#') and line
.strip()]
226 attrs
, cols
= abi_parse_line(line
)
228 # post-process attributes
231 alias
= entry_dict
[attrs
['alias']]
233 raise Exception('failed to alias %s' % attrs
['alias'])
235 raise Exception('recursive alias %s' % ent
.name
)
237 attrs
['alias'] = alias
242 if attrs
['slot'] < 0:
244 elif attrs
['slot'] != slot
:
245 raise Exception('invalid slot in %s' % (line
))
247 ent
= ABIEntry(cols
, attrs
)
248 if entry_dict
.has_key(ent
.name
):
249 raise Exception('%s is duplicated' % (ent
.name
))
250 entry_dict
[ent
.name
] = ent
252 entries
= entry_dict
.values()
257 def abi_sanity_check(entries
):
262 last_slot
= entries
[-1].slot
264 for slot
in xrange(last_slot
+ 1):
265 if entries
[i
].slot
!= slot
:
266 raise Exception('entries are not ordered by slots')
268 raise Exception('first entry of slot %d aliases %s'
269 % (slot
, entries
[i
].alias
.name
))
271 while i
< len(entries
) and entries
[i
].slot
== slot
:
273 if not handcode
and ent
.handcode
:
274 handcode
= ent
.handcode
275 elif ent
.handcode
!= handcode
:
276 raise Exception('two aliases with handcode %s != %s',
277 ent
.handcode
, handcode
)
279 if ent
.name
in all_names
:
280 raise Exception('%s is duplicated' % (ent
.name
))
281 if ent
.alias
and ent
.alias
.name
not in all_names
:
282 raise Exception('failed to alias %s' % (ent
.alias
.name
))
283 all_names
.append(ent
.name
)
286 raise Exception('there are %d invalid entries' % (len(entries
) - 1))
288 class ABIPrinter(object):
291 def __init__(self
, entries
):
292 self
.entries
= entries
294 # sort entries by their names
295 self
.entries_sorted_by_names
= self
.entries
[:]
296 self
.entries_sorted_by_names
.sort(lambda x
, y
: cmp(x
.name
, y
.name
))
298 self
.indent
= ' ' * 3
299 self
.noop_warn
= 'noop_warn'
300 self
.noop_generic
= 'noop_generic'
301 self
.current_get
= 'entry_current_get'
303 self
.api_defines
= []
304 self
.api_headers
= ['"KHR/khrplatform.h"']
305 self
.api_call
= 'KHRONOS_APICALL'
306 self
.api_entry
= 'KHRONOS_APIENTRY'
307 self
.api_attrs
= 'KHRONOS_APIATTRIBUTES'
311 self
.lib_need_table_size
= True
312 self
.lib_need_noop_array
= True
313 self
.lib_need_stubs
= True
314 self
.lib_need_all_entries
= True
315 self
.lib_need_non_hidden_entries
= False
318 return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
320 def c_public_includes(self
):
321 """Return includes of the client API headers."""
322 defines
= ['#define ' + d
for d
in self
.api_defines
]
323 includes
= ['#include ' + h
for h
in self
.api_headers
]
324 return "\n".join(defines
+ includes
)
326 def need_entry_point(self
, ent
):
327 """Return True if an entry point is needed for the entry."""
328 # non-handcode hidden aliases may share the entry they alias
329 use_alias
= (ent
.hidden
and ent
.alias
and not ent
.handcode
)
332 def c_public_declarations(self
, prefix
):
333 """Return the declarations of public entry points."""
335 for ent
in self
.entries
:
336 if not self
.need_entry_point(ent
):
338 export
= self
.api_call
if not ent
.hidden
else ''
339 decls
.append(self
._c
_decl
(ent
, prefix
, True, export
) + ';')
341 return "\n".join(decls
)
343 def c_mapi_table(self
):
344 """Return defines of the dispatch table size."""
345 num_static_entries
= self
.entries
[-1].slot
+ 1
346 return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
347 '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
348 num_static_entries
, ABI_NUM_DYNAMIC_ENTRIES
)
350 def c_mapi_table_initializer(self
, prefix
):
351 """Return the array initializer for mapi_table_fill."""
352 entries
= [self
._c
_function
(ent
, prefix
)
353 for ent
in self
.entries
if not ent
.alias
]
354 pre
= self
.indent
+ '(mapi_proc) '
355 return pre
+ (',\n' + pre
).join(entries
)
357 def c_mapi_table_spec(self
):
358 """Return the spec for mapi_init."""
361 for ent
in self
.entries
:
366 line
+= '%s\\0' % ent
.name
370 return self
.indent
+ self
.indent
.join(specv1
)
372 def _c_function(self
, ent
, prefix
, mangle
=False, stringify
=False):
373 """Return the function name of an entry."""
375 True: { True: '%s_STR(%s)', False: '%s(%s)' },
376 False: { True: '"%s%s"', False: '%s%s' },
378 fmt
= formats
[prefix
.isupper()][stringify
]
380 if mangle
and ent
.hidden
:
381 name
= '_dispatch_stub_' + str(ent
.slot
)
382 return fmt
% (prefix
, name
)
384 def _c_function_call(self
, ent
, prefix
):
385 """Return the function name used for calling."""
387 # _c_function does not handle this case
388 formats
= { True: '%s(%s)', False: '%s%s' }
389 fmt
= formats
[prefix
.isupper()]
390 name
= fmt
% (prefix
, ent
.handcode
)
391 elif self
.need_entry_point(ent
):
392 name
= self
._c
_function
(ent
, prefix
, True)
394 name
= self
._c
_function
(ent
.alias
, prefix
, True)
397 def _c_decl(self
, ent
, prefix
, mangle
=False, export
=''):
398 """Return the C declaration for the entry."""
399 decl
= '%s %s %s(%s)' % (ent
.c_return(), self
.api_entry
,
400 self
._c
_function
(ent
, prefix
, mangle
), ent
.c_params())
402 decl
= export
+ ' ' + decl
404 decl
+= ' ' + self
.api_attrs
408 def _c_cast(self
, ent
):
409 """Return the C cast for the entry."""
410 cast
= '%s (%s *)(%s)' % (
411 ent
.c_return(), self
.api_entry
, ent
.c_params())
415 def c_private_declarations(self
, prefix
):
416 """Return the declarations of private functions."""
417 decls
= [self
._c
_decl
(ent
, prefix
) + ';'
418 for ent
in self
.entries
if not ent
.alias
]
420 return "\n".join(decls
)
422 def c_public_dispatches(self
, prefix
, no_hidden
):
423 """Return the public dispatch functions."""
425 for ent
in self
.entries
:
426 if ent
.hidden
and no_hidden
:
429 if not self
.need_entry_point(ent
):
432 export
= self
.api_call
if not ent
.hidden
else ''
434 proto
= self
._c
_decl
(ent
, prefix
, True, export
)
435 cast
= self
._c
_cast
(ent
)
441 stmt1
+= 'const struct mapi_table *_tbl = %s();' % (
444 stmt2
+= 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
447 stmt3
+= '%s((%s) _func)(%s);' % (ret
, cast
, ent
.c_args())
449 disp
= '%s\n{\n%s\n%s\n%s\n}' % (proto
, stmt1
, stmt2
, stmt3
)
452 disp
= '#if 0\n' + disp
+ '\n#endif'
454 dispatches
.append(disp
)
456 return '\n\n'.join(dispatches
)
458 def c_public_initializer(self
, prefix
):
459 """Return the initializer for public dispatch functions."""
461 for ent
in self
.entries
:
465 name
= '%s(mapi_func) %s' % (self
.indent
,
466 self
._c
_function
_call
(ent
, prefix
))
469 return ',\n'.join(names
)
471 def c_stub_string_pool(self
):
472 """Return the string pool for use by stubs."""
473 # sort entries by their names
474 sorted_entries
= self
.entries
[:]
475 sorted_entries
.sort(lambda x
, y
: cmp(x
.name
, y
.name
))
480 for ent
in sorted_entries
:
482 pool
.append('%s' % (ent
.name
))
483 count
+= len(ent
.name
) + 1
485 pool_str
= self
.indent
+ '"' + \
486 ('\\0"\n' + self
.indent
+ '"').join(pool
) + '";'
487 return (pool_str
, offsets
)
489 def c_stub_initializer(self
, prefix
, pool_offsets
):
490 """Return the initializer for struct mapi_stub array."""
492 for ent
in self
.entries_sorted_by_names
:
493 stubs
.append('%s{ (void *) %d, %d, NULL }' % (
494 self
.indent
, pool_offsets
[ent
], ent
.slot
))
496 return ',\n'.join(stubs
)
498 def c_noop_functions(self
, prefix
, warn_prefix
):
499 """Return the noop functions."""
501 for ent
in self
.entries
:
505 proto
= self
._c
_decl
(ent
, prefix
, False, 'static')
509 for t
, n
, a
in ent
.params
:
510 stmt1
+= "%s(void) %s;" % (space
, n
)
516 stmt1
+= self
.indent
+ '%s(%s);' % (self
.noop_warn
,
517 self
._c
_function
(ent
, warn_prefix
, False, True))
520 stmt2
= self
.indent
+ 'return (%s) 0;' % (ent
.ret
)
521 noop
= '%s\n{\n%s\n%s\n}' % (proto
, stmt1
, stmt2
)
523 noop
= '%s\n{\n%s\n}' % (proto
, stmt1
)
527 return '\n\n'.join(noops
)
529 def c_noop_initializer(self
, prefix
, use_generic
):
530 """Return an initializer for the noop dispatch table."""
531 entries
= [self
._c
_function
(ent
, prefix
)
532 for ent
in self
.entries
if not ent
.alias
]
534 entries
= [self
.noop_generic
] * len(entries
)
536 entries
.extend([self
.noop_generic
] * ABI_NUM_DYNAMIC_ENTRIES
)
538 pre
= self
.indent
+ '(mapi_func) '
539 return pre
+ (',\n' + pre
).join(entries
)
541 def c_asm_gcc(self
, prefix
, no_hidden
):
544 for ent
in self
.entries
:
545 if ent
.hidden
and no_hidden
:
548 if not self
.need_entry_point(ent
):
551 name
= self
._c
_function
(ent
, prefix
, True, True)
557 asm
.append('".hidden "%s"\\n"' % (name
))
559 if ent
.alias
and not (ent
.alias
.hidden
and no_hidden
):
560 asm
.append('".globl "%s"\\n"' % (name
))
561 asm
.append('".set "%s", "%s"\\n"' % (name
,
562 self
._c
_function
(ent
.alias
, prefix
, True, True)))
564 asm
.append('STUB_ASM_ENTRY(%s)"\\n"' % (name
))
565 asm
.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent
.slot
))
571 return "\n".join(asm
)
573 def output_for_lib(self
):
574 print self
.c_notice()
581 print '#ifdef MAPI_TMP_DEFINES'
582 print self
.c_public_includes()
584 print self
.c_public_declarations(self
.prefix_lib
)
585 print '#undef MAPI_TMP_DEFINES'
586 print '#endif /* MAPI_TMP_DEFINES */'
588 if self
.lib_need_table_size
:
590 print '#ifdef MAPI_TMP_TABLE'
591 print self
.c_mapi_table()
592 print '#undef MAPI_TMP_TABLE'
593 print '#endif /* MAPI_TMP_TABLE */'
595 if self
.lib_need_noop_array
:
597 print '#ifdef MAPI_TMP_NOOP_ARRAY'
600 print self
.c_noop_functions(self
.prefix_noop
, self
.prefix_warn
)
602 print 'const mapi_func table_%s_array[] = {' % (self
.prefix_noop
)
603 print self
.c_noop_initializer(self
.prefix_noop
, False)
606 print '#else /* DEBUG */'
608 print 'const mapi_func table_%s_array[] = {' % (self
.prefix_noop
)
609 print self
.c_noop_initializer(self
.prefix_noop
, True)
612 print '#endif /* DEBUG */'
613 print '#undef MAPI_TMP_NOOP_ARRAY'
614 print '#endif /* MAPI_TMP_NOOP_ARRAY */'
616 if self
.lib_need_stubs
:
617 pool
, pool_offsets
= self
.c_stub_string_pool()
619 print '#ifdef MAPI_TMP_PUBLIC_STUBS'
620 print 'static const char public_string_pool[] ='
623 print 'static const struct mapi_stub public_stubs[] = {'
624 print self
.c_stub_initializer(self
.prefix_lib
, pool_offsets
)
626 print '#undef MAPI_TMP_PUBLIC_STUBS'
627 print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
629 if self
.lib_need_all_entries
:
631 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
632 print self
.c_public_dispatches(self
.prefix_lib
, False)
634 print 'static const mapi_func public_entries[] = {'
635 print self
.c_public_initializer(self
.prefix_lib
)
637 print '#undef MAPI_TMP_PUBLIC_ENTRIES'
638 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
641 print '#ifdef MAPI_TMP_STUB_ASM_GCC'
643 print self
.c_asm_gcc(self
.prefix_lib
, False)
645 print '#undef MAPI_TMP_STUB_ASM_GCC'
646 print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
648 if self
.lib_need_non_hidden_entries
:
650 for ent
in self
.entries
:
656 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
657 print self
.c_public_dispatches(self
.prefix_lib
, True)
659 print '/* does not need public_entries */'
660 print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
661 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
664 print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
666 print self
.c_asm_gcc(self
.prefix_lib
, True)
668 print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
669 print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
671 def output_for_app(self
):
672 print self
.c_notice()
674 print self
.c_private_declarations(self
.prefix_app
)
676 print '#ifdef API_TMP_DEFINE_SPEC'
678 print 'static const char %s_spec[] =' % (self
.prefix_app
)
679 print self
.c_mapi_table_spec()
681 print 'static const mapi_proc %s_procs[] = {' % (self
.prefix_app
)
682 print self
.c_mapi_table_initializer(self
.prefix_app
)
685 print '#endif /* API_TMP_DEFINE_SPEC */'
687 class GLAPIPrinter(ABIPrinter
):
688 """OpenGL API Printer"""
690 def __init__(self
, entries
):
692 self
._override
_for
_api
(ent
)
693 super(GLAPIPrinter
, self
).__init
__(entries
)
695 self
.api_defines
= ['GL_GLEXT_PROTOTYPES']
696 self
.api_headers
= ['"GL/gl.h"', '"GL/glext.h"']
697 self
.api_call
= 'GLAPI'
698 self
.api_entry
= 'APIENTRY'
701 self
.lib_need_table_size
= False
702 self
.lib_need_noop_array
= False
703 self
.lib_need_stubs
= False
704 self
.lib_need_all_entries
= False
705 self
.lib_need_non_hidden_entries
= True
707 self
.prefix_lib
= 'GLAPI_PREFIX'
708 self
.prefix_app
= '_mesa_'
709 self
.prefix_noop
= 'noop'
710 self
.prefix_warn
= self
.prefix_lib
712 self
.c_header
= self
._get
_c
_header
()
714 def _override_for_api(self
, ent
):
715 """Override attributes of an entry if necessary for this
717 # By default, no override is necessary.
720 def _get_c_header(self
):
721 header
= """#ifndef _GLAPI_TMP_H_
722 #define _GLAPI_TMP_H_
723 #ifdef USE_MGL_NAMESPACE
724 #define GLAPI_PREFIX(func) mgl##func
725 #define GLAPI_PREFIX_STR(func) "mgl"#func
727 #define GLAPI_PREFIX(func) gl##func
728 #define GLAPI_PREFIX_STR(func) "gl"#func
729 #endif /* USE_MGL_NAMESPACE */
731 typedef int GLclampx;
732 #endif /* _GLAPI_TMP_H_ */"""
736 class ES1APIPrinter(GLAPIPrinter
):
737 """OpenGL ES 1.x API Printer"""
739 def __init__(self
, entries
):
740 super(ES1APIPrinter
, self
).__init
__(entries
)
741 self
.prefix_lib
= 'gl'
742 self
.prefix_warn
= 'gl'
744 def _override_for_api(self
, ent
):
745 if ent
.xml_data
is None:
746 raise Exception('ES2 API printer requires XML input')
747 ent
.hidden
= ent
.name
not in \
748 ent
.xml_data
.entry_points_for_api_version('es1')
751 def _get_c_header(self
):
752 header
= """#ifndef _GLAPI_TMP_H_
753 #define _GLAPI_TMP_H_
754 typedef int GLclampx;
755 #endif /* _GLAPI_TMP_H_ */"""
759 class ES2APIPrinter(GLAPIPrinter
):
760 """OpenGL ES 2.x API Printer"""
762 def __init__(self
, entries
):
763 super(ES2APIPrinter
, self
).__init
__(entries
)
764 self
.prefix_lib
= 'gl'
765 self
.prefix_warn
= 'gl'
767 def _override_for_api(self
, ent
):
768 if ent
.xml_data
is None:
769 raise Exception('ES2 API printer requires XML input')
770 ent
.hidden
= ent
.name
not in \
771 ent
.xml_data
.entry_points_for_api_version('es2')
774 def _get_c_header(self
):
775 header
= """#ifndef _GLAPI_TMP_H_
776 #define _GLAPI_TMP_H_
777 typedef int GLclampx;
778 #endif /* _GLAPI_TMP_H_ */"""
782 class SharedGLAPIPrinter(GLAPIPrinter
):
783 """Shared GLAPI API Printer"""
785 def __init__(self
, entries
):
786 super(SharedGLAPIPrinter
, self
).__init
__(entries
)
788 self
.lib_need_table_size
= True
789 self
.lib_need_noop_array
= True
790 self
.lib_need_stubs
= True
791 self
.lib_need_all_entries
= True
792 self
.lib_need_non_hidden_entries
= False
794 self
.prefix_lib
= 'shared'
795 self
.prefix_warn
= 'gl'
797 def _override_for_api(self
, ent
):
801 def _get_c_header(self
):
802 header
= """#ifndef _GLAPI_TMP_H_
803 #define _GLAPI_TMP_H_
804 typedef int GLclampx;
805 #endif /* _GLAPI_TMP_H_ */"""
809 class VGAPIPrinter(ABIPrinter
):
810 """OpenVG API Printer"""
812 def __init__(self
, entries
):
813 super(VGAPIPrinter
, self
).__init
__(entries
)
815 self
.api_defines
= ['VG_VGEXT_PROTOTYPES']
816 self
.api_headers
= ['"VG/openvg.h"', '"VG/vgext.h"']
817 self
.api_call
= 'VG_API_CALL'
818 self
.api_entry
= 'VG_API_ENTRY'
819 self
.api_attrs
= 'VG_API_EXIT'
821 self
.prefix_lib
= 'vg'
822 self
.prefix_app
= 'vega'
823 self
.prefix_noop
= 'noop'
824 self
.prefix_warn
= 'vg'
827 printers
= ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
828 modes
= ['lib', 'app']
830 parser
= OptionParser(usage
='usage: %prog [options] <filename>')
831 parser
.add_option('-p', '--printer', dest
='printer',
832 help='printer to use: %s' % (", ".join(printers
)))
833 parser
.add_option('-m', '--mode', dest
='mode',
834 help='target user: %s' % (", ".join(modes
)))
836 options
, args
= parser
.parse_args()
837 if not args
or options
.printer
not in printers
or \
838 options
.mode
not in modes
:
842 return (args
[0], options
)
846 'vgapi': VGAPIPrinter
,
847 'glapi': GLAPIPrinter
,
848 'es1api': ES1APIPrinter
,
849 'es2api': ES2APIPrinter
,
850 'shared-glapi': SharedGLAPIPrinter
,
853 filename
, options
= parse_args()
855 if filename
.endswith('.xml'):
856 entries
= abi_parse_xml(filename
)
858 entries
= abi_parse(filename
)
859 abi_sanity_check(entries
)
861 printer
= printers
[options
.printer
](entries
)
862 if options
.mode
== 'lib':
863 printer
.output_for_lib()
865 printer
.output_for_app()
867 if __name__
== '__main__':