]>
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 char* dfname
= name_destroy(realname
);
265 *pyclass
<< tab4
<< "def __del__(self, " << "delfunc=" << module<< "." << dfname
<< "):\n";
266 emitAddPragmas(*pyclass
,"__del__",tab8
);
267 *pyclass
<< tab8
<< "if self.thisown == 1:\n"
268 << tab8
<< tab4
<< "try:\n"
269 << tab8
<< tab8
<< "delfunc(self)\n"
270 << tab8
<< tab4
<< "except:\n"
271 << tab8
<< tab8
<< "pass\n";
275 doc_entry
->usage
= "";
276 doc_entry
->usage
<< "del this";
281 // -------------------------------------------------------------------------------
282 // PYTHON::cpp_close_class()
284 // Closes a Python class and writes out a wrapper
285 // -------------------------------------------------------------------------------
287 void PYTHON::cpp_close_class() {
293 if (!have_constructor
) {
294 // Build a constructor that takes a pointer to this kind of object
295 *construct
<< tab4
<< "def __init__(self,this):\n";
296 *construct
<< tab8
<< "self.this = this\n";
299 // First, build the pointer base class
301 ptrclass
<< "class " << class_name
<< "Ptr(" << *base_class
<< "):\n";
303 ptrclass
<< "class " << class_name
<< "Ptr :\n";
306 // *getattr << tab8 << "return self.__dict__[name]\n";
307 *getattr
<< tab8
<< "raise AttributeError,name\n";
308 *setattr
<< tab8
<< "self.__dict__[name] = value\n";
311 << tab4
<< "def __init__(self,this):\n"
312 << tab8
<< "self.this = this\n"
313 << tab8
<< "self.thisown = 0\n";
323 // Supply a repr method for this class
324 repr
<< tab4
<< "def __repr__(self):\n"
325 << tab8
<< "return \"<C " << class_name
<<" instance at %s>\" % (self.this,)\n";
328 emitAddPragmas(classes
,"__class__",tab4
);
331 // Now build the real class with a normal constructor
333 classes
<< "class " << class_name
<< "(" << class_name
<< "Ptr):\n";
335 if (docstring
&& doc_entry
) {
336 classes
<< tab4
<< "\"\"\"" << add_docstring(doc_entry
) << "\"\"\"\n";
339 classes
<< *construct
<< "\n\n"
340 << "\n" << *additional
<< "\n";
349 void PYTHON::cpp_cleanup() { };
351 void PYTHON::cpp_inherit(char **baseclass
,int) {
354 int i
= 0, first_base
= 0;
357 this->Language::cpp_inherit(baseclass
);
361 // We'll inherit variables and constants, but not methods
363 this->Language::cpp_inherit(baseclass
, INHERIT_VAR
);
365 if (!baseclass
) return;
366 base_class
= new String
;
368 // Now tell the Python module that we're inheriting from a base class
370 while (baseclass
[i
]) {
371 bc
= (char *) hash
.lookup(baseclass
[i
]);
373 if (first_base
) *base_class
<< ",";
374 *base_class
<< bc
<< "Ptr";
385 // --------------------------------------------------------------------------------
386 // PYTHON::cpp_variable(char *name, char *iname, DataType *t)
388 // Adds an instance member.
389 // --------------------------------------------------------------------------------
391 void PYTHON::cpp_variable(char *name
, char *iname
, DataType
*t
) {
394 int oldshadow
= shadow
;
395 String cname
= "python:";
397 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
398 this->Language::cpp_variable(name
,iname
,t
);
409 // Check to see if we've already seen this
411 cname
<< class_name
<< "::" << realname
;
412 if (add_symbol(cname
.get(), 0,0)) {
413 return; // Forget it, already seen it
416 // Figure out if we've seen this datatype before
418 if ((hash
.lookup(t
->name
)) && (t
->is_pointer
<= 1)) inhash
= 1;
420 // Now write some code to set the variable
421 *setattr
<< tab8
<< "if name == \"" << realname
<< "\" :\n";
423 *setattr
<< tab8
<< tab4
<< module << "." << name_set(name_member(realname
,class_name
)) << "(self,value.this)\n";
425 *setattr
<< tab8
<< tab4
<< module << "." << name_set(name_member(realname
,class_name
)) << "(self,value)\n";
427 *setattr
<< tab8
<< tab4
<< "return\n";
429 // Write some code to get the variable
430 *getattr
<< tab8
<< "if name == \"" << realname
<< "\" : \n";
432 *getattr
<< tab8
<< tab4
<< "return " << (char *) hash
.lookup(t
->name
) << "Ptr(" << module << "."
433 << name_get(name_member(realname
,class_name
)) << "(self))\n";
435 *getattr
<< tab8
<< tab4
<< "return " << module << "." << name_get(name_member(realname
,class_name
)) << "(self)\n";
438 // Patch up ye old documentation entry
441 doc_entry
->usage
= "";
442 doc_entry
->usage
<< "self." << realname
;
447 // --------------------------------------------------------------------------------
448 // PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value)
450 // Add access to a C++ constant
451 // --------------------------------------------------------------------------------
453 void PYTHON::cpp_declare_const(char *name
, char *iname
, DataType
*type
, char *value
) {
455 int oldshadow
= shadow
;
456 String cname
= "python:";
458 if (shadow
) shadow
= shadow
| PYSHADOW_MEMBER
;
459 this->Language::cpp_declare_const(name
,iname
,type
,value
);
468 // Check to see if we've already seen this
470 cname
<< class_name
<< "::" << realname
;
471 if (add_symbol(cname
.get(), 0,0)) {
472 return; // Forget it, already seen it
475 *cinit
<< tab4
<< realname
<< " = " << module << "." << name_member(realname
,class_name
) << "\n";
478 doc_entry
->usage
= "";
479 doc_entry
->usage
<< "self." << realname
;
481 doc_entry
->usage
<< " = " << value
;
487 // --------------------------------------------------------------------------------
488 // PYTHON::add_typedef(DataType *t, char *name)
490 // This is called whenever a typedef is encountered. When shadow classes are
491 // used, this function lets us discovered hidden uses of a class. For example :
497 // typedef FooBar *FooBarPtr;
499 // --------------------------------------------------------------------------------
501 void PYTHON::add_typedef(DataType
*t
, char *name
) {
505 // First check to see if there aren't too many pointers
507 if (t
->is_pointer
> 1) return;
509 if (hash
.lookup(name
)) return; // Already added
512 // Now look up the datatype in our shadow class hash table
514 if (hash
.lookup(t
->name
)) {
516 // Yep. This datatype is in the hash
518 // Put this types 'new' name into the hash
520 hash
.add(name
,copy_string((char *) hash
.lookup(t
->name
)));