]>
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 = " << 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 = " << 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(" 
 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 \"<%s.%s instance; proxy of C++ " << class_name 
<<" instance at %s>\" % (self.__class__.__module__, self.__class__.__name__, 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
)));