TMethod.cxx

Go to the documentation of this file.
00001 // @(#)root/meta:$Id: TMethod.cxx 35864 2010-09-29 18:11:52Z pcanal $
00002 // Author: Rene Brun   09/02/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 //  Each ROOT class (see TClass) has a linked list of methods.          //
00015 //  This class describes one single method (member function).           //
00016 //  The method info is obtained via the CINT api. See class TCint.      //
00017 //                                                                      //
00018 //  The method information is used a.o. by the THml class and by the    //
00019 //  TTree class.                                                        //
00020 //                                                                      //
00021 //////////////////////////////////////////////////////////////////////////
00022 
00023 #include "TClass.h"
00024 #include "TMethod.h"
00025 #include "TMethodArg.h"
00026 #include "TMethodCall.h"
00027 #include "TROOT.h"
00028 #include "TApplication.h"
00029 #include "TInterpreter.h"
00030 #include "Strlen.h"
00031 #include "TDataMember.h"
00032 
00033 
00034 ClassImp(TMethod)
00035 
00036 //______________________________________________________________________________
00037 TMethod::TMethod(MethodInfo_t *info, TClass *cl) : TFunction(info)
00038 {
00039    // Default TMethod ctor. TMethods are constructed in TClass.
00040    // Comment strings are pre-parsed to find out whether the method is
00041    // a context-menu item.
00042 
00043    fClass        = cl;
00044    fGetterMethod = 0;
00045    fSetterMethod = 0;
00046    fMenuItem     = kMenuNoMenu;
00047 
00048    if (fInfo) {
00049       const char *t = gCint->MethodInfo_Title(fInfo);
00050 
00051       if (t && strstr(t, "*TOGGLE")) {
00052          fMenuItem = kMenuToggle;
00053          const char *s;
00054          if ((s = strstr(t, "*GETTER="))) {
00055             fGetter = s+8;
00056             fGetter = fGetter.Strip(TString::kBoth);
00057          }
00058       } else
00059       if (t && strstr(t, "*MENU"))
00060          fMenuItem = kMenuDialog;
00061       else
00062       if (t && strstr(t, "*SUBMENU"))
00063          {
00064          fMenuItem = kMenuSubMenu;
00065          }
00066       else
00067          fMenuItem = kMenuNoMenu;
00068    }
00069 }
00070 
00071 //______________________________________________________________________________
00072 TMethod::TMethod(const TMethod& orig) : TFunction(orig)
00073 {
00074    // Copy ctor.
00075 
00076    fClass        = orig.fClass;
00077    fMenuItem     = orig.fMenuItem;
00078    fGetter       = orig.fGetter;
00079    fGetterMethod = 0;
00080    fSetterMethod = 0;
00081 }
00082 
00083 //______________________________________________________________________________
00084 TMethod& TMethod::operator=(const TMethod& rhs)
00085 {
00086    // Assignment operator.
00087 
00088    if (this != &rhs) {
00089       TFunction::operator=(rhs);
00090       fClass        = rhs.fClass;
00091       fMenuItem     = rhs.fMenuItem;
00092       fGetter       = rhs.fGetter;
00093       if (fGetterMethod)
00094          delete fGetterMethod;
00095       fGetterMethod = 0;
00096       if (fSetterMethod)
00097          delete fSetterMethod;
00098       fSetterMethod = 0;
00099    }
00100    return *this;
00101 }
00102 
00103 //______________________________________________________________________________
00104 TMethod::~TMethod()
00105 {
00106    // Cleanup.
00107 
00108    delete fGetterMethod;
00109    delete fSetterMethod;
00110 }
00111 
00112 //______________________________________________________________________________
00113 TObject *TMethod::Clone(const char *newname) const
00114 {
00115    // Clone method.
00116 
00117    TNamed *newobj = new TMethod(*this);
00118    if (newname && strlen(newname)) newobj->SetName(newname);
00119    return newobj;
00120 }
00121 
00122 //______________________________________________________________________________
00123 const char *TMethod::GetCommentString()
00124 {
00125    // Returns a comment string from the class declaration.
00126 
00127    return gCint->MethodInfo_Title(fInfo);
00128 }
00129 
00130 
00131 //______________________________________________________________________________
00132 void TMethod::CreateSignature()
00133 {
00134    // Using the CINT method arg information create a complete signature string.
00135 
00136    TFunction::CreateSignature();
00137 
00138    if (Property() & kIsMethConst) fSignature += " const";
00139 }
00140 
00141 //______________________________________________________________________________
00142 TDataMember *TMethod::FindDataMember()
00143 {
00144    // Tries to guess DataMember from comment string
00145    // and Method's name <==(only if 1 Argument!).
00146    // If more then one argument=> returns pointer to the last argument.
00147    // It also sets MethodArgs' pointers to point to specified data members.
00148    //
00149    // The form of comment string defining arguments is:
00150    // void XXX(Int_t x1, Float_t y2) //*ARGS={x1=>fX1,y2=>fY2}
00151    // where fX1, fY2 are data fields in the same class.
00152    // ("pointers" to data members)
00153 
00154    Char_t *argstring = (char*)strstr(GetCommentString(),"*ARGS={");
00155 
00156    // the following statement has been commented (Rene). Not needed
00157    // it was making troubles in BuildRealData for classes with protected
00158    // default constructors.
00159    // if (!(GetClass()->GetListOfRealData())) GetClass()->BuildRealData();
00160 
00161    if (argstring) {
00162 
00163       // if we found any argument-specifying hints  - parse it
00164 
00165       if (!fMethodArgs) return 0;
00166 
00167       Int_t nchs = strlen(argstring);    // workspace...
00168       char *argstr = new char[nchs+1];   // workspace...
00169       char *ptr1 = 0;
00170       char *tok  = 0;
00171       char *ptr2 = 0;
00172       Int_t i;
00173 
00174       strlcpy(argstr,argstring,nchs+1);       //let's move it to "worksapce"  copy
00175       ptr2 = strtok(argstr,"{}");     //extract the data!
00176       if (ptr2 == 0) {
00177          Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
00178          delete [] argstr;
00179          return 0;
00180       }
00181       ptr2 = strtok((char*)0,"{}");
00182 
00183       //extract argument tokens//
00184       char *tokens[20];
00185       Int_t cnt       = 0;
00186       Int_t token_cnt = 0;
00187       do {
00188          ptr1 = strtok((char*) (cnt++ ? 0:ptr2),",;"); //extract tokens
00189                                                         // separated by , or ;
00190          if (ptr1) {
00191             Int_t nch = strlen(ptr1);
00192             tok = new char[nch+1];
00193             strlcpy(tok,ptr1,nch+1);
00194             tokens[token_cnt] = tok;            //store this token.
00195             token_cnt++;
00196          }
00197       } while (ptr1);
00198 
00199       //now let's  parse all argument tokens...
00200       TClass     *cl = 0;
00201       TMethodArg *a  = 0;
00202       TMethodArg *ar = 0;
00203       TDataMember *member = 0;
00204 
00205       for (i=0; i<token_cnt;i++) {
00206          cnt = 0;
00207          ptr1 = strtok(tokens[i],"=>");  //LeftHandedSide=methodarg
00208          ptr2 = strtok((char*)0,"=>"); //RightHandedSide-points to datamember
00209 
00210          //find the MethodArg
00211          a      = 0;
00212          ar     = 0;
00213          member = 0;
00214          TIter nextarg(fMethodArgs);     // iterate through all arguments.
00215          while ((ar = (TMethodArg*)nextarg())) {
00216             if (!strcmp(ptr1,ar->GetName())) {
00217                a = ar;
00218                break;
00219             }
00220          }
00221 
00222          //now find the data member
00223          cl = GetClass()->GetBaseDataMember(ptr2);
00224          if (cl) {
00225             member = cl->GetDataMember(ptr2);
00226             if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
00227                                      //We can do it - friend decl. in MethodArg
00228          }
00229          delete [] tokens[i];
00230       }
00231       delete [] argstr;
00232       return member; // nothing else to do! We return a pointer to the last
00233                      // found data member
00234 
00235    // if not found in comment string - try to guess it from name!
00236    } else {
00237       if (fMethodArgs)
00238          if (fMethodArgs->GetSize() != 1) return 0;
00239       
00240       TMethodArg *a = 0;
00241       if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());
00242 
00243       char dataname[64]    = "";
00244       char basename[64]    = "";
00245       const char *funcname = GetName();
00246       if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
00247          snprintf(basename,64,"%s",funcname+3);
00248       else if ( strncmp(funcname,"Is",2) == 0 )
00249          snprintf(basename,64,"%s",funcname+2);
00250       else if (strncmp(funcname, "Has", 3) == 0)
00251          snprintf(basename,64,"%s", funcname+3);
00252       else
00253          return 0;
00254 
00255       snprintf(dataname,64,"f%s",basename);
00256 
00257       TClass *cl = GetClass()->GetBaseDataMember(dataname);
00258       if (cl) {
00259          TDataMember *member   = cl->GetDataMember(dataname);
00260          if (a) a->fDataMember = member;
00261          return member;
00262       } else {
00263          snprintf(dataname,64,"fIs%s",basename);  //in case of IsEditable()
00264                                                         //and fIsEditable
00265          cl = GetClass()->GetBaseDataMember(dataname);
00266          if (cl) {
00267             TDataMember *member = cl->GetDataMember(dataname);
00268             if (a) a->fDataMember = member;
00269             return member;
00270          }
00271       }
00272    }
00273 
00274    //if nothing found - return null -pointer:
00275    return 0;
00276 }
00277 
00278 //______________________________________________________________________________
00279 TMethodCall *TMethod::GetterMethod()
00280 {
00281    // Return call environment for the getter method in case this is a
00282    // *TOGGLE method (for the context menu).
00283 
00284    if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
00285       fGetterMethod = new TMethodCall(fClass, Getter(), "");
00286    }
00287    return fGetterMethod;
00288 }
00289 
00290 //______________________________________________________________________________
00291 TMethodCall *TMethod::SetterMethod()
00292 {
00293    // Return call environment for this method in case this is a
00294    // *TOGGLE method which takes a single boolean or integer argument.
00295 
00296    if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
00297       fSetterMethod = new TMethodCall(fClass, GetName(), "1");
00298    }
00299    return fSetterMethod;
00300 }
00301 
00302 //______________________________________________________________________________
00303 TList *TMethod::GetListOfMethodArgs()
00304 {
00305    // Returns methodarg list and additionally updates fDataMember in TMethod by
00306    // calling FindDataMember();
00307 
00308    if (!fMethodArgs){
00309       TFunction::GetListOfMethodArgs();
00310       FindDataMember();
00311    }
00312    return fMethodArgs;
00313 }

Generated on Tue Jul 5 14:11:55 2011 for ROOT_528-00b_version by  doxygen 1.5.1