00001
00002
00003
00004
00005 #include "PyROOT.h"
00006 #include "TPyClassGenerator.h"
00007 #include "Utility.h"
00008 #include "TPyReturn.h"
00009
00010
00011 #include "TClass.h"
00012
00013
00014 #include "Api.h"
00015
00016
00017 #include <string>
00018 #include <typeinfo>
00019
00020
00021
00022 namespace {
00023
00024
00025 int PyCtorCallback( G__value* res, G__CONST char*, struct G__param* , int )
00026 {
00027 PyObject* pyclass = PyROOT::Utility::GetInstalledMethod( G__value_get_tagnum(res) );
00028 if ( ! pyclass )
00029 return 0;
00030
00031 PyObject* args = PyTuple_New( 0 );
00032 PyObject* result = PyObject_Call( pyclass, args, NULL );
00033 if ( ! result )
00034 PyErr_Print();
00035 Py_DECREF( args );
00036
00037 G__letint( res, 'u', (Long_t)result );
00038 res->ref = (Long_t)result;
00039
00040 G__linked_taginfo pti;
00041 pti.tagnum = -1;
00042 pti.tagtype = 'c';
00043
00044 PyObject* str = PyObject_Str( pyclass );
00045 std::string clName = PyROOT_PyUnicode_AsString( str );
00046 Py_DECREF( str );
00047
00048 clName = clName.substr( clName.rfind( '.' )+1, std::string::npos );
00049 pti.tagname = clName.c_str();
00050
00051 G__set_tagnum( res, G__get_linked_tagnum( &pti ) );
00052
00053 return ( 1 );
00054 }
00055
00056
00057 int PyMemFuncCallback( G__value* res, G__CONST char*, struct G__param* libp, int )
00058 {
00059 PyObject* pyfunc = PyROOT::Utility::GetInstalledMethod( G__value_get_tagnum(res) );
00060 if ( ! pyfunc )
00061 return 0;
00062
00063 PyObject* self = (PyObject*)G__getstructoffset();
00064 Py_INCREF( self );
00065
00066 PyObject* args = PyTuple_New( 1 + libp->paran );
00067 PyTuple_SetItem( args, 0, self );
00068 for ( int i = 0; i < libp->paran; ++i ) {
00069 PyObject* arg = 0;
00070 switch ( G__value_get_type(&libp->para[i]) ) {
00071 case 'd':
00072 arg = PyFloat_FromDouble( G__Mdouble(libp->para[i]) );
00073 break;
00074 case 'f':
00075 arg = PyFloat_FromDouble( (double)G__Mfloat(libp->para[i]) );
00076 break;
00077 case 'l':
00078 arg = PyLong_FromLong( G__Mlong(libp->para[i]) );
00079 break;
00080 case 'k':
00081 arg = PyLong_FromUnsignedLong( G__Mulong(libp->para[i] ) );
00082 break;
00083 case 'i':
00084 arg = PyInt_FromLong( (Long_t)G__Mint(libp->para[i]) );
00085 break;
00086 case 'h':
00087
00088 arg = PyLong_FromUnsignedLong( *(ULong_t*)((void*)G__Mlong(libp->para[i])) );
00089 break;
00090 case 's':
00091 arg = PyInt_FromLong( (Long_t)G__Mshort(libp->para[i]) );
00092 break;
00093 case 'r':
00094 arg = PyInt_FromLong( (Long_t)G__Mushort(libp->para[i]) );
00095 break;
00096 case 'u':
00097
00098 break;
00099 case 'c':
00100 char cc[2]; cc[0] = G__Mchar(libp->para[i]); cc[1] = '\0';
00101 arg = PyBytes_FromString( cc );
00102 break;
00103 case 'b':
00104
00105 break;
00106 case 'C':
00107 arg = PyBytes_FromString( (char*)G__Mlong(libp->para[i]) );
00108 break;
00109 }
00110
00111 if ( arg != 0 )
00112 PyTuple_SetItem( args, i+1, arg );
00113 else {
00114 PyErr_Format( PyExc_TypeError,
00115 "error converting parameter: %d (type: %c)", i, G__value_get_type(&libp->para[i]) );
00116 break;
00117 }
00118
00119 }
00120
00121 PyObject* result = 0;
00122 if ( ! PyErr_Occurred() )
00123 result = PyObject_Call( pyfunc, args, NULL );
00124 Py_DECREF( args );
00125
00126 if ( ! result )
00127 PyErr_Print();
00128
00129 TPyReturn* retval = new TPyReturn( result );
00130 G__letint( res, 'u', (Long_t)retval );
00131 res->ref = (Long_t)retval;
00132 G__set_tagnum( res, ((G__ClassInfo*)TPyReturn::Class()->GetClassInfo())->Tagnum() );
00133
00134 return ( 1 );
00135 }
00136
00137 }
00138
00139
00140
00141 TClass* TPyClassGenerator::GetClass( const char* name, Bool_t load )
00142 {
00143 return GetClass( name, load, kFALSE );
00144 }
00145
00146
00147 TClass* TPyClassGenerator::GetClass( const char* name, Bool_t load, Bool_t silent )
00148 {
00149
00150 if ( PyROOT::gDictLookupActive == kTRUE )
00151 return 0;
00152
00153 if ( ! load || ! name )
00154 return 0;
00155
00156
00157 std::string clName = name;
00158 std::string::size_type pos = clName.rfind( '.' );
00159
00160 if ( pos == std::string::npos )
00161 return 0;
00162
00163 std::string mdName = clName.substr( 0, pos );
00164 clName = clName.substr( pos+1, std::string::npos );
00165
00166
00167 if ( TClass::GetClass( clName.c_str(), load, silent ) )
00168 return TClass::GetClass( clName.c_str(), load, silent );
00169
00170
00171 PyObject* mod = PyImport_AddModule( const_cast< char* >( mdName.c_str() ) );
00172 if ( ! mod ) {
00173 PyErr_Clear();
00174 return 0;
00175 }
00176
00177 Py_INCREF( mod );
00178 PyObject* pyclass =
00179 PyDict_GetItemString( PyModule_GetDict( mod ), const_cast< char* >( clName.c_str() ) );
00180 Py_XINCREF( pyclass );
00181 Py_DECREF( mod );
00182
00183 if ( ! pyclass ) {
00184 PyErr_Clear();
00185 return 0;
00186 }
00187
00188
00189 PyObject* attrs = PyObject_Dir( pyclass );
00190 if ( ! attrs ) {
00191 PyErr_Clear();
00192 Py_DECREF( pyclass );
00193 return 0;
00194 }
00195
00196
00197 G__linked_taginfo pti;
00198 pti.tagnum = -1;
00199 pti.tagtype = 'c';
00200 pti.tagname = clName.c_str();
00201 G__add_compiledheader( (clName+".h").c_str() );
00202
00203 int tagnum = G__get_linked_tagnum( &pti );
00204
00205 G__tagtable_setup(
00206 tagnum, sizeof(PyObject), G__CPPLINK, 0x00020000, "", 0, 0 );
00207
00208 G__ClassInfo gcl( tagnum );
00209
00210 G__tag_memfunc_setup( tagnum );
00211
00212
00213 PyROOT::Utility::InstallMethod( &gcl, pyclass, clName, 0, "ellipsis", (void*)PyCtorCallback );
00214
00215
00216 for ( int i = 0; i < PyList_GET_SIZE( attrs ); ++i ) {
00217 PyObject* label = PyList_GET_ITEM( attrs, i );
00218 Py_INCREF( label );
00219 PyObject* attr = PyObject_GetAttr( pyclass, label );
00220
00221
00222 if ( PyCallable_Check( attr ) ) {
00223 std::string mtName = PyROOT_PyUnicode_AsString( label );
00224
00225
00226 if ( mtName != "__init__" ) {
00227 PyROOT::Utility::InstallMethod(
00228 &gcl, attr, mtName, "TPyReturn", "ellipsis", (void*)PyMemFuncCallback );
00229 }
00230 }
00231
00232 Py_DECREF( attr );
00233 Py_DECREF( label );
00234 }
00235
00236 G__tag_memfunc_reset();
00237
00238
00239 Py_DECREF( pyclass );
00240
00241 TClass* klass = new TClass( clName.c_str(), silent );
00242 TClass::AddClass( klass );
00243
00244 return klass;
00245 }
00246
00247
00248 TClass* TPyClassGenerator::GetClass( const type_info& typeinfo, Bool_t load, Bool_t silent )
00249 {
00250 return GetClass( typeinfo.name(), load, silent );
00251 }
00252
00253 TClass* TPyClassGenerator::GetClass( const type_info& typeinfo, Bool_t load )
00254 {
00255
00256 return GetClass( typeinfo.name(), load );
00257 }