]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/Modules/pycpp.cxx
the Russian translations were somehow corrupted, fixed
[wxWidgets.git] / wxPython / wxSWIG / Modules / pycpp.cxx
1 /*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
3 *
4 * Author : David Beazley
5 *
6 * Department of Computer Science
7 * University of Chicago
8 * 1100 E 58th Street
9 * Chicago, IL 60637
10 * beazley@cs.uchicago.edu
11 *
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
15
16 /**********************************************************************
17 * $Header$
18 *
19 * pycpp.cxx
20 *
21 * This module contains code to generate Python shadow classes of C/C++
22 * objects.
23 **************************************************************************/
24
25
26 #include "swig.h"
27 #include "python.h"
28
29 static String *setattr;
30 static String *getattr;
31 static String *pyclass;
32 static String *construct;
33 static String *cinit;
34 static String *additional;
35 static int have_constructor;
36 static int have_destructor;
37 static int have_getattr;
38 static int have_setattr;
39 static int have_repr;
40 static char *class_name;
41 static char *class_type;
42 static char *real_classname;
43 static String *base_class;
44 static String base_getattr;
45 static String base_setattr;
46 static int class_renamed = 0;
47
48 // --------------------------------------------------------------------------
49 // PYTHON::cpp_open_class(char *classname, char *rname, char *ctype, int strip)
50 //
51 // Opens a new C++ class or structure.
52 // --------------------------------------------------------------------------
53
54 void PYTHON::cpp_open_class(char *classname, char *rname, char *ctype, int strip) {
55
56 char temp[256];
57
58 this->Language::cpp_open_class(classname, rname, ctype, strip);
59
60 if (shadow) {
61 /* Create new strings for building up a wrapper function */
62
63 setattr = new String();
64 getattr = new String();
65 pyclass = new String();
66 construct = new String();
67 cinit = new String();
68 additional= new String();
69 base_class = 0;
70 base_getattr = "";
71 base_setattr = "";
72
73
74 // *pyclass << "class " << rname << ":\n";
75 *setattr << tab4 << "def __setattr__(self,name,value):\n";
76 *getattr << tab4 << "def __getattr__(self,name):\n";
77 have_constructor = 0;
78 have_destructor = 0;
79 have_getattr = 0;
80 have_setattr = 0;
81 have_repr = 0;
82 if (rname) {
83 class_name = copy_string(rname);
84 class_renamed = 1;
85 } else {
86 class_name = copy_string(classname);
87 class_renamed = 0;
88 }
89 }
90
91 real_classname = copy_string(classname);
92 class_type = copy_string(ctype);
93
94 // Build up the hash table
95 hash.add(real_classname,copy_string(class_name));
96
97 sprintf(temp,"%s %s", class_type, real_classname);
98 hash.add(temp,copy_string(class_name));
99
100 }
101
102 // --------------------------------------------------------------------------
103 // PYTHON::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l)
104 //
105 // Creates a C++ member function
106 // --------------------------------------------------------------------------
107
108 void PYTHON::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) {
109
110 Parm *p;
111 int i;
112 char *realname;
113 int oldshadow;
114 int pcount;
115 int numopt;
116 int have_optional;
117
118 String cname = "python:";
119 String translate = "";
120
121 // Create the default member function
122
123 oldshadow = shadow; // Disable shadowing when wrapping member functions
124 if (shadow) shadow = shadow | PYSHADOW_MEMBER;
125 this->Language::cpp_member_func(name,iname,t,l);
126 shadow = oldshadow;
127 if (shadow) {
128 if (!iname)
129 realname = name;
130 else
131 realname = iname;
132
133 // Check to see if we've already seen this
134 cname << class_name << "::" << realname;
135 if (add_symbol(cname.get(), 0,0)) {
136 return; // Forget it, already saw it
137 }
138
139 if (strcmp(realname,"__repr__") == 0)
140 have_repr = 1;
141
142 // Now add it to the class
143
144 *pyclass << tab4 << "def " << realname << "(self, *_args, **_kwargs):\n";
145 // Create a doc string
146 if (docstring && doc_entry) {
147 *pyclass << tab8 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n";
148 }
149 *pyclass << tab8 << "val = apply(" << module << "." << name_member(realname,class_name) << ",(self,) + _args, _kwargs)\n";
150
151 // Check to see if the return type is an object
152 if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) {
153 if (!typemap_check("out",typemap_lang,t,name_member(realname,class_name))) {
154 if (!have_output) {
155 *pyclass << tab8 << "if val: val = " << (char *) hash.lookup(t->name) << "Ptr(val) ";
156 if (((hash.lookup(t->name)) && (t->is_pointer < 1)) ||
157 ((hash.lookup(t->name)) && (t->is_pointer == 1) && NewObject))
158 *pyclass << "; val.thisown = 1\n";
159 else
160 *pyclass << "\n";
161 } else {
162 // Do nothing!
163 }
164 }
165 }
166 emitAddPragmas(*pyclass, realname, tab8);
167 *pyclass << tab8 << "return val\n";
168
169 // Change the usage string to reflect our shadow class
170 if (doc_entry) {
171 doc_entry->usage = "";
172 doc_entry->usage << usage_func(realname,t,l);
173 }
174 }
175 }
176
177 // -----------------------------------------------------------------------------
178 // void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l)
179 //
180 // Make a constructor for our class
181 // -----------------------------------------------------------------------------
182
183 void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l) {
184 char *realname;
185 Parm *p;
186 int i;
187 int oldshadow = shadow;
188 String cname = "python:constructor:";
189 String translate = "";
190 int pcount, numopt;
191 int have_optional;
192
193 if (shadow) shadow = shadow | PYSHADOW_MEMBER;
194 this->Language::cpp_constructor(name,iname,l);
195 shadow = oldshadow;
196
197 if (shadow) {
198 if (iname)
199 realname = iname;
200 else {
201 if (class_renamed) realname = class_name;
202 else realname = class_name;
203 }
204
205 // Check to see if we've already seen this
206 cname << class_name << "::" << realname;
207 if (add_symbol(cname.get(), 0,0)) {
208 return; // Forget it, already seen it
209 }
210
211 if (!have_constructor) {
212
213 // Create a new constructor
214
215 *construct << tab4 << "def __init__(self,*_args,**_kwargs):\n";
216 if (docstring && doc_entry)
217 *construct << tab8 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n";
218
219 *construct << tab8 << "self.this = apply(" << module << "." << name_construct(realname) << ",_args,_kwargs)\n";
220 *construct << tab8 << "self.thisown = 1\n";
221 emitAddPragmas(*construct,"__init__",tab8);
222 have_constructor = 1;
223 } else {
224
225 // Hmmm. We seem to be creating a different constructor. We're just going to create a
226 // function for it.
227
228 *additional << "def " << realname << "(*_args,**_kwargs):\n";
229 *additional << tab4 << "val = " << class_name << "Ptr(apply("
230 << module << "." << name_construct(realname) << ",_args,_kwargs))\n"
231 << tab4 << "val.thisown = 1\n";
232 emitAddPragmas(*additional, realname, tab4);
233 *additional << tab4 << "return val\n\n";
234 }
235 // Patch up the documentation entry
236 if (doc_entry) {
237 doc_entry->usage = "";
238 doc_entry->usage << usage_func(class_name,0,l);
239 }
240 }
241 }
242
243 // ------------------------------------------------------------------------------
244 // void PYTHON::cpp_destructor(char *name, char *newname)
245 //
246 // Creates a destructor for this object
247 // ------------------------------------------------------------------------------
248
249 void PYTHON::cpp_destructor(char *name, char *newname) {
250 char *realname;
251 int oldshadow = shadow;
252
253 if (shadow) shadow = shadow | PYSHADOW_MEMBER;
254 this->Language::cpp_destructor(name,newname);
255 shadow = oldshadow;
256 if (shadow) {
257 if (newname) realname = newname;
258 else {
259 if (class_renamed) realname = class_name;
260 else realname = name;
261 }
262
263 *pyclass << tab4 << "def __del__(self," << module << "=" << module << "):\n";
264 emitAddPragmas(*pyclass,"__del__",tab8);
265 *pyclass << tab8 << "if self.thisown == 1 :\n"
266 << tab8 << tab4 << module << "." << name_destroy(realname) << "(self)\n";
267
268 have_destructor = 1;
269 if (doc_entry) {
270 doc_entry->usage = "";
271 doc_entry->usage << "del this";
272 }
273 }
274 }
275
276 // -------------------------------------------------------------------------------
277 // PYTHON::cpp_close_class()
278 //
279 // Closes a Python class and writes out a wrapper
280 // -------------------------------------------------------------------------------
281
282 void PYTHON::cpp_close_class() {
283 String ptrclass;
284 String repr;
285
286 if (shadow) {
287
288 if (!have_constructor) {
289 // Build a constructor that takes a pointer to this kind of object
290 *construct << tab4 << "def __init__(self,this):\n";
291 *construct << tab8 << "self.this = this\n";
292 }
293
294 // First, build the pointer base class
295 if (base_class) {
296 ptrclass << "class " << class_name << "Ptr(" << *base_class << "):\n";
297 } else {
298 ptrclass << "class " << class_name << "Ptr :\n";
299 }
300
301 // *getattr << tab8 << "return self.__dict__[name]\n";
302 *getattr << tab8 << "raise AttributeError,name\n";
303 *setattr << tab8 << "self.__dict__[name] = value\n";
304
305 ptrclass << *cinit
306 << tab4 << "def __init__(self,this):\n"
307 << tab8 << "self.this = this\n"
308 << tab8 << "self.thisown = 0\n";
309
310 classes << ptrclass
311 << *pyclass;
312 if (have_setattr)
313 classes << *setattr;
314 if (have_getattr)
315 classes << *getattr;
316
317 if (!have_repr) {
318 // Supply a repr method for this class
319 repr << tab4 << "def __repr__(self):\n"
320 << tab8 << "return \"<C " << class_name <<" instance at %s>\" % (self.this,)\n";
321
322 classes << repr;
323 emitAddPragmas(classes,"__class__",tab4);
324 }
325
326 // Now build the real class with a normal constructor
327
328 classes << "class " << class_name << "(" << class_name << "Ptr):\n";
329
330 if (docstring && doc_entry) {
331 classes << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n";
332 }
333
334 classes << *construct << "\n\n"
335 << "\n" << *additional << "\n";
336
337 delete pyclass;
338 delete setattr;
339 delete getattr;
340 delete additional;
341 }
342 }
343
344 void PYTHON::cpp_cleanup() { };
345
346 void PYTHON::cpp_inherit(char **baseclass,int) {
347
348 char *bc;
349 int i = 0, first_base = 0;
350
351 if (!shadow) {
352 this->Language::cpp_inherit(baseclass);
353 return;
354 }
355
356 // We'll inherit variables and constants, but not methods
357
358 this->Language::cpp_inherit(baseclass, INHERIT_VAR);
359
360 if (!baseclass) return;
361 base_class = new String;
362
363 // Now tell the Python module that we're inheriting from a base class
364
365 while (baseclass[i]) {
366 bc = (char *) hash.lookup(baseclass[i]);
367 if (bc) {
368 if (first_base) *base_class << ",";
369 *base_class << bc << "Ptr";
370 first_base = 1;
371 }
372 i++;
373 }
374 if (!first_base) {
375 delete base_class;
376 base_class = 0;
377 }
378 }
379
380 // --------------------------------------------------------------------------------
381 // PYTHON::cpp_variable(char *name, char *iname, DataType *t)
382 //
383 // Adds an instance member.
384 // --------------------------------------------------------------------------------
385
386 void PYTHON::cpp_variable(char *name, char *iname, DataType *t) {
387 char *realname;
388 int inhash = 0;
389 int oldshadow = shadow;
390 String cname = "python:";
391
392 if (shadow) shadow = shadow | PYSHADOW_MEMBER;
393 this->Language::cpp_variable(name,iname,t);
394 shadow = oldshadow;
395
396 if (shadow) {
397 have_getattr = 1;
398 have_setattr = 1;
399 if (!iname)
400 realname = name;
401 else
402 realname = iname;
403
404 // Check to see if we've already seen this
405
406 cname << class_name << "::" << realname;
407 if (add_symbol(cname.get(), 0,0)) {
408 return; // Forget it, already seen it
409 }
410
411 // Figure out if we've seen this datatype before
412
413 if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) inhash = 1;
414
415 // Now write some code to set the variable
416 *setattr << tab8 << "if name == \"" << realname << "\" :\n";
417 if (inhash) {
418 *setattr << tab8 << tab4 << module << "." << name_set(name_member(realname,class_name)) << "(self,value.this)\n";
419 } else {
420 *setattr << tab8 << tab4 << module << "." << name_set(name_member(realname,class_name)) << "(self,value)\n";
421 }
422 *setattr << tab8 << tab4 << "return\n";
423
424 // Write some code to get the variable
425 *getattr << tab8 << "if name == \"" << realname << "\" : \n";
426 if (inhash) {
427 *getattr << tab8 << tab4 << "return " << (char *) hash.lookup(t->name) << "Ptr(" << module << "."
428 << name_get(name_member(realname,class_name)) << "(self))\n";
429 } else {
430 *getattr << tab8 << tab4 << "return " << module << "." << name_get(name_member(realname,class_name)) << "(self)\n";
431 }
432
433 // Patch up ye old documentation entry
434
435 if (doc_entry) {
436 doc_entry->usage = "";
437 doc_entry->usage << "self." << realname;
438 }
439 }
440 }
441
442 // --------------------------------------------------------------------------------
443 // PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value)
444 //
445 // Add access to a C++ constant
446 // --------------------------------------------------------------------------------
447
448 void PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value) {
449 char *realname;
450 int oldshadow = shadow;
451 String cname = "python:";
452
453 if (shadow) shadow = shadow | PYSHADOW_MEMBER;
454 this->Language::cpp_declare_const(name,iname,type,value);
455 shadow = oldshadow;
456
457 if (shadow) {
458 if (!iname)
459 realname = name;
460 else
461 realname = iname;
462
463 // Check to see if we've already seen this
464
465 cname << class_name << "::" << realname;
466 if (add_symbol(cname.get(), 0,0)) {
467 return; // Forget it, already seen it
468 }
469
470 *cinit << tab4 << realname << " = " << module << "." << name_member(realname,class_name) << "\n";
471
472 if (doc_entry) {
473 doc_entry->usage = "";
474 doc_entry->usage << "self." << realname;
475 if (value) {
476 doc_entry->usage << " = " << value;
477 }
478 }
479 }
480 }
481
482 // --------------------------------------------------------------------------------
483 // PYTHON::add_typedef(DataType *t, char *name)
484 //
485 // This is called whenever a typedef is encountered. When shadow classes are
486 // used, this function lets us discovered hidden uses of a class. For example :
487 //
488 // struct FooBar {
489 // ...
490 // }
491 //
492 // typedef FooBar *FooBarPtr;
493 //
494 // --------------------------------------------------------------------------------
495
496 void PYTHON::add_typedef(DataType *t, char *name) {
497
498 if (!shadow) return;
499
500 // First check to see if there aren't too many pointers
501
502 if (t->is_pointer > 1) return;
503
504 if (hash.lookup(name)) return; // Already added
505
506
507 // Now look up the datatype in our shadow class hash table
508
509 if (hash.lookup(t->name)) {
510
511 // Yep. This datatype is in the hash
512
513 // Put this types 'new' name into the hash
514
515 hash.add(name,copy_string((char *) hash.lookup(t->name)));
516 }
517 }