// @(#)root/meta:$Name: $:$Id: TMethod.cxx,v 1.6 2004/03/12 08:53:04 brun Exp $
// Author: Rene Brun 09/02/95
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// Each ROOT class (see TClass) has a linked list of methods. //
// This class describes one single method (member function). //
// The method info is obtained via the CINT api. See class TCint. //
// //
// The method information is used a.o. by the THml class and by the //
// TTree class. //
// //
//////////////////////////////////////////////////////////////////////////
#include "TClass.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TMethodCall.h"
#include "TROOT.h"
#include "TApplication.h"
#include "TInterpreter.h"
#include "Strlen.h"
#include "Api.h"
#include "TDataMember.h"
ClassImp(TMethod)
//______________________________________________________________________________
TMethod::TMethod(G__MethodInfo *info, TClass *cl) : TFunction(info)
{
// Default TMethod ctor. TMethods are constructed in TClass.
// Comment strings are pre-parsed to find out whether the method is
// a context-menu item.
fClass = cl;
fGetterMethod = 0;
fSetterMethod = 0;
if (fInfo) {
const char *t = fInfo->Title();
if (t && strstr(t, "*TOGGLE")) {
fMenuItem = kMenuToggle;
const char *s;
if ((s = strstr(t, "*GETTER="))) {
fGetter = s+8;
fGetter = fGetter.Strip(TString::kBoth);
}
} else
if (t && strstr(t, "*MENU"))
fMenuItem = kMenuDialog;
else
if (t && strstr(t, "*SUBMENU"))
{
fMenuItem = kMenuSubMenu;
}
else
fMenuItem = kMenuNoMenu;
}
}
//______________________________________________________________________________
TMethod::TMethod(const TMethod& orig) : TFunction(orig)
{
// Copy ctor.
fClass = orig.fClass;
fMenuItem = orig.fMenuItem;
fGetter = orig.fGetter;
fGetterMethod = 0;
fSetterMethod = 0;
}
//______________________________________________________________________________
TMethod& TMethod::operator=(const TMethod& rhs)
{
// Assignment operator.
if (this != &rhs) {
TFunction::operator=(rhs);
fClass = rhs.fClass;
fMenuItem = rhs.fMenuItem;
fGetter = rhs.fGetter;
if (fGetterMethod)
delete fGetterMethod;
fGetterMethod = 0;
if (fSetterMethod)
delete fSetterMethod;
fSetterMethod = 0;
}
return *this;
}
//______________________________________________________________________________
TMethod::~TMethod()
{
// Cleanup.
delete fGetterMethod;
delete fSetterMethod;
}
//______________________________________________________________________________
TObject *TMethod::Clone(const char *newname) const
{
// Clone method.
TNamed *newobj = new TMethod(*this);
if (newname && strlen(newname)) newobj->SetName(newname);
return newobj;
}
//______________________________________________________________________________
const char *TMethod::GetCommentString()
{
// Returns a comment string from the class declaration.
return fInfo->Title();
}
//______________________________________________________________________________
void TMethod::CreateSignature()
{
// Using the CINT method arg information create a complete signature string.
TFunction::CreateSignature();
if (Property() & kIsConstant) fSignature += " const";
}
//______________________________________________________________________________
TDataMember *TMethod::FindDataMember()
{
// Tries to guess DataMember from comment string
// and Method's name <==(only if 1 Argument!).
// If more then one argument=> returns pointer to the last argument.
// It also sets MethodArgs' pointers to point to specified data members.
//
// The form of comment string defining arguments is:
// void XXX(Int_t x1, Float_t y2) //*ARGS={x1=>fX1,y2=>fY2}
// where fX1, fY2 are data fields in the same class.
// ("pointers" to data members)
Char_t *argstring = (char*)strstr(GetCommentString(),"*ARGS={");
// the following statement has been commented (Rene). Not needed
// it was making troubles in BuildRealData for classes with protected
// default constructors.
// if (!(GetClass()->GetListOfRealData())) GetClass()->BuildRealData();
if (argstring) {
// if we found any argument-specifying hints - parse it
if (!fMethodArgs) return 0;
char argstr[2048]; // workspace...
char *ptr1 = 0;
char *tok = 0;
char *ptr2 = 0;
Int_t i;
strcpy(argstr,argstring); //let's move it to "worksapce" copy
ptr2 = strtok(argstr,"{}"); //extract the data!
ptr2 = strtok((char*)0,"{}");
//extract argument tokens//
char *tokens[20];
Int_t cnt = 0;
Int_t token_cnt = 0;
do {
ptr1 = strtok((char*) (cnt++ ? 0:ptr2),",;"); //extract tokens
// separated by , or ;
if (ptr1) {
tok = new char[strlen(ptr1)+1];
strcpy(tok,ptr1);
tokens[token_cnt] = tok; //store this token.
token_cnt++;
}
} while (ptr1);
//now let's parse all argument tokens...
TClass *cl = 0;
TMethodArg *a = 0;
TMethodArg *ar = 0;
TDataMember *member = 0;
for (i=0; i<token_cnt;i++) {
cnt = 0;
ptr1 = strtok(tokens[i],"=>"); //LeftHandedSide=methodarg
ptr2 = strtok((char*)0,"=>"); //RightHandedSide-points to datamember
//find the MethodArg
a = 0;
ar = 0;
member = 0;
TIter nextarg(fMethodArgs); // iterate through all arguments.
while ((ar = (TMethodArg*)nextarg())) {
if (!strcmp(ptr1,ar->GetName())) {
a = ar;
break;
}
}
//now find the data member
cl = GetClass()->GetBaseDataMember(ptr2);
if (cl) {
member = cl->GetDataMember(ptr2);
if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
//We can do it - friend decl. in MethodArg
}
delete tokens[i];
}
return member; // nothing else to do! We return a pointer to the last
// found data member
// if not found in comment string - try to guess it from name!
} else {
if (fMethodArgs)
if (fMethodArgs->GetSize() != 1) return 0;
TMethodArg *a = 0;
if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());
char dataname[64] = "";
char basename[64] = "";
const char *funcname = GetName();
if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
sprintf(basename,"%s",funcname+3);
else if ( strncmp(funcname,"Is",2) == 0 )
sprintf(basename,"%s",funcname+2);
else if (strncmp(funcname, "Has", 3) == 0)
sprintf(basename, "%s", funcname+3);
else
return 0;
sprintf(dataname,"f%s",basename);
TClass *cl = GetClass()->GetBaseDataMember(dataname);
if (cl) {
TDataMember *member = cl->GetDataMember(dataname);
if (a) a->fDataMember = member;
return member;
} else {
sprintf(dataname,"fIs%s",basename); //in case of IsEditable()
//and fIsEditable
cl = GetClass()->GetBaseDataMember(dataname);
if (cl) {
TDataMember *member = cl->GetDataMember(dataname);
if (a) a->fDataMember = member;
return member;
}
}
}
//if nothing found - return null -pointer:
return 0;
}
//______________________________________________________________________________
TMethodCall *TMethod::GetterMethod()
{
// Return call environment for the getter method in case this is a
// *TOGGLE method (for the context menu).
if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
fGetterMethod = new TMethodCall(fClass, Getter(), "");
}
return fGetterMethod;
}
//______________________________________________________________________________
TMethodCall *TMethod::SetterMethod()
{
// Return call environment for this method in case this is a
// *TOGGLE method which takes a single boolean or integer argument.
if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
fSetterMethod = new TMethodCall(fClass, GetName(), "1");
}
return fSetterMethod;
}
//______________________________________________________________________________
TList *TMethod::GetListOfMethodArgs()
{
// Returns methodarg list and additionally updates fDataMember in TMethod by
// calling FindDataMember();
if (!fMethodArgs){
TFunction::GetListOfMethodArgs();
FindDataMember();
}
return fMethodArgs;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.