debug.py (3886B)
1 from glad.lang.c.generator import CGenerator 2 3 4 DEFAULT_DEBUG_IMPL = ''' 5 {return_def} 6 _pre_call_callback("{name}", {args_callback}); 7 {return_assign} glad_{name}({args}); 8 _post_call_callback("{name}", {args_callback}); 9 {return_return} 10 ''' 11 12 13 DEBUG_HEADER = ''' 14 #define GLAD_DEBUG 15 typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...); 16 17 GLAPI void glad_set_pre_callback(GLADcallback cb); 18 GLAPI void glad_set_post_callback(GLADcallback cb); 19 ''' 20 21 DEBUG_CODE = ''' 22 static GLADcallback _pre_call_callback = _pre_call_callback_default; 23 void glad_set_pre_callback(GLADcallback cb) { 24 _pre_call_callback = cb; 25 } 26 27 static GLADcallback _post_call_callback = _post_call_callback_default; 28 void glad_set_post_callback(GLADcallback cb) { 29 _post_call_callback = cb; 30 } 31 ''' 32 33 DEFAULT_CALLBACK = ''' 34 void _pre_call_callback_default(const char *name, void *funcptr, int len_args, ...) {} 35 void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {} 36 ''' 37 38 DEFAULT_CALLBACK_GL = ''' 39 void _pre_call_callback_default(const char *name, void *funcptr, int len_args, ...) {} 40 void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) { 41 GLenum error_code; 42 error_code = glad_glGetError(); 43 44 if (error_code != GL_NO_ERROR) { 45 fprintf(stderr, "ERROR %d in %s\\n", error_code, name); 46 } 47 } 48 ''' 49 50 51 class CDebugGenerator(CGenerator): 52 NAME = 'c-debug' 53 NAME_LONG = 'C/C++ Debug' 54 55 def write_code_head(self, f): 56 CGenerator.write_code_head(self, f) 57 58 if self.spec.NAME == 'gl': 59 f.write(DEFAULT_CALLBACK_GL) 60 else: 61 f.write(DEFAULT_CALLBACK) 62 63 f.write(DEBUG_CODE) 64 65 def write_api_header(self, f): 66 CGenerator.write_api_header(self, f) 67 f.write(DEBUG_HEADER) 68 69 def write_function_prototype(self, fobj, func): 70 fobj.write('typedef {} (APIENTRYP PFN{}PROC)({});\n'.format( 71 func.proto.ret.to_c(), func.proto.name.upper(), 72 ', '.join(param.type.raw for param in func.params) 73 )) 74 fobj.write('GLAPI PFN{}PROC glad_{};\n'.format( 75 func.proto.name.upper(), func.proto.name 76 )) 77 fobj.write('GLAPI PFN{}PROC glad_debug_{};\n'.format( 78 func.proto.name.upper(), func.proto.name 79 )) 80 fobj.write('#define {0} glad_debug_{0}\n'.format(func.proto.name)) 81 82 def write_function(self, fobj, func): 83 fobj.write('PFN{}PROC glad_{};\n'.format( 84 func.proto.name.upper(), func.proto.name 85 )) 86 87 # write the default debug function 88 args_def = ', '.join( 89 '{type} arg{i}'.format(type=param.type.to_c(), i=i) 90 for i, param in enumerate(func.params) 91 ) 92 fobj.write('{} APIENTRY glad_debug_impl_{}({}) {{'.format( 93 func.proto.ret.to_c(), func.proto.name, args_def 94 )) 95 args = ', '.join('arg{}'.format(i) for i, _ in enumerate(func.params)) 96 args_callback = ', '.join(filter( 97 None, ['(void*){}'.format(func.proto.name), str(len(func.params)), args] 98 )) 99 return_def = '' 100 return_assign = '' 101 return_return = '' 102 # lower because of win API having VOID 103 if not func.proto.ret.to_c().lower() == 'void': 104 return_def = '\n {} ret;'.format(func.proto.ret.to_c()) 105 return_assign = 'ret = ' 106 return_return = 'return ret;' 107 fobj.write('\n'.join(filter(None, DEFAULT_DEBUG_IMPL.format( 108 name=func.proto.name, args=args, args_callback=args_callback, 109 return_def=return_def, return_assign=return_assign, 110 return_return=return_return 111 ).splitlines()))) 112 fobj.write('\n}\n') 113 114 fobj.write('PFN{0}PROC glad_debug_{1} = glad_debug_impl_{1};\n'.format( 115 func.proto.name.upper(), func.proto.name 116 ))