-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathprint_objc.py
106 lines (87 loc) · 3.26 KB
/
print_objc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# coding: utf-8
from __future__ import absolute_import
from __future__ import print_function
from objc_util import *
import ctypes
import re
from six.moves import range
def parse_encoding(enc):
type_names={'c':'char',
'i':'int',
's':'short',
'l':'long',
'q':'long long',
'C':'unsigned char',
'I':'unsigned int',
'S':'unsigned short',
'Q':'unsigned long long',
'f':'float',
'd':'double',
'B':'bool',
'v':'void',
'*':'char *',
'@':'object',
'#':'class',
':':'method',
'^':'pointer',
'?':'unknown'}
def parse(c):
return c.startswith(b'^')*b'*' + type_names.get(c.split(b'^')[-1],c.split(b'^')[-1])
enc=re.split(b'\d*',enc)
signature = [parse(c) for c in enc if c]
return signature
#missing bnum. bit field, []array, {}struct, ()union
#objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );
def get_methods(objc_class):
'''return list of selector name, and string ret type and arg types'''
free = c.free
free.argtypes = [c_void_p]
free.restype = None
class_copyMethodList = c.class_copyMethodList
class_copyMethodList.restype = ctypes.POINTER(c_void_p)
class_copyMethodList.argtypes = [c_void_p, ctypes.POINTER(ctypes.c_uint)]
method_getName = c.method_getName
method_getName.restype = c_void_p
method_getName.argtypes = [c_void_p]
method_getTypeEncoding=c.method_getTypeEncoding;
method_getTypeEncoding.restype =c_char_p
method_getTypeEncoding.argtypes= [ c_void_p ]
#DumpObjcMethods(object_getClass(yourClass) /* Metaclass */);
py_methods = []
num_methods = c_uint(0)
method_list_ptr = class_copyMethodList(objc_class.ptr, ctypes.byref(num_methods))
for i in range(num_methods.value):
selector = method_getName(method_list_ptr[i])
enc=method_getTypeEncoding(method_list_ptr[i])
penc=parse_encoding(enc)
sel_name = c.sel_getName(selector)
py_method_name = sel_name.replace(b':', b'_')
#py_methods.append(enc[0]+' ' +py_method_name+'('+', '.join(enc[3:])+')')
py_methods.append((py_method_name, penc[0],penc[3:]))
free(method_list_ptr)
return sorted(py_methods)
def get_class_methods(objc_class):
'''get class methods'''
object_getClass = c.object_getClass
object_getClass.restype = c_void_p
object_getClass.argtypes = [c_void_p]
meta=ObjCInstance(object_getClass(objc_class))
return get_methods(meta)
import console
def print_methods(clsname,print_private=False):
cls=ObjCClass(clsname)
console.set_color(1,0,0)
print(clsname)
print('Class Methods______')
console.set_color(0,0,0)
m=get_class_methods(cls)
print('\n'.join([(k[1]+' ' +k[0]+'( '+', '.join(k[2])+' )') for k in m if not k[0].startswith(b'_')]))
if print_private:
print('\n'.join([(k[1]+' ' +k[0]+'( '+', '.join(k[2])+' )') for k in m if k[0].startswith(b'_')]))
console.set_color(1,0,0)
print('_______Instance Methods______')
console.set_color(0,0,0)
m=get_methods(cls)
print('\n'.join([(k[1]+'\t' +k[0]+'( '+', '.join(k[2])+' )') for k in m if not k[0].startswith(b'_')]))
if print_private:
print(b'\n'.join([(k[1]+'\t' +k[0]+b'( '+b', '.join(k[2])+b' )') for k in m if k[0].startswith(b'_')]))