]> git.cworth.org Git - apitrace/blob - base.py
Handle pointers correctly.
[apitrace] / base.py
1 """C basic types"""
2
3 class Type:
4
5     def __init__(self, name):
6         self.name = name
7
8     def __str__(self):
9         return self.name
10
11     def isoutput(self):
12         return False
13
14     def dump(self, instance):
15         raise NotImplementedError
16     
17     def wrap_instance(self, instance):
18         pass
19
20     def unwrap_instance(self, instance):
21         pass
22
23
24 class Void(Type):
25
26     def __init__(self):
27         Type.__init__(self, "void")
28
29 Void = Void()
30
31
32 class Intrinsic(Type):
33
34     def __init__(self, name, format):
35         Type.__init__(self, name)
36         self.format = format
37
38     def dump(self, instance):
39         print '    g_pLog->TextF("%s", %s);' % (self.format, instance)
40
41
42 class Const(Type):
43
44     def __init__(self, type):
45         Type.__init__(self, 'C' + type.name)
46         self.type = type
47
48     def dump(self, instance):
49         self.type.dump(instance)
50
51     def __str__(self):
52         return "const " + str(self.type)
53
54
55 class Pointer(Type):
56
57     def __init__(self, type):
58         Type.__init__(self, 'P' + type.name)
59         self.type = type
60
61     def __str__(self):
62         return str(self.type) + " *"
63     
64     def dump(self, instance):
65         print '    if(%s) {' % instance
66         try:
67             self.type.dump("*" + instance)
68         except NotImplementedError:
69             print '        g_pLog->TextF("%%p", %s);' % instance
70         print '    }'
71         print '    else'
72         print '        g_pLog->Text("NULL");'
73
74     def wrap_instance(self, instance):
75         self.type.wrap_instance("*" + instance)
76
77     def unwrap_instance(self, instance):
78         self.type.wrap_instance("*" + instance)
79
80
81 class OutPointer(Pointer):
82
83     def isoutput(self):
84         return True
85
86
87 class Enum(Type):
88
89     def __init__(self, name, values):
90         Type.__init__(self, name)
91         self.values = values
92     
93     def dump(self, instance):
94         print '    switch(%s) {' % instance
95         for value in self.values:
96             print '    case %s:' % value
97             print '        g_pLog->Text("%s");' % value
98             print '        break;'
99         print '    default:'
100         print '        g_pLog->TextF("%%i", %s);' % instance
101         print '        break;'
102         print '    }'
103
104
105 class Flags(Type):
106
107     def __init__(self, type, values):
108         Type.__init__(self, type.name)
109         self.values = values
110
111
112 class Struct(Type):
113
114     def __init__(self, name, members):
115         Type.__init__(self, name)
116         self.members = members
117
118     def dump(self, instance):
119         print '    g_pLog->Text("{");'
120         first = True
121         for type, name in self.members:
122             if first:
123                 first = False
124             else:
125                 print '    g_pLog->Text(", ");'
126             type.dump('(%s).%s' % (instance, name))
127         print '    g_pLog->Text("}");'
128
129
130 class Alias(Type):
131
132     def __init__(self, name, type):
133         Type.__init__(self, name)
134         self.type = type
135
136     def dump(self, instance):
137         self.type.dump(instance)
138
139
140 class Function:
141
142     def __init__(self, type, name, args, call = '__stdcall'):
143         self.type = type
144         self.name = name
145         self.args = args
146         self.call = call
147
148     def prototype(self, name=None):
149         if name is not None:
150             name = name.strip()
151         else:
152             name = self.name
153         s = name
154         if self.call:
155             s = self.call + ' ' + s
156         if name.startswith('*'):
157             s = '(' + s + ')'
158         s = str(self.type) + ' ' + s
159         s += "("
160         if self.args:
161             s += ", ".join(["%s %s" % (type, name) for type, name in self.args])
162         else:
163             s += "void"
164         s += ")"
165         return s
166
167
168 class Interface(Type):
169
170     def __init__(self, name, base=None):
171         Type.__init__(self, name)
172         self.base = base
173         self.methods = []
174
175     def itermethods(self):
176         if self.base is not None:
177             for method in self.base.itermethods():
178                 yield method
179         for method in self.methods:
180             yield method
181         raise StopIteration
182
183     def wrap_name(self):
184         return "Wrap" + self.name
185
186     def wrap_pre_decl(self):
187         print "class %s;" % self.wrap_name()
188
189     def wrap_decl(self):
190         print "class %s : public %s " % (self.wrap_name(), self.name)
191         print "{"
192         print "public:"
193         print "    %s(%s * pInstance);" % (self.wrap_name(), self.name)
194         print "    virtual ~%s();" % self.wrap_name()
195         print
196         for method in self.itermethods():
197             print "    " + method.prototype() + ";"
198         print
199         #print "private:"
200         print "    %s * m_pInstance;" % (self.name,)
201         print "};"
202         print
203
204     def wrap_impl(self):
205         print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name)
206         print '    m_pInstance = pInstance;'
207         print '}'
208         print
209         print '%s::~%s() {' % (self.wrap_name(), self.wrap_name())
210         print '}'
211         print
212         for method in self.itermethods():
213             print method.prototype(self.wrap_name() + '::' + method.name) + ' {'
214             if method.type is Void:
215                 result = ''
216             else:
217                 print '    %s result;' % method.type
218                 result = 'result = '
219             print '    g_pLog->BeginCall("%s");' % (self.name + '::' + method.name)
220             print '    g_pLog->BeginParam("this", "%s *");' % self.name
221             print '    g_pLog->TextF("%p", m_pInstance);'
222             print '    g_pLog->EndParam();'
223             for type, name in method.args:
224                 if not type.isoutput():
225                     type.unwrap_instance(name)
226                     print '    g_pLog->BeginParam("%s", "%s");' % (name, type)
227                     type.dump(name)
228                     print '    g_pLog->EndParam();'
229             print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(name) for type, name in method.args]))
230             for type, name in method.args:
231                 if type.isoutput():
232                     print '    g_pLog->BeginParam("%s", "%s");' % (name, type)
233                     type.dump(name)
234                     print '    g_pLog->EndParam();'
235                     type.wrap_instance(name)
236             if method.type is not Void:
237                 print '    g_pLog->BeginReturn("%s");' % method.type
238                 method.type.dump("result")
239                 print '    g_pLog->EndReturn();'
240                 method.type.wrap_instance('result')
241             print '    g_pLog->EndCall();'
242             if method.name == 'QueryInterface':
243                 print '    if(*ppvObj == m_pInstance)'
244                 print '        *ppvObj = this;'
245             if method.name == 'Release':
246                 assert method.type is not Void
247                 print '    if(!result)'
248                 print '        delete this;'
249             if method.type is not Void:
250                 print '    return result;'
251             print '}'
252             print
253         print
254
255
256 class Method(Function):
257
258     def __init__(self, type, name, args):
259         Function.__init__(self, type, name, args)
260
261
262 towrap = []
263
264 class WrapPointer(Pointer):
265
266     def __init__(self, type):
267         Pointer.__init__(self, type)
268         if type not in towrap:
269             towrap.append(type)
270
271     def wrap_instance(self, instance):
272         print "    if(%s)" % instance
273         print "        %s = new %s(%s);" % (instance, self.type.wrap_name(), instance)
274
275     def unwrap_instance(self, instance):
276         print "    if(%s)" % instance
277         print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance)
278
279 String = Intrinsic("char *", "%s")
280 Int = Intrinsic("int", "%i")
281 Long = Intrinsic("long", "%li")
282 Float = Intrinsic("float", "%f")
283
284
285 def wrap():
286     for type in towrap:
287         type.wrap_pre_decl()
288     print
289     for type in towrap:
290         type.wrap_decl()
291     print
292     for type in towrap:
293         type.wrap_impl()
294     print