]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/Modules/pycpp.cxx
1 /*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
4 * Author : David Beazley
6 * Department of Computer Science
7 * University of Chicago
10 * beazley@cs.uchicago.edu
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
16 /**********************************************************************
21 * This module contains code to generate Python shadow classes of C/C++
23 **************************************************************************/
29 static String
*setattr
;
30 static String
*getattr
;
31 static String
*pyclass
;
32 static String
*construct
;
34 static String
*additional
;
35 static int have_constructor
;
36 static int have_destructor
;
37 static int have_getattr
;
38 static int have_setattr
;
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;
48 // --------------------------------------------------------------------------
49 // PYTHON::cpp_open_class(char *classname, char *rname, char *ctype, int strip)
51 // Opens a new C++ class or structure.
52 // --------------------------------------------------------------------------
54 void PYTHON::cpp_open_class(char *classname
, char *rname
, char *ctype
, int strip
) {
58 this->Language::cpp_open_class(classname
, rname
, ctype
, strip
);
61 /* Create new strings for building up a wrapper function */
63 setattr
= new String();
64 getattr
= new String();
65 pyclass
= new String();
66 construct
= new String();
68 additional
= new String();
74 // *pyclass << "class " << rname << ":\n";
75 *setattr
<< tab4
<< "def __setattr__(self,name,value):\n";
76 *getattr
<< tab4
<< "def __getattr__(self,name):\n";
83 class_name
= copy_string(rname
);
86 class_name
= copy_string(classname
);
91 real_classname
= copy_string(classname
);
92 class_type
= copy_string(ctype
);
94 // Build up the hash table
95 hash
.add(real_classname
,copy_string(class_name
));
97 sprintf(temp
,"%s %s", class_type
, real_classname
);
98 hash
.add(temp
,copy_string(class_name
));
102 // --------------------------------------------------------------------------
103 // PYTHON::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l)
105 // Creates a C++ member function
106 // --------------------------------------------------------------------------
108 void PYTHON::cpp_member_func(char *name
, char *iname
, DataType
*t
, ParmList
*l
) {
118 String cname
= "python:";
119 String translate
= "";
121 // Create the default member function
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
);
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
139 if (strcmp(realname
,"__repr__") == 0)
142 // Now add it to the class
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";
149 *pyclass
<< tab8
<< "val = apply(" << module << "." << name_member(realname
,class_name
) << ",(self,) + _args, _kwargs)\n";
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
))) {
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";
166 emitAddPragmas(*pyclass
, realname
, tab8
);
167 *pyclass
<< tab8
<< "return val\n";
169 // Change the usage string to reflect our shadow class
171 doc_entry
->usage
= "";
172 doc_entry
->usage
<< usage_func(realname
,t
,l
);
177 // -----------------------------------------------------------------------------
178 // void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l)
180 // Make a constructor for our class
181 // -----------------------------------------------------------------------------
183 void PYTHON::cpp_constructor(char *name
, char *iname
, ParmList
*l
) {
187 int oldshadow
= shadow
;
188 String cname
= "python:constructor:";
189 String translate
= "";
193 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
194 this->Language::cpp_constructor(name
,iname
,l
);
201 if (class_renamed
) realname
= class_name
;
202 else realname
= class_name
;
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
211 if (!have_constructor
) {
213 // Create a new constructor
215 *construct
<< tab4
<< "def __init__(self,*_args,**_kwargs):\n";
216 if (docstring
&& doc_entry
)
217 *construct
<< tab8
<< "\"\"\"" << add_docstring(doc_entry
) << "\"\"\"\n";
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;
225 // Hmmm. We seem to be creating a different constructor. We're just going to create a
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";
235 // Patch up the documentation entry
237 doc_entry
->usage
= "";
238 doc_entry
->usage
<< usage_func(class_name
,0,l
);
243 // ------------------------------------------------------------------------------
244 // void PYTHON::cpp_destructor(char *name, char *newname)
246 // Creates a destructor for this object
247 // ------------------------------------------------------------------------------
249 void PYTHON::cpp_destructor(char *name
, char *newname
) {
251 int oldshadow
= shadow
;
253 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
254 this->Language::cpp_destructor(name
,newname
);
257 if (newname
) realname
= newname
;
259 if (class_renamed
) realname
= class_name
;
260 else realname
= name
;
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";
270 doc_entry
->usage
= "";
271 doc_entry
->usage
<< "del this";
276 // -------------------------------------------------------------------------------
277 // PYTHON::cpp_close_class()
279 // Closes a Python class and writes out a wrapper
280 // -------------------------------------------------------------------------------
282 void PYTHON::cpp_close_class() {
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";
294 // First, build the pointer base class
296 ptrclass
<< "class " << class_name
<< "Ptr(" << *base_class
<< "):\n";
298 ptrclass
<< "class " << class_name
<< "Ptr :\n";
301 // *getattr << tab8 << "return self.__dict__[name]\n";
302 *getattr
<< tab8
<< "raise AttributeError,name\n";
303 *setattr
<< tab8
<< "self.__dict__[name] = value\n";
306 << tab4
<< "def __init__(self,this):\n"
307 << tab8
<< "self.this = this\n"
308 << tab8
<< "self.thisown = 0\n";
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";
323 emitAddPragmas(classes
,"__class__",tab4
);
326 // Now build the real class with a normal constructor
328 classes
<< "class " << class_name
<< "(" << class_name
<< "Ptr):\n";
330 if (docstring
&& doc_entry
) {
331 classes
<< tab4
<< "\"\"\"" << add_docstring(doc_entry
) << "\"\"\"\n";
334 classes
<< *construct
<< "\n\n"
335 << "\n" << *additional
<< "\n";
344 void PYTHON::cpp_cleanup() { };
346 void PYTHON::cpp_inherit(char **baseclass
,int) {
349 int i
= 0, first_base
= 0;
352 this->Language::cpp_inherit(baseclass
);
356 // We'll inherit variables and constants, but not methods
358 this->Language::cpp_inherit(baseclass
, INHERIT_VAR
);
360 if (!baseclass
) return;
361 base_class
= new String
;
363 // Now tell the Python module that we're inheriting from a base class
365 while (baseclass
[i
]) {
366 bc
= (char *) hash
.lookup(baseclass
[i
]);
368 if (first_base
) *base_class
<< ",";
369 *base_class
<< bc
<< "Ptr";
380 // --------------------------------------------------------------------------------
381 // PYTHON::cpp_variable(char *name, char *iname, DataType *t)
383 // Adds an instance member.
384 // --------------------------------------------------------------------------------
386 void PYTHON::cpp_variable(char *name
, char *iname
, DataType
*t
) {
389 int oldshadow
= shadow
;
390 String cname
= "python:";
392 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
393 this->Language::cpp_variable(name
,iname
,t
);
404 // Check to see if we've already seen this
406 cname
<< class_name
<< "::" << realname
;
407 if (add_symbol(cname
.get(), 0,0)) {
408 return; // Forget it, already seen it
411 // Figure out if we've seen this datatype before
413 if ((hash
.lookup(t
->name
)) && (t
->is_pointer
<= 1)) inhash
= 1;
415 // Now write some code to set the variable
416 *setattr
<< tab8
<< "if name == \"" << realname
<< "\" :\n";
418 *setattr
<< tab8
<< tab4
<< module << "." << name_set(name_member(realname
,class_name
)) << "(self,value.this)\n";
420 *setattr
<< tab8
<< tab4
<< module << "." << name_set(name_member(realname
,class_name
)) << "(self,value)\n";
422 *setattr
<< tab8
<< tab4
<< "return\n";
424 // Write some code to get the variable
425 *getattr
<< tab8
<< "if name == \"" << realname
<< "\" : \n";
427 *getattr
<< tab8
<< tab4
<< "return " << (char *) hash
.lookup(t
->name
) << "Ptr(" << module << "."
428 << name_get(name_member(realname
,class_name
)) << "(self))\n";
430 *getattr
<< tab8
<< tab4
<< "return " << module << "." << name_get(name_member(realname
,class_name
)) << "(self)\n";
433 // Patch up ye old documentation entry
436 doc_entry
->usage
= "";
437 doc_entry
->usage
<< "self." << realname
;
442 // --------------------------------------------------------------------------------
443 // PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value)
445 // Add access to a C++ constant
446 // --------------------------------------------------------------------------------
448 void PYTHON::cpp_declare_const(char *name
, char *iname
, DataType
*type
, char *value
) {
450 int oldshadow
= shadow
;
451 String cname
= "python:";
453 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
454 this->Language::cpp_declare_const(name
,iname
,type
,value
);
463 // Check to see if we've already seen this
465 cname
<< class_name
<< "::" << realname
;
466 if (add_symbol(cname
.get(), 0,0)) {
467 return; // Forget it, already seen it
470 *cinit
<< tab4
<< realname
<< " = " << module << "." << name_member(realname
,class_name
) << "\n";
473 doc_entry
->usage
= "";
474 doc_entry
->usage
<< "self." << realname
;
476 doc_entry
->usage
<< " = " << value
;
482 // --------------------------------------------------------------------------------
483 // PYTHON::add_typedef(DataType *t, char *name)
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 :
492 // typedef FooBar *FooBarPtr;
494 // --------------------------------------------------------------------------------
496 void PYTHON::add_typedef(DataType
*t
, char *name
) {
500 // First check to see if there aren't too many pointers
502 if (t
->is_pointer
> 1) return;
504 if (hash
.lookup(name
)) return; // Already added
507 // Now look up the datatype in our shadow class hash table
509 if (hash
.lookup(t
->name
)) {
511 // Yep. This datatype is in the hash
513 // Put this types 'new' name into the hash
515 hash
.add(name
,copy_string((char *) hash
.lookup(t
->name
)));