00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "TInterpreter.h"
00027 #include "TMethodCall.h"
00028 #include "TMethod.h"
00029 #include "TClass.h"
00030 #include "TROOT.h"
00031 #include "Strlen.h"
00032 #include "TVirtualMutex.h"
00033
00034 ClassImp(TMethodCall)
00035
00036
00037 TMethodCall::TMethodCall()
00038 {
00039
00040
00041
00042 fFunc = 0;
00043 fOffset = 0;
00044 fClass = 0;
00045 fMetPtr = 0;
00046 fMethod = "";
00047 fParams = "";
00048 fProto = "";
00049 fDtorOnly = kFALSE;
00050 fRetType = kNone;
00051 }
00052
00053
00054 TMethodCall::TMethodCall(TClass *cl, const char *method, const char *params)
00055 {
00056
00057
00058
00059
00060
00061
00062 fFunc = 0;
00063
00064 Init(cl, method, params);
00065 }
00066
00067
00068 TMethodCall::TMethodCall(const char *function, const char *params)
00069 {
00070
00071
00072
00073
00074
00075
00076 fFunc = 0;
00077
00078 Init(function, params);
00079 }
00080
00081
00082 TMethodCall::TMethodCall(const TMethodCall &orig) : TObject(orig)
00083 {
00084
00085
00086 fFunc = orig.fFunc ? gCint->CallFunc_FactoryCopy(orig.fFunc) : 0;
00087 fOffset = orig.fOffset;
00088 fClass = orig.fClass;
00089 fMethod = orig.fMethod;
00090 fParams = orig.fParams;
00091 fProto = orig.fProto;
00092 fDtorOnly = orig.fDtorOnly;
00093 fRetType = orig.fRetType;
00094
00095 fMetPtr = 0;
00096 }
00097
00098
00099 TMethodCall &TMethodCall::operator=(const TMethodCall &rhs)
00100 {
00101
00102
00103 if (this != &rhs) {
00104 gCint->CallFunc_Delete(fFunc);
00105 fFunc = rhs.fFunc ? gCint->CallFunc_FactoryCopy(rhs.fFunc) : 0;
00106 fOffset = rhs.fOffset;
00107 fClass = rhs.fClass;
00108 fMethod = rhs.fMethod;
00109 fParams = rhs.fParams;
00110 fProto = rhs.fProto;
00111 fDtorOnly = rhs.fDtorOnly;
00112 fRetType = rhs.fRetType;
00113
00114 delete fMetPtr;
00115 fMetPtr = 0;
00116 }
00117
00118 return *this;
00119 }
00120
00121
00122 TMethodCall::~TMethodCall()
00123 {
00124
00125
00126 gCint->CallFunc_Delete(fFunc);
00127 delete fMetPtr;
00128 }
00129
00130
00131 TObject *TMethodCall::Clone(const char *) const
00132 {
00133
00134
00135 TObject *newobj = new TMethodCall(*this);
00136 return newobj;
00137 }
00138
00139
00140 static TClass *R__FindScope(const char *function, UInt_t &pos, ClassInfo_t *cinfo)
00141 {
00142
00143
00144
00145 if (function) {
00146 UInt_t nested = 0;
00147 for(int i=strlen(function); i>=0; --i) {
00148 switch(function[i]) {
00149 case '<': --nested; break;
00150 case '>': ++nested; break;
00151 case ':':
00152 if (nested==0) {
00153 if (i>2 && function[i-1]==':') {
00154 TString scope(function);
00155 scope[i-1] = 0;
00156 pos = i+1;
00157 TClass *cl = TClass::GetClass(scope);
00158 if (!cl) gCint->ClassInfo_Init(cinfo, scope);
00159 return cl;
00160 }
00161 }
00162 break;
00163 }
00164 }
00165 }
00166 return 0;
00167 }
00168
00169
00170 void TMethodCall::Init(TClass *cl, const char *method, const char *params)
00171 {
00172
00173
00174
00175
00176
00177
00178
00179 ClassInfo_t *cinfo = gCint->ClassInfo_Factory();
00180 if (!cl) {
00181 UInt_t pos = 0;
00182 cl = R__FindScope(method,pos,cinfo);
00183 method = method+pos;
00184 }
00185 InitImplementation(method,params,0,cl,cinfo);
00186 gCint->ClassInfo_Delete(cinfo);
00187 }
00188
00189
00190 void TMethodCall::Init(const char *function, const char *params)
00191 {
00192
00193
00194
00195
00196
00197
00198
00199 UInt_t pos = 0;
00200 ClassInfo_t *cinfo = gCint->ClassInfo_Factory();
00201 TClass *cl = R__FindScope(function,pos,cinfo);
00202 InitImplementation(function+pos, params, 0, cl, cinfo);
00203 gCint->ClassInfo_Delete(cinfo);
00204 }
00205
00206
00207 void TMethodCall::InitImplementation(const char *methodname, const char *params,
00208 const char *proto, TClass *cl,
00209 const ClassInfo_t *cinfo)
00210 {
00211
00212
00213
00214
00215
00216 if (!fFunc)
00217 fFunc = gCint->CallFunc_Factory();
00218 else
00219 gCint->CallFunc_Init(fFunc);
00220
00221 fClass = cl;
00222 fMetPtr = 0;
00223 fMethod = methodname;
00224 fParams = params ? params : "";
00225 fProto = proto ? proto : "";
00226 fDtorOnly = kFALSE;
00227 fRetType = kNone;
00228
00229 ClassInfo_t *scope = 0;
00230 ClassInfo_t *global = gCint->ClassInfo_Factory();
00231 if (cl) scope = (ClassInfo_t*)cl->GetClassInfo();
00232 else scope = (ClassInfo_t*)cinfo;
00233
00234 if (!scope) return;
00235
00236 R__LOCKGUARD2(gCINTMutex);
00237 if (params && params[0]) {
00238 gCint->CallFunc_SetFunc(fFunc, scope, (char *)methodname, (char *)params, &fOffset);
00239 } else if (proto && proto[0]) {
00240 gCint->CallFunc_SetFuncProto(fFunc, scope, (char *)methodname, (char *)proto, &fOffset);
00241 } else {
00242
00243 gCint->CallFunc_SetFunc(fFunc, scope, (char *)methodname, "", &fOffset);
00244 }
00245
00246 gCint->ClassInfo_Delete(global);
00247 }
00248
00249
00250 void TMethodCall::InitWithPrototype(TClass *cl, const char *method, const char *proto)
00251 {
00252
00253
00254
00255
00256
00257
00258
00259 ClassInfo_t *cinfo = gCint->ClassInfo_Factory();
00260 if (!cl) {
00261 UInt_t pos = 0;
00262 cl = R__FindScope(method,pos,cinfo);
00263 method = method+pos;
00264 }
00265 InitImplementation(method, 0, proto, cl, cinfo);
00266 gCint->ClassInfo_Delete(cinfo);
00267 }
00268
00269
00270 void TMethodCall::InitWithPrototype(const char *function, const char *proto)
00271 {
00272
00273
00274
00275
00276
00277
00278
00279 UInt_t pos = 0;
00280 ClassInfo_t *cinfo = gCint->ClassInfo_Factory();
00281 TClass *cl = R__FindScope(function,pos,cinfo);
00282 InitImplementation(function+pos, 0, proto, cl, cinfo);
00283 gCint->ClassInfo_Delete(cinfo);
00284 }
00285
00286
00287 Bool_t TMethodCall::IsValid() const
00288 {
00289
00290
00291
00292 return fFunc ? gCint->CallFunc_IsValid(fFunc) : kFALSE;
00293 }
00294
00295
00296 TFunction *TMethodCall::GetMethod()
00297 {
00298
00299
00300
00301
00302
00303
00304
00305 if (!fMetPtr) {
00306 if (fClass) {
00307 if (fProto == "") {
00308 fMetPtr = fClass->GetMethod(fMethod.Data(), fParams.Data());
00309 } else {
00310 fMetPtr = fClass->GetMethodWithPrototype(fMethod.Data(), fProto.Data());
00311 }
00312 TMethod *met = dynamic_cast<TMethod*>(fMetPtr);
00313 if (met) fMetPtr = new TMethod(*met);
00314 } else {
00315 if (fProto == "")
00316 fMetPtr = gROOT->GetGlobalFunction(fMethod.Data(), fParams.Data(), kTRUE);
00317 else
00318 fMetPtr = gROOT->GetGlobalFunctionWithPrototype(fMethod.Data(), fProto.Data(), kTRUE);
00319 if (fMetPtr) fMetPtr = new TFunction(*fMetPtr);
00320 }
00321 }
00322
00323 return fMetPtr;
00324 }
00325
00326
00327 void TMethodCall::Execute(void *object)
00328 {
00329
00330
00331 if (!fFunc) return;
00332
00333 R__LOCKGUARD2(gCINTMutex);
00334 void *address = 0;
00335 if (object) address = (void*)((Long_t)object + fOffset);
00336 gCint->SetTempLevel(1);
00337 if (fDtorOnly) {
00338 Long_t saveglobalvar = gCint->Getgvp();
00339 gCint->Setgvp((Long_t)address);
00340 gCint->CallFunc_Exec(fFunc,address);
00341 gCint->Setgvp(saveglobalvar);
00342 } else
00343 gCint->CallFunc_Exec(fFunc,address);
00344 gCint->SetTempLevel(-1);
00345 }
00346
00347
00348 void TMethodCall::Execute(void *object, const char *params)
00349 {
00350
00351
00352 if (!fFunc) return;
00353
00354 R__LOCKGUARD2(gCINTMutex);
00355 gCint->CallFunc_SetArgs(fFunc, (char *)params);
00356
00357 void *address = 0;
00358 if (object) address = (void*)((Long_t)object + fOffset);
00359 gCint->SetTempLevel(1);
00360 gCint->CallFunc_Exec(fFunc,address);
00361 gCint->SetTempLevel(-1);
00362 }
00363
00364
00365 void TMethodCall::Execute(void *object, Long_t &retLong)
00366 {
00367
00368
00369 if (!fFunc) return;
00370
00371 R__LOCKGUARD2(gCINTMutex);
00372 void *address = 0;
00373 if (object) address = (void*)((Long_t)object + fOffset);
00374 gCint->SetTempLevel(1);
00375 retLong = gCint->CallFunc_ExecInt(fFunc,address);
00376 gCint->SetTempLevel(-1);
00377 }
00378
00379
00380 void TMethodCall::Execute(void *object, const char *params, Long_t &retLong)
00381 {
00382
00383
00384 if (!fFunc) return;
00385
00386 R__LOCKGUARD2(gCINTMutex);
00387 gCint->CallFunc_SetArgs(fFunc, (char *)params);
00388
00389 void *address = 0;
00390 if (object) address = (void*)((Long_t)object + fOffset);
00391 gCint->SetTempLevel(1);
00392 retLong = gCint->CallFunc_ExecInt(fFunc,address);
00393 gCint->SetTempLevel(-1);
00394 }
00395
00396
00397 void TMethodCall::Execute(void *object, Double_t &retDouble)
00398 {
00399
00400
00401 if (!fFunc) return;
00402
00403 R__LOCKGUARD2(gCINTMutex);
00404 void *address = 0;
00405 if (object) address = (void*)((Long_t)object + fOffset);
00406 gCint->SetTempLevel(1);
00407 retDouble = gCint->CallFunc_ExecDouble(fFunc,address);
00408 gCint->SetTempLevel(-1);
00409 }
00410
00411
00412 void TMethodCall::Execute(void *object, const char *params, Double_t &retDouble)
00413 {
00414
00415
00416 if (!fFunc) return;
00417
00418 R__LOCKGUARD2(gCINTMutex);
00419 gCint->CallFunc_SetArgs(fFunc, (char *)params);
00420
00421 void *address = 0;
00422 if (object) address = (void*)((Long_t)object + fOffset);
00423 gCint->SetTempLevel(1);
00424 retDouble = gCint->CallFunc_ExecDouble(fFunc,address);
00425 gCint->SetTempLevel(-1);
00426 }
00427
00428
00429 void TMethodCall::Execute(void *object, char **retText)
00430 {
00431
00432
00433 if (!fFunc) return;
00434
00435 R__LOCKGUARD2(gCINTMutex);
00436 void *address = 0;
00437 if (object) address = (void*)((Long_t)object + fOffset);
00438 gCint->SetTempLevel(1);
00439 *retText =(char*) (gCint->CallFunc_ExecInt(fFunc,address));
00440 gCint->SetTempLevel(-1);
00441 }
00442
00443
00444 void TMethodCall::Execute(void *object, const char *params, char **retText)
00445 {
00446
00447
00448 if (!fFunc) return;
00449
00450 R__LOCKGUARD2(gCINTMutex);
00451 gCint->CallFunc_SetArgs(fFunc, (char *)params);
00452
00453 void *address = 0;
00454 if (object) address = (void*)((Long_t)object + fOffset);
00455 gCint->SetTempLevel(1);
00456 *retText =(char*)(gCint->CallFunc_ExecInt(fFunc,address));
00457 gCint->SetTempLevel(-1);
00458 }
00459
00460
00461 TMethodCall::EReturnType TMethodCall::ReturnType()
00462 {
00463
00464
00465
00466
00467 if ( fRetType == kNone) {
00468 TFunction *func = GetMethod();
00469 if (func == 0) {
00470 fRetType = kOther;
00471 Error("ReturnType","Unknown method");
00472 return kOther;
00473 }
00474
00475
00476 Int_t nstar = 0;
00477 const char* rettype = func->GetReturnTypeName();
00478 const char* returntype = rettype;
00479 while (*returntype) {
00480 if (*returntype == '*') nstar++;
00481 returntype++;
00482 }
00483
00484 TypedefInfo_t *atype = gCint->TypedefInfo_Factory();
00485 gCint->TypedefInfo_Init(atype,gCint->TypeName(rettype));
00486
00487
00488 const char *name = gCint->TypedefInfo_TrueName(atype);
00489
00490 Bool_t isEnum = kFALSE;
00491 TypeInfo_t *typed = 0;
00492 if (!strcmp("(unknown)",name)) {
00493 typed = gCint->TypeInfo_Factory();
00494 gCint->TypeInfo_Init(typed,func->GetReturnTypeName());
00495 name = gCint->TypeInfo_TrueName(typed);
00496 if (gCint->TypeInfo_Property(typed)&kIsEnum) {
00497 isEnum = kTRUE;
00498 }
00499 }
00500
00501 if ((nstar==1) &&
00502 (!strcmp("unsigned char", name) || !strcmp("char", name) ||
00503 !strcmp("UChar_t", name) || !strcmp("Char_t", name) ||
00504 !strcmp("const unsigned char", name) || !strcmp("const char", name) ||
00505 !strcmp("const UChar_t", name) || !strcmp("const Char_t", name) ||
00506 !strcmp("unsigned char*", name) || !strcmp("char*", name) ||
00507 !strcmp("UChar_t*", name) || !strcmp("Char_t*", name) ||
00508 !strcmp("const unsigned char*", name) || !strcmp("const char*", name) ||
00509 !strcmp("const UChar_t*", name) || !strcmp("const Char_t*", name)))
00510 fRetType = kString;
00511 else if (!strcmp("unsigned int", name) || !strcmp("int", name) ||
00512 !strcmp("unsigned long", name) || !strcmp("long", name) ||
00513 !strcmp("unsigned long long", name) || !strcmp("long long", name) ||
00514 !strcmp("unsigned short", name) || !strcmp("short", name) ||
00515 !strcmp("unsigned char", name) || !strcmp("char", name) ||
00516 !strcmp("UInt_t", name) || !strcmp("Int_t", name) ||
00517 !strcmp("ULong_t", name) || !strcmp("Long_t", name) ||
00518 !strcmp("ULong64_t", name) || !strcmp("Long_t64", name) ||
00519 !strcmp("UShort_t", name) || !strcmp("Short_t", name) ||
00520 !strcmp("UChar_t", name) || !strcmp("Char_t", name) ||
00521 !strcmp("Bool_t", name) || !strcmp("bool", name) ||
00522 strstr(name, "enum"))
00523 fRetType = kLong;
00524 else if (!strcmp("float", name) || !strcmp("double", name) ||
00525 !strcmp("Float_t", name) || !strcmp("Double_t", name))
00526 fRetType = kDouble;
00527 else if (isEnum)
00528 fRetType = kLong;
00529 else
00530 fRetType = kOther;
00531 gCint->TypeInfo_Delete(typed);
00532 gCint->TypedefInfo_Delete(atype);
00533
00534 }
00535
00536 return fRetType;
00537 }
00538
00539
00540 void TMethodCall::SetParamPtrs(void *paramArr, Int_t nparam)
00541 {
00542
00543
00544
00545
00546
00547
00548 if (!fFunc) return;
00549 R__LOCKGUARD2(gCINTMutex);
00550 gCint->CallFunc_SetArgArray(fFunc,(Long_t *)paramArr, nparam);
00551 }
00552
00553
00554 void TMethodCall::ResetParam()
00555 {
00556
00557
00558 if (!fFunc) return;
00559 gCint->CallFunc_ResetArg(fFunc);
00560 }
00561
00562
00563 void TMethodCall::SetParam(Long_t l)
00564 {
00565
00566
00567 if (!fFunc) return;
00568 gCint->CallFunc_SetArg(fFunc,l);
00569 }
00570
00571
00572 void TMethodCall::SetParam(Double_t d)
00573 {
00574
00575
00576 if (!fFunc) return;
00577 gCint->CallFunc_SetArg(fFunc,d);
00578 }
00579
00580
00581 void TMethodCall::SetParam(Long64_t ll)
00582 {
00583
00584
00585 if (!fFunc) return;
00586 gCint->CallFunc_SetArg(fFunc,ll);
00587 }
00588
00589
00590 void TMethodCall::SetParam(ULong64_t ull)
00591 {
00592
00593
00594 if (!fFunc) return;
00595 gCint->CallFunc_SetArg(fFunc,ull);
00596 }