]>
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
)));