blob: 8f91a6dcdcecf55a0d701c2317b392b3c0cfe3b8 [file] [log] [blame]
José Fonseca95442442008-07-08 10:32:53 +09001#############################################################################
2#
3# Copyright 2008 Jose Fonseca
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
José Fonsecad626cf42008-07-07 07:43:16 +090020"""C basic types"""
21
22class Type:
23
24 def __init__(self, name):
25 self.name = name
26
27 def __str__(self):
28 return self.name
29
30 def isoutput(self):
31 return False
32
José Fonsecaa83fb242008-07-07 16:55:52 +090033 def dump(self, instance):
34 raise NotImplementedError
35
José Fonsecad626cf42008-07-07 07:43:16 +090036 def wrap_instance(self, instance):
37 pass
38
José Fonseca27cd25d2008-07-07 13:44:00 +090039 def unwrap_instance(self, instance):
40 pass
41
José Fonsecad626cf42008-07-07 07:43:16 +090042
43class Void(Type):
44
45 def __init__(self):
46 Type.__init__(self, "void")
47
48Void = Void()
49
50
51class Intrinsic(Type):
52
53 def __init__(self, name, format):
54 Type.__init__(self, name)
55 self.format = format
56
José Fonsecaa83fb242008-07-07 16:55:52 +090057 def dump(self, instance):
José Fonseca22aec832008-07-09 09:38:45 +090058 print ' Log::TextF("%s", %s);' % (self.format, instance)
José Fonsecaa83fb242008-07-07 16:55:52 +090059
José Fonsecad626cf42008-07-07 07:43:16 +090060
61class Const(Type):
62
63 def __init__(self, type):
64 Type.__init__(self, 'C' + type.name)
65 self.type = type
66
José Fonsecaa83fb242008-07-07 16:55:52 +090067 def dump(self, instance):
68 self.type.dump(instance)
69
José Fonsecad626cf42008-07-07 07:43:16 +090070 def __str__(self):
71 return "const " + str(self.type)
72
73
74class Pointer(Type):
75
76 def __init__(self, type):
77 Type.__init__(self, 'P' + type.name)
78 self.type = type
79
80 def __str__(self):
81 return str(self.type) + " *"
José Fonsecaa83fb242008-07-07 16:55:52 +090082
83 def dump(self, instance):
José Fonseca4a9c40c2008-07-07 18:04:53 +090084 print ' if(%s) {' % instance
José Fonsecaa83fb242008-07-07 16:55:52 +090085 try:
José Fonsecaa83fb242008-07-07 16:55:52 +090086 self.type.dump("*" + instance)
José Fonseca4a9c40c2008-07-07 18:04:53 +090087 except NotImplementedError:
José Fonseca22aec832008-07-09 09:38:45 +090088 print ' Log::TextF("%%p", %s);' % instance
José Fonseca4a9c40c2008-07-07 18:04:53 +090089 print ' }'
90 print ' else'
José Fonseca22aec832008-07-09 09:38:45 +090091 print ' Log::Text("NULL");'
José Fonsecad626cf42008-07-07 07:43:16 +090092
93 def wrap_instance(self, instance):
94 self.type.wrap_instance("*" + instance)
95
José Fonseca27cd25d2008-07-07 13:44:00 +090096 def unwrap_instance(self, instance):
97 self.type.wrap_instance("*" + instance)
98
José Fonsecad626cf42008-07-07 07:43:16 +090099
José Fonsecab974caa2008-07-09 08:12:34 +0900100def ConstPointer(type):
101 return Pointer(Const(type))
102
103
José Fonsecaa83fb242008-07-07 16:55:52 +0900104class OutPointer(Pointer):
José Fonsecad626cf42008-07-07 07:43:16 +0900105
106 def isoutput(self):
107 return True
108
José Fonsecad626cf42008-07-07 07:43:16 +0900109
110class Enum(Type):
111
112 def __init__(self, name, values):
113 Type.__init__(self, name)
114 self.values = values
José Fonsecaa83fb242008-07-07 16:55:52 +0900115
116 def dump(self, instance):
117 print ' switch(%s) {' % instance
118 for value in self.values:
119 print ' case %s:' % value
José Fonseca22aec832008-07-09 09:38:45 +0900120 print ' Log::Text("%s");' % value
José Fonsecaa83fb242008-07-07 16:55:52 +0900121 print ' break;'
122 print ' default:'
José Fonseca22aec832008-07-09 09:38:45 +0900123 print ' Log::TextF("%%i", %s);' % instance
José Fonsecaa83fb242008-07-07 16:55:52 +0900124 print ' break;'
125 print ' }'
José Fonsecad626cf42008-07-07 07:43:16 +0900126
127
128class Flags(Type):
129
130 def __init__(self, type, values):
131 Type.__init__(self, type.name)
José Fonsecaec61f312008-07-09 02:16:43 +0900132 self.type = type
José Fonsecad626cf42008-07-07 07:43:16 +0900133 self.values = values
134
José Fonsecaec61f312008-07-09 02:16:43 +0900135 def dump(self, instance):
136 print ' {'
137 print ' %s l_Value = %s;' % (self.type, instance)
138 for value in self.values:
139 print ' if((l_Value & %s) == %s) {' % (value, value)
José Fonseca22aec832008-07-09 09:38:45 +0900140 print ' Log::Text("%s | ");' % value
José Fonsecaec61f312008-07-09 02:16:43 +0900141 print ' l_Value &= ~%s;' % value
142 print ' }'
143 self.type.dump("l_Value");
144 print ' }'
145
José Fonsecad626cf42008-07-07 07:43:16 +0900146
147class Struct(Type):
148
149 def __init__(self, name, members):
150 Type.__init__(self, name)
151 self.members = members
152
José Fonsecaa83fb242008-07-07 16:55:52 +0900153 def dump(self, instance):
José Fonseca22aec832008-07-09 09:38:45 +0900154 print ' Log::Text("{");'
José Fonsecaa83fb242008-07-07 16:55:52 +0900155 first = True
156 for type, name in self.members:
157 if first:
158 first = False
159 else:
José Fonseca22aec832008-07-09 09:38:45 +0900160 print ' Log::Text(", ");'
José Fonsecaa83fb242008-07-07 16:55:52 +0900161 type.dump('(%s).%s' % (instance, name))
José Fonseca22aec832008-07-09 09:38:45 +0900162 print ' Log::Text("}");'
José Fonsecaa83fb242008-07-07 16:55:52 +0900163
José Fonsecad626cf42008-07-07 07:43:16 +0900164
165class Alias(Type):
166
167 def __init__(self, name, type):
168 Type.__init__(self, name)
169 self.type = type
170
José Fonsecaa83fb242008-07-07 16:55:52 +0900171 def dump(self, instance):
172 self.type.dump(instance)
173
José Fonsecad626cf42008-07-07 07:43:16 +0900174
175class Function:
176
177 def __init__(self, type, name, args, call = '__stdcall'):
178 self.type = type
179 self.name = name
180 self.args = args
181 self.call = call
182
183 def prototype(self, name=None):
184 if name is not None:
185 name = name.strip()
186 else:
187 name = self.name
188 s = name
189 if self.call:
190 s = self.call + ' ' + s
191 if name.startswith('*'):
192 s = '(' + s + ')'
193 s = str(self.type) + ' ' + s
194 s += "("
195 if self.args:
196 s += ", ".join(["%s %s" % (type, name) for type, name in self.args])
197 else:
198 s += "void"
199 s += ")"
200 return s
201
202
203class Interface(Type):
204
205 def __init__(self, name, base=None):
206 Type.__init__(self, name)
207 self.base = base
208 self.methods = []
209
210 def itermethods(self):
211 if self.base is not None:
212 for method in self.base.itermethods():
213 yield method
214 for method in self.methods:
215 yield method
216 raise StopIteration
217
218 def wrap_name(self):
219 return "Wrap" + self.name
220
221 def wrap_pre_decl(self):
222 print "class %s;" % self.wrap_name()
223
224 def wrap_decl(self):
225 print "class %s : public %s " % (self.wrap_name(), self.name)
226 print "{"
227 print "public:"
228 print " %s(%s * pInstance);" % (self.wrap_name(), self.name)
229 print " virtual ~%s();" % self.wrap_name()
230 print
231 for method in self.itermethods():
232 print " " + method.prototype() + ";"
233 print
José Fonseca27cd25d2008-07-07 13:44:00 +0900234 #print "private:"
José Fonsecad626cf42008-07-07 07:43:16 +0900235 print " %s * m_pInstance;" % (self.name,)
236 print "};"
237 print
238
239 def wrap_impl(self):
240 print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name)
José Fonsecad626cf42008-07-07 07:43:16 +0900241 print ' m_pInstance = pInstance;'
242 print '}'
243 print
244 print '%s::~%s() {' % (self.wrap_name(), self.wrap_name())
José Fonsecad626cf42008-07-07 07:43:16 +0900245 print '}'
246 print
247 for method in self.itermethods():
248 print method.prototype(self.wrap_name() + '::' + method.name) + ' {'
249 if method.type is Void:
250 result = ''
251 else:
252 print ' %s result;' % method.type
253 result = 'result = '
José Fonseca22aec832008-07-09 09:38:45 +0900254 print ' Log::BeginCall("%s");' % (self.name + '::' + method.name)
255 print ' Log::BeginParam("this", "%s *");' % self.name
256 print ' Log::TextF("%p", m_pInstance);'
257 print ' Log::EndParam();'
José Fonseca27cd25d2008-07-07 13:44:00 +0900258 for type, name in method.args:
259 if not type.isoutput():
260 type.unwrap_instance(name)
José Fonseca22aec832008-07-09 09:38:45 +0900261 print ' Log::BeginParam("%s", "%s");' % (name, type)
José Fonsecaa83fb242008-07-07 16:55:52 +0900262 type.dump(name)
José Fonseca22aec832008-07-09 09:38:45 +0900263 print ' Log::EndParam();'
José Fonsecad626cf42008-07-07 07:43:16 +0900264 print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(name) for type, name in method.args]))
265 for type, name in method.args:
266 if type.isoutput():
José Fonseca22aec832008-07-09 09:38:45 +0900267 print ' Log::BeginParam("%s", "%s");' % (name, type)
José Fonseca22aa6882008-07-07 17:33:30 +0900268 type.dump(name)
José Fonseca22aec832008-07-09 09:38:45 +0900269 print ' Log::EndParam();'
José Fonsecad626cf42008-07-07 07:43:16 +0900270 type.wrap_instance(name)
271 if method.type is not Void:
José Fonseca22aec832008-07-09 09:38:45 +0900272 print ' Log::BeginReturn("%s");' % method.type
José Fonseca4a9c40c2008-07-07 18:04:53 +0900273 method.type.dump("result")
José Fonseca22aec832008-07-09 09:38:45 +0900274 print ' Log::EndReturn();'
José Fonsecad626cf42008-07-07 07:43:16 +0900275 method.type.wrap_instance('result')
José Fonseca22aec832008-07-09 09:38:45 +0900276 print ' Log::EndCall();'
José Fonsecad626cf42008-07-07 07:43:16 +0900277 if method.name == 'QueryInterface':
278 print ' if(*ppvObj == m_pInstance)'
279 print ' *ppvObj = this;'
280 if method.name == 'Release':
281 assert method.type is not Void
282 print ' if(!result)'
283 print ' delete this;'
284 if method.type is not Void:
285 print ' return result;'
286 print '}'
287 print
288 print
289
290
291class Method(Function):
292
293 def __init__(self, type, name, args):
294 Function.__init__(self, type, name, args)
295
296
297towrap = []
298
299class WrapPointer(Pointer):
300
301 def __init__(self, type):
302 Pointer.__init__(self, type)
303 if type not in towrap:
304 towrap.append(type)
305
306 def wrap_instance(self, instance):
307 print " if(%s)" % instance
308 print " %s = new %s(%s);" % (instance, self.type.wrap_name(), instance)
309
José Fonseca27cd25d2008-07-07 13:44:00 +0900310 def unwrap_instance(self, instance):
311 print " if(%s)" % instance
312 print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance)
313
José Fonsecad626cf42008-07-07 07:43:16 +0900314String = Intrinsic("char *", "%s")
José Fonsecaec61f312008-07-09 02:16:43 +0900315Short = Intrinsic("short", "%i")
José Fonsecad626cf42008-07-07 07:43:16 +0900316Int = Intrinsic("int", "%i")
317Long = Intrinsic("long", "%li")
318Float = Intrinsic("float", "%f")
319
320
321def wrap():
322 for type in towrap:
323 type.wrap_pre_decl()
324 print
325 for type in towrap:
326 type.wrap_decl()
327 print
328 for type in towrap:
329 type.wrap_impl()
330 print