blob: 60920560c6c0c2d85e6aa0cb512eae64e3508727 [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):
58 print ' g_pLog->TextF("%s", %s);' % (self.format, instance)
59
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:
88 print ' g_pLog->TextF("%%p", %s);' % instance
89 print ' }'
90 print ' else'
91 print ' g_pLog->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é Fonsecaa83fb242008-07-07 16:55:52 +0900100class OutPointer(Pointer):
José Fonsecad626cf42008-07-07 07:43:16 +0900101
102 def isoutput(self):
103 return True
104
José Fonsecad626cf42008-07-07 07:43:16 +0900105
106class Enum(Type):
107
108 def __init__(self, name, values):
109 Type.__init__(self, name)
110 self.values = values
José Fonsecaa83fb242008-07-07 16:55:52 +0900111
112 def dump(self, instance):
113 print ' switch(%s) {' % instance
114 for value in self.values:
115 print ' case %s:' % value
116 print ' g_pLog->Text("%s");' % value
117 print ' break;'
118 print ' default:'
119 print ' g_pLog->TextF("%%i", %s);' % instance
120 print ' break;'
121 print ' }'
José Fonsecad626cf42008-07-07 07:43:16 +0900122
123
124class Flags(Type):
125
126 def __init__(self, type, values):
127 Type.__init__(self, type.name)
José Fonsecaec61f312008-07-09 02:16:43 +0900128 self.type = type
José Fonsecad626cf42008-07-07 07:43:16 +0900129 self.values = values
130
José Fonsecaec61f312008-07-09 02:16:43 +0900131 def dump(self, instance):
132 print ' {'
133 print ' %s l_Value = %s;' % (self.type, instance)
134 for value in self.values:
135 print ' if((l_Value & %s) == %s) {' % (value, value)
136 print ' g_pLog->Text("%s | ");' % value
137 print ' l_Value &= ~%s;' % value
138 print ' }'
139 self.type.dump("l_Value");
140 print ' }'
141
José Fonsecad626cf42008-07-07 07:43:16 +0900142
143class Struct(Type):
144
145 def __init__(self, name, members):
146 Type.__init__(self, name)
147 self.members = members
148
José Fonsecaa83fb242008-07-07 16:55:52 +0900149 def dump(self, instance):
150 print ' g_pLog->Text("{");'
151 first = True
152 for type, name in self.members:
153 if first:
154 first = False
155 else:
156 print ' g_pLog->Text(", ");'
157 type.dump('(%s).%s' % (instance, name))
158 print ' g_pLog->Text("}");'
159
José Fonsecad626cf42008-07-07 07:43:16 +0900160
161class Alias(Type):
162
163 def __init__(self, name, type):
164 Type.__init__(self, name)
165 self.type = type
166
José Fonsecaa83fb242008-07-07 16:55:52 +0900167 def dump(self, instance):
168 self.type.dump(instance)
169
José Fonsecad626cf42008-07-07 07:43:16 +0900170
171class Function:
172
173 def __init__(self, type, name, args, call = '__stdcall'):
174 self.type = type
175 self.name = name
176 self.args = args
177 self.call = call
178
179 def prototype(self, name=None):
180 if name is not None:
181 name = name.strip()
182 else:
183 name = self.name
184 s = name
185 if self.call:
186 s = self.call + ' ' + s
187 if name.startswith('*'):
188 s = '(' + s + ')'
189 s = str(self.type) + ' ' + s
190 s += "("
191 if self.args:
192 s += ", ".join(["%s %s" % (type, name) for type, name in self.args])
193 else:
194 s += "void"
195 s += ")"
196 return s
197
198
199class Interface(Type):
200
201 def __init__(self, name, base=None):
202 Type.__init__(self, name)
203 self.base = base
204 self.methods = []
205
206 def itermethods(self):
207 if self.base is not None:
208 for method in self.base.itermethods():
209 yield method
210 for method in self.methods:
211 yield method
212 raise StopIteration
213
214 def wrap_name(self):
215 return "Wrap" + self.name
216
217 def wrap_pre_decl(self):
218 print "class %s;" % self.wrap_name()
219
220 def wrap_decl(self):
221 print "class %s : public %s " % (self.wrap_name(), self.name)
222 print "{"
223 print "public:"
224 print " %s(%s * pInstance);" % (self.wrap_name(), self.name)
225 print " virtual ~%s();" % self.wrap_name()
226 print
227 for method in self.itermethods():
228 print " " + method.prototype() + ";"
229 print
José Fonseca27cd25d2008-07-07 13:44:00 +0900230 #print "private:"
José Fonsecad626cf42008-07-07 07:43:16 +0900231 print " %s * m_pInstance;" % (self.name,)
232 print "};"
233 print
234
235 def wrap_impl(self):
236 print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name)
José Fonsecad626cf42008-07-07 07:43:16 +0900237 print ' m_pInstance = pInstance;'
238 print '}'
239 print
240 print '%s::~%s() {' % (self.wrap_name(), self.wrap_name())
José Fonsecad626cf42008-07-07 07:43:16 +0900241 print '}'
242 print
243 for method in self.itermethods():
244 print method.prototype(self.wrap_name() + '::' + method.name) + ' {'
245 if method.type is Void:
246 result = ''
247 else:
248 print ' %s result;' % method.type
249 result = 'result = '
José Fonsecad7605892008-07-07 13:09:31 +0900250 print ' g_pLog->BeginCall("%s");' % (self.name + '::' + method.name)
José Fonseca4a9c40c2008-07-07 18:04:53 +0900251 print ' g_pLog->BeginParam("this", "%s *");' % self.name
252 print ' g_pLog->TextF("%p", m_pInstance);'
253 print ' g_pLog->EndParam();'
José Fonseca27cd25d2008-07-07 13:44:00 +0900254 for type, name in method.args:
255 if not type.isoutput():
256 type.unwrap_instance(name)
José Fonsecaa83fb242008-07-07 16:55:52 +0900257 print ' g_pLog->BeginParam("%s", "%s");' % (name, type)
258 type.dump(name)
259 print ' g_pLog->EndParam();'
José Fonsecad626cf42008-07-07 07:43:16 +0900260 print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(name) for type, name in method.args]))
261 for type, name in method.args:
262 if type.isoutput():
José Fonseca22aa6882008-07-07 17:33:30 +0900263 print ' g_pLog->BeginParam("%s", "%s");' % (name, type)
264 type.dump(name)
265 print ' g_pLog->EndParam();'
José Fonsecad626cf42008-07-07 07:43:16 +0900266 type.wrap_instance(name)
267 if method.type is not Void:
José Fonseca22aa6882008-07-07 17:33:30 +0900268 print ' g_pLog->BeginReturn("%s");' % method.type
José Fonseca4a9c40c2008-07-07 18:04:53 +0900269 method.type.dump("result")
José Fonseca22aa6882008-07-07 17:33:30 +0900270 print ' g_pLog->EndReturn();'
José Fonsecad626cf42008-07-07 07:43:16 +0900271 method.type.wrap_instance('result')
José Fonseca22aa6882008-07-07 17:33:30 +0900272 print ' g_pLog->EndCall();'
José Fonsecad626cf42008-07-07 07:43:16 +0900273 if method.name == 'QueryInterface':
274 print ' if(*ppvObj == m_pInstance)'
275 print ' *ppvObj = this;'
276 if method.name == 'Release':
277 assert method.type is not Void
278 print ' if(!result)'
279 print ' delete this;'
280 if method.type is not Void:
281 print ' return result;'
282 print '}'
283 print
284 print
285
286
287class Method(Function):
288
289 def __init__(self, type, name, args):
290 Function.__init__(self, type, name, args)
291
292
293towrap = []
294
295class WrapPointer(Pointer):
296
297 def __init__(self, type):
298 Pointer.__init__(self, type)
299 if type not in towrap:
300 towrap.append(type)
301
302 def wrap_instance(self, instance):
303 print " if(%s)" % instance
304 print " %s = new %s(%s);" % (instance, self.type.wrap_name(), instance)
305
José Fonseca27cd25d2008-07-07 13:44:00 +0900306 def unwrap_instance(self, instance):
307 print " if(%s)" % instance
308 print " %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance)
309
José Fonsecad626cf42008-07-07 07:43:16 +0900310String = Intrinsic("char *", "%s")
José Fonsecaec61f312008-07-09 02:16:43 +0900311Short = Intrinsic("short", "%i")
José Fonsecad626cf42008-07-07 07:43:16 +0900312Int = Intrinsic("int", "%i")
313Long = Intrinsic("long", "%li")
314Float = Intrinsic("float", "%f")
315
316
317def wrap():
318 for type in towrap:
319 type.wrap_pre_decl()
320 print
321 for type in towrap:
322 type.wrap_decl()
323 print
324 for type in towrap:
325 type.wrap_impl()
326 print