]> git.cworth.org Git - apitrace/blob - base.py
Avoid consecutive const keywords.
[apitrace] / base.py
1 #############################################################################
2 #
3 # Copyright 2008 Tungsten Graphics, Inc.
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as published
7 # by the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 #############################################################################
19
20 """C basic types"""
21
22
23 import debug
24
25
26 all_types = {}
27
28 class Type:
29
30     def __init__(self, name):
31         self.name = name
32
33     def __str__(self):
34         return self.name
35
36     def identifier(self):
37         return self.name.replace(' ', '_')
38
39     def isoutput(self):
40         return False
41
42     def decl(self):
43         pass
44
45     def impl(self):
46         pass
47
48     def dump(self, instance):
49         raise NotImplementedError
50     
51     def wrap_instance(self, instance):
52         pass 
53
54     def unwrap_instance(self, instance):
55         pass
56
57
58 class _Void(Type):
59
60     def __init__(self):
61         Type.__init__(self, "void")
62
63 Void = _Void()
64
65
66 class Concrete(Type):
67
68     def __init__(self, name):
69         for char in name:
70             assert char.isalnum() or char in '_ '
71
72         Type.__init__(self, name)
73         
74         assert self.name not in all_types
75         if self.name not in all_types:
76             all_types[self.name] = self
77
78     def decl(self):
79         print 'void Dump%s(const %s &value);' % (self.identifier(), str(self))
80     
81     def impl(self):
82         print 'void Dump%s(const %s &value) {' % (self.identifier(), str(self))
83         self._dump("value");
84         print '}'
85         print
86     
87     def _dump(self, instance):
88         raise NotImplementedError
89     
90     def dump(self, instance):
91         print '    Dump%s(%s);' % (self.identifier(), instance)
92     
93
94 class Intrinsic(Concrete):
95
96     def __init__(self, expr, format, name = None):
97         if name is None:
98             name = expr
99         Concrete.__init__(self, name)
100         self.expr = expr
101         self.format = format
102
103     def _dump(self, instance):
104         print '    Log::TextF("%s", %s);' % (self.format, instance)
105         
106     def __str__(self):
107         return self.expr
108
109
110 class Const(Type):
111
112     def __init__(self, type):
113         Type.__init__(self, 'C' + type.name)
114         self.type = type
115
116     def dump(self, instance):
117         self.type.dump(instance)
118
119     def __str__(self):
120         if isinstance(self.type, Pointer):
121             return str(self.type) + " const"
122         else:
123             return "const " + str(self.type)
124
125
126 class Pointer(Type):
127
128     def __init__(self, type):
129         Type.__init__(self, 'P' + type.name)
130         self.type = type
131
132     def __str__(self):
133         return str(self.type) + " *"
134     
135     def dump(self, instance):
136         print '    if(%s) {' % instance
137         print '        Log::BeginReference("%s", %s);' % (self.type, instance)
138         try:
139             self.type.dump("*" + instance)
140         except NotImplementedError:
141             pass
142         print '        Log::EndReference();'
143         print '    }'
144         print '    else'
145         print '        Log::Text("NULL");'
146
147     def wrap_instance(self, instance):
148         self.type.wrap_instance("*" + instance)
149
150     def unwrap_instance(self, instance):
151         self.type.wrap_instance("*" + instance)
152
153
154 def ConstPointer(type):
155     return Pointer(Const(type))
156
157
158 class OutPointer(Pointer):
159
160     def isoutput(self):
161         return True
162
163
164 class Enum(Concrete):
165
166     def __init__(self, name, values):
167         Concrete.__init__(self, name)
168         self.values = values
169     
170     def _dump(self, instance):
171         print '    switch(%s) {' % instance
172         for value in self.values:
173             print '    case %s:' % value
174             print '        Log::Text("%s");' % value
175             print '        break;'
176         print '    default:'
177         print '        Log::TextF("%%i", %s);' % instance
178         print '        break;'
179         print '    }'
180
181
182 class FakeEnum(Enum):
183
184     __seq = 0
185     
186     def __init__(self, type, values):
187         FakeEnum.__seq += 1
188         Enum.__init__(self, type.name + str(FakeEnum.__seq), values)
189         self.type = type
190     
191     def __str__(self):
192         return str(self.type)
193
194
195 class Flags(Concrete):
196
197     __seq = 0
198     
199     def __init__(self, type, values):
200         Flags.__seq += 1
201         Concrete.__init__(self, type.name + str(Flags.__seq))
202         self.type = type
203         self.values = values
204
205     def __str__(self):
206         return str(self.type)
207     
208     def _dump(self, instance):
209         print '    bool l_First = TRUE;'
210         print '    %s l_Value = %s;' % (self.type, instance)
211         for value in self.values:
212             print '    if((l_Value & %s) == %s) {' % (value, value)
213             print '        if(!l_First)'
214             print '            Log::Text(" | ");'
215             print '        Log::Text("%s");' % value
216             print '        l_Value &= ~%s;' % value
217             print '        l_First = FALSE;'
218             print '    }'
219         print '    if(l_Value || l_First) {'
220         print '        if(!l_First)'
221         print '            Log::Text(" | ");'
222         self.type.dump("l_Value");
223         print '    }'
224
225
226 class Struct(Concrete):
227
228     def __init__(self, name, members):
229         Concrete.__init__(self, name)
230         self.members = members
231
232     def _dump(self, instance):
233         for type, name in self.members:
234             print '    Log::BeginElement("%s", "%s");' % (type, name)
235             type.dump('(%s).%s' % (instance, name))
236             print '    Log::EndElement();'
237
238
239 class Alias(Type):
240
241     def __init__(self, name, type):
242         Type.__init__(self, name)
243         self.type = type
244
245     def dump(self, instance):
246         self.type.dump(instance)
247
248
249 class Function:
250
251     def __init__(self, type, name, args, call = '__stdcall', fail = None):
252         self.type = type
253         self.name = name
254         self.args = args
255         self.call = call
256         self.fail = fail
257
258     def prototype(self, name=None):
259         if name is not None:
260             name = name.strip()
261         else:
262             name = self.name
263         s = name
264         if self.call:
265             s = self.call + ' ' + s
266         if name.startswith('*'):
267             s = '(' + s + ')'
268         s = str(self.type) + ' ' + s
269         s += "("
270         if self.args:
271             s += ", ".join(["%s %s" % (type, name) for type, name in self.args])
272         else:
273             s += "void"
274         s += ")"
275         return s
276
277     def pointer_type(self):
278         return 'P' + self.name
279
280     def pointer_value(self):
281         return 'p' + self.name
282
283     def wrap_decl(self):
284         ptype = self.pointer_type()
285         pvalue = self.pointer_value()
286         print 'typedef ' + self.prototype('* %s' % ptype) + ';'
287         print 'static %s %s = NULL;' % (ptype, pvalue)
288         print
289
290     def get_true_pointer(self):
291         raise NotImplementedError
292
293     def fail_impl(self):
294         if self.fail is not None:
295             if self.type is Void:
296                 assert self.fail == ''
297                 print '            return;' 
298             else:
299                 assert self.fail != ''
300                 print '            return %s;' % self.fail
301         else:
302             print '            ExitProcess(0);'
303
304     def wrap_impl(self):
305         pvalue = self.pointer_value()
306         print self.prototype() + ' {'
307         if self.type is Void:
308             result = ''
309         else:
310             print '    %s result;' % self.type
311             result = 'result = '
312         self.get_true_pointer()
313         print '    Log::BeginCall("%s");' % (self.name)
314         for type, name in self.args:
315             if not type.isoutput():
316                 type.unwrap_instance(name)
317                 print '    Log::BeginArg("%s", "%s");' % (type, name)
318                 type.dump(name)
319                 print '    Log::EndArg();'
320         print '    %s%s(%s);' % (result, pvalue, ', '.join([str(name) for type, name in self.args]))
321         for type, name in self.args:
322             if type.isoutput():
323                 print '    Log::BeginArg("%s", "%s");' % (type, name)
324                 type.dump(name)
325                 print '    Log::EndArg();'
326                 type.wrap_instance(name)
327         if self.type is not Void:
328             print '    Log::BeginReturn("%s");' % self.type
329             self.type.dump("result")
330             print '    Log::EndReturn();'
331             self.type.wrap_instance('result')
332         print '    Log::EndCall();'
333         self.post_call_impl()
334         if self.type is not Void:
335             print '    return result;'
336         print '}'
337         print
338
339     def post_call_impl(self):
340         pass
341
342
343 class Interface(Type):
344
345     def __init__(self, name, base=None):
346         Type.__init__(self, name)
347         self.base = base
348         self.methods = []
349
350     def itermethods(self):
351         if self.base is not None:
352             for method in self.base.itermethods():
353                 yield method
354         for method in self.methods:
355             yield method
356         raise StopIteration
357
358     def wrap_name(self):
359         return "Wrap" + self.name
360
361     def wrap_pre_decl(self):
362         print "class %s;" % self.wrap_name()
363
364     def wrap_decl(self):
365         print "class %s : public %s " % (self.wrap_name(), self.name)
366         print "{"
367         print "public:"
368         print "    %s(%s * pInstance);" % (self.wrap_name(), self.name)
369         print "    virtual ~%s();" % self.wrap_name()
370         print
371         for method in self.itermethods():
372             print "    " + method.prototype() + ";"
373         print
374         #print "private:"
375         print "    %s * m_pInstance;" % (self.name,)
376         print "};"
377         print
378
379     def wrap_impl(self):
380         print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name)
381         print '    m_pInstance = pInstance;'
382         print '}'
383         print
384         print '%s::~%s() {' % (self.wrap_name(), self.wrap_name())
385         print '}'
386         print
387         for method in self.itermethods():
388             print method.prototype(self.wrap_name() + '::' + method.name) + ' {'
389             if method.type is Void:
390                 result = ''
391             else:
392                 print '    %s result;' % method.type
393                 result = 'result = '
394             print '    Log::BeginCall("%s");' % (self.name + '::' + method.name)
395             print '    Log::BeginArg("%s *", "this");' % self.name
396             print '    Log::BeginReference("%s", m_pInstance);' % self.name
397             print '    Log::EndReference();'
398             print '    Log::EndArg();'
399             for type, name in method.args:
400                 if not type.isoutput():
401                     type.unwrap_instance(name)
402                     print '    Log::BeginArg("%s", "%s");' % (type, name)
403                     type.dump(name)
404                     print '    Log::EndArg();'
405             print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(name) for type, name in method.args]))
406             for type, name in method.args:
407                 if type.isoutput():
408                     print '    Log::BeginArg("%s", "%s");' % (type, name)
409                     type.dump(name)
410                     print '    Log::EndArg();'
411                     type.wrap_instance(name)
412             if method.type is not Void:
413                 print '    Log::BeginReturn("%s");' % method.type
414                 method.type.dump("result")
415                 print '    Log::EndReturn();'
416                 method.type.wrap_instance('result')
417             print '    Log::EndCall();'
418             if method.name == 'QueryInterface':
419                 print '    if(*ppvObj == m_pInstance)'
420                 print '        *ppvObj = this;'
421             if method.name == 'Release':
422                 assert method.type is not Void
423                 print '    if(!result)'
424                 print '        delete this;'
425             if method.type is not Void:
426                 print '    return result;'
427             print '}'
428             print
429         print
430
431
432 class Method(Function):
433
434     def __init__(self, type, name, args):
435         Function.__init__(self, type, name, args)
436
437
438 towrap = []
439
440 class WrapPointer(Pointer):
441
442     def __init__(self, type):
443         Pointer.__init__(self, type)
444         if type not in towrap:
445             towrap.append(type)
446
447     def wrap_instance(self, instance):
448         print "    if(%s)" % instance
449         print "        %s = new %s(%s);" % (instance, self.type.wrap_name(), instance)
450
451     def unwrap_instance(self, instance):
452         print "    if(%s)" % instance
453         print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance)
454
455
456 class _String(Type):
457
458     def __init__(self):
459         Type.__init__(self, "String")
460
461     def __str__(self):
462         return "char *"
463
464     def dump(self, instance):
465         print '    Log::DumpString((const char *)%s);' % instance
466
467 String = _String()
468
469 class _WString(Type):
470
471     def __init__(self):
472         Type.__init__(self, "WString")
473
474     def __str__(self):
475         return "wchar_t *"
476
477     def dump(self, instance):
478         print '    Log::DumpWString(%s);' % instance
479
480 WString = _WString()
481
482
483 SChar = Intrinsic("signed char", "%i")
484 UChar = Intrinsic("unsigned char", "%u")
485 Short = Intrinsic("short", "%i")
486 Int = Intrinsic("int", "%i")
487 Long = Intrinsic("long", "%li")
488 UShort = Intrinsic("unsigned short", "%u")
489 UInt = Intrinsic("unsigned int", "%u")
490 ULong = Intrinsic("unsigned long", "%lu")
491 Float = Intrinsic("float", "%f")
492 Double = Intrinsic("double", "%f")
493
494
495 def wrap():
496     for type in all_types.itervalues():
497         type.decl()
498     print
499     for type in all_types.itervalues():
500         type.impl()
501     print
502     for type in towrap:
503         type.wrap_pre_decl()
504     print
505     for type in towrap:
506         type.wrap_decl()
507     print
508     for type in towrap:
509         type.wrap_impl()
510     print