Logo ROOT  
Reference Guide
TMethod.cxx
Go to the documentation of this file.
1 // @(#)root/meta:$Id$
2 // Author: Rene Brun 09/02/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TMethod
13  Each ROOT class (see TClass) has a linked list of methods.
14  This class describes one single method (member function).
15  The method info is obtained via the CINT api. See class TCling.
16 
17  The method information is used a.o. by the THml class and by the
18  TTree class.
19 */
20 
21 #include "strtok.h"
22 #include "strlcpy.h"
23 #include "snprintf.h"
24 #include "TClass.h"
25 #include "TList.h"
26 #include "TMethod.h"
27 #include "TMethodArg.h"
28 #include "TMethodCall.h"
29 #include "TInterpreter.h"
30 #include "Strlen.h"
31 #include "TDataMember.h"
32 
33 
35 
36 ////////////////////////////////////////////////////////////////////////////////
37 /// Default TMethod ctor. TMethods are constructed in TClass.
38 /// Comment strings are pre-parsed to find out whether the method is
39 /// a context-menu item.
40 
41 TMethod::TMethod(MethodInfo_t *info, TClass *cl) : TFunction(info)
42 {
43  fClass = cl;
44  fGetterMethod = 0;
45  fSetterMethod = 0;
47 
48  if (fInfo) {
50  }
51 }
52 
53 ////////////////////////////////////////////////////////////////////////////////
54 /// Copy ctor.
55 
56 TMethod::TMethod(const TMethod& orig) : TFunction(orig)
57 {
58  fClass = orig.fClass;
59  fMenuItem = orig.fMenuItem;
60  fGetter = orig.fGetter;
61  fGetterMethod = 0;
62  fSetterMethod = 0;
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// Assignment operator.
67 
69 {
70  if (this != &rhs) {
72  fClass = rhs.fClass;
73  fMenuItem = rhs.fMenuItem;
74  fGetter = rhs.fGetter;
75  if (fGetterMethod)
76  delete fGetterMethod;
77  fGetterMethod = 0;
78  if (fSetterMethod)
79  delete fSetterMethod;
80  fSetterMethod = 0;
81  }
82  return *this;
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// Cleanup.
87 
89 {
90  delete fGetterMethod;
91  delete fSetterMethod;
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Clone method.
96 
97 TObject *TMethod::Clone(const char *newname) const
98 {
99  TNamed *newobj = new TMethod(*this);
100  if (newname && strlen(newname)) newobj->SetName(newname);
101  return newobj;
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Returns a comment string from the class declaration.
106 
108 {
109  return fInfo ? gCling->MethodInfo_Title(fInfo) : "";
110 }
111 
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Using the CINT method arg information create a complete signature string.
115 
117 {
119 
120  if (Property() & kIsConstMethod) fSignature += " const";
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Tries to guess DataMember from comment string
125 /// and Method's name <==(only if 1 Argument!).
126 /// If more then one argument=> returns pointer to the last argument.
127 /// It also sets MethodArgs' pointers to point to specified data members.
128 ///
129 /// The form of comment string defining arguments is:
130 /// void XXX(Int_t x1, Float_t y2) //*ARGS={x1=>fX1,y2=>fY2}
131 /// where fX1, fY2 are data fields in the same class.
132 /// ("pointers" to data members)
133 
135 {
136  Char_t *argstring = (char*)strstr(GetCommentString(),"*ARGS={");
137 
138  // the following statement has been commented (Rene). Not needed
139  // it was making troubles in BuildRealData for classes with protected
140  // default constructors.
141  // if (!(GetClass()->GetListOfRealData())) GetClass()->BuildRealData();
142 
143  if (argstring) {
144 
145  // if we found any argument-specifying hints - parse it
146 
147  if (!fMethodArgs) return 0;
148 
149  Int_t nchs = strlen(argstring); // workspace...
150  char *argstr = new char[nchs+1]; // workspace...
151  char *ptr1 = 0;
152  char *tok = 0;
153  char *ptr2 = 0;
154  Int_t i;
155 
156  strlcpy(argstr,argstring,nchs+1); //let's move it to "workspace" copy
157  char *rest;
158  ptr2 = R__STRTOK_R(argstr, "{}", &rest); // extract the data!
159  if (ptr2 == 0) {
160  Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
161  delete [] argstr;
162  return 0;
163  }
164  ptr2 = R__STRTOK_R((char *)0, "{}", &rest);
165 
166  //extract argument tokens//
167  char *tokens[20];
168  Int_t cnt = 0;
169  Int_t token_cnt = 0;
170  do {
171  ptr1 = R__STRTOK_R((char *)(cnt++ ? 0 : ptr2), ",;", &rest); // extract tokens
172  // separated by , or ;
173  if (ptr1) {
174  Int_t nch = strlen(ptr1);
175  tok = new char[nch+1];
176  strlcpy(tok,ptr1,nch+1);
177  tokens[token_cnt] = tok; //store this token.
178  token_cnt++;
179  }
180  } while (ptr1);
181 
182  //now let's parse all argument tokens...
183  TClass *cl = nullptr;
184  TMethodArg *a = nullptr;
185  TMethodArg *ar = nullptr;
186  TDataMember *member = nullptr;
187 
188  for (i=0; i<token_cnt;i++) {
189  ptr1 = R__STRTOK_R(tokens[i], "=>", &rest); // LeftHandedSide=methodarg
190  ptr2 = R__STRTOK_R((char *) nullptr, "=>", &rest); // RightHandedSide-points to datamember
191 
192  //find the MethodArg
193  a = 0;
194  ar = 0;
195  member = 0;
196  TIter nextarg(fMethodArgs); // iterate through all arguments.
197  while ((ar = (TMethodArg*)nextarg())) {
198  if (!strcmp(ptr1,ar->GetName())) {
199  a = ar;
200  break;
201  }
202  }
203 
204  //now find the data member
206  if (cl) {
207  member = cl->GetDataMember(ptr2);
208  if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
209  //We can do it - friend decl. in MethodArg
210  }
211  delete [] tokens[i];
212  }
213  delete [] argstr;
214  return member; // nothing else to do! We return a pointer to the last
215  // found data member
216 
217  // if not found in comment string - try to guess it from name!
218  } else {
219  if (fMethodArgs)
220  if (fMethodArgs->GetSize() != 1) return 0;
221 
222  TMethodArg *a = 0;
223  if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());
224 
225  char dataname[67] = "";
226  char basename[64] = "";
227  const char *funcname = GetName();
228  if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
229  snprintf(basename,64,"%s",funcname+3);
230  else if ( strncmp(funcname,"Is",2) == 0 )
231  snprintf(basename,64,"%s",funcname+2);
232  else if (strncmp(funcname, "Has", 3) == 0)
233  snprintf(basename,64,"%s", funcname+3);
234  else
235  return 0;
236 
237  snprintf(dataname,67,"f%s",basename);
238 
239  TClass *cl = GetClass()->GetBaseDataMember(dataname);
240  if (cl) {
241  TDataMember *member = cl->GetDataMember(dataname);
242  if (a) a->fDataMember = member;
243  return member;
244  } else {
245  snprintf(dataname,67,"fIs%s",basename); //in case of IsEditable()
246  //and fIsEditable
247  cl = GetClass()->GetBaseDataMember(dataname);
248  if (cl) {
249  TDataMember *member = cl->GetDataMember(dataname);
250  if (a) a->fDataMember = member;
251  return member;
252  }
253  }
254  }
255 
256  //if nothing found - return null -pointer:
257  return 0;
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Return call environment for the getter method in case this is a
262 /// *TOGGLE method (for the context menu).
263 
265 {
266  if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
267  fGetterMethod = new TMethodCall(fClass, Getter(), "");
268  }
269  return fGetterMethod;
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Return true if this function object is pointing to a currently
274 /// loaded function. If a function is unloaded after the TMethod
275 /// is created, the TMethod will be set to be invalid.
276 
278 {
279  // Register the transaction when checking the validity of the object.
281  DeclId_t newId = gInterpreter->GetFunction(fClass->GetClassInfo(), fName);
282  if (newId) {
283  MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
284  Update(info);
285  }
286  return newId != 0;
287  }
288  return fInfo != 0;
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Return call environment for this method in case this is a
293 /// *TOGGLE method which takes a single boolean or integer argument.
294 
296 {
297  if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
298  fSetterMethod = new TMethodCall(fClass, GetName(), "1");
299  }
300  return fSetterMethod;
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Returns methodarg list and additionally updates fDataMember in TMethod by
305 /// calling FindDataMember();
306 
308 {
309  if (!fMethodArgs){
311  FindDataMember();
312  }
313  return fMethodArgs;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Set the menu item as prescribed in the doctstring.
318 
319 void TMethod::SetMenuItem(const char *docstring)
320 {
321  if (docstring && strstr(docstring, "*TOGGLE")) {
323  const char *s;
324  if ((s = strstr(docstring, "*GETTER="))) {
325  fGetter = s+8;
327  }
328  } else
329  if (docstring && strstr(docstring, "*MENU"))
331  else
332  if (docstring && strstr(docstring, "*SUBMENU"))
334  else
336 }
337 
338 ////////////////////////////////////////////////////////////////////////////////
339 /// Update the TMethod to reflect the new info.
340 ///
341 /// This can be used to implement unloading (info == 0) and then reloading
342 /// (info being the 'new' decl address).
343 
344 Bool_t TMethod::Update(MethodInfo_t *info)
345 {
346  if (TFunction::Update(info)) {
347  delete fGetterMethod; fGetterMethod = 0;
348  delete fSetterMethod; fSetterMethod = 0;
349  if (fInfo) {
351  }
352  return kTRUE;
353  } else {
354  return kFALSE;
355  }
356 }
TMethod::GetListOfMethodArgs
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition: TMethod.cxx:307
TMethod::GetterMethod
virtual TMethodCall * GetterMethod()
Return call environment for the getter method in case this is a *TOGGLE method (for the context menu)...
Definition: TMethod.cxx:264
TFunction::operator=
TFunction & operator=(const TFunction &rhs)
Assignment operator.
Definition: TFunction.cxx:63
TClass::GetBaseDataMember
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2805
TMethod::fMenuItem
EMenuItemKind fMenuItem
Definition: TMethod.h:42
TMethod::IsValid
virtual Bool_t IsValid()
Return true if this function object is pointing to a currently loaded function.
Definition: TMethod.cxx:277
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:95
snprintf
#define snprintf
Definition: civetweb.c:1540
TMethod::operator=
TMethod & operator=(const TMethod &rhs)
Assignment operator.
Definition: TMethod.cxx:68
TNamed::SetName
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
TString::Strip
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1128
ptr2
static byte * ptr2
Definition: gifdecode.c:17
TMethod::TMethod
TMethod(MethodInfo_t *info=0, TClass *cl=0)
Default TMethod ctor.
Definition: TMethod.cxx:41
TMethod::fGetterMethod
TMethodCall * fGetterMethod
Definition: TMethod.h:44
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TMethodArg
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:36
TMethod.h
TFunction::GetListOfMethodArgs
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:127
TFunction::fSignature
TString fSignature
Definition: TFunction.h:38
gInterpreter
#define gInterpreter
Definition: TInterpreter.h:560
TDataMember.h
TGeant4Unit::s
static constexpr double s
Definition: TGeant4SystemOfUnits.h:162
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:921
TDataMember
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
TNamed::fName
TString fName
Definition: TNamed.h:32
TInterpreter::MethodInfo_Title
virtual const char * MethodInfo_Title(MethodInfo_t *) const
Definition: TInterpreter.h:506
Strlen.h
TClass.h
TList.h
bool
TClass::GetDataMember
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3383
TString::kBoth
@ kBoth
Definition: TString.h:267
TFunction::fInfo
MethodInfo_t * fInfo
Definition: TFunction.h:36
TList::First
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:659
kMenuToggle
@ kMenuToggle
Definition: TMethod.h:34
TMethod::GetCommentString
virtual const char * GetCommentString()
Returns a comment string from the class declaration.
Definition: TMethod.cxx:107
TFunction::Property
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:184
TMethod::fClass
TClass * fClass
Definition: TMethod.h:41
TMethod::FindDataMember
virtual TDataMember * FindDataMember()
Tries to guess DataMember from comment string and Method's name <==(only if 1 Argument!...
Definition: TMethod.cxx:134
TDictionary::DeclId_t
const void * DeclId_t
Definition: TDictionary.h:223
a
auto * a
Definition: textangle.C:12
TNamed
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TMethod::GetClass
TClass * GetClass() const
Definition: TMethod.h:55
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:96
TFunction::fMethodArgs
TList * fMethodArgs
Definition: TFunction.h:39
TMethod
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
kMenuDialog
@ kMenuDialog
Definition: TMethod.h:33
TClass::GetClassInfo
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:430
TMethod::fGetter
TString fGetter
Definition: TMethod.h:43
TMethod::Getter
virtual const char * Getter() const
Definition: TMethod.h:59
TFunction::Update
virtual bool Update(MethodInfo_t *info)
Update the TFunction to reflect the new info.
Definition: TFunction.cxx:279
kIsConstMethod
@ kIsConstMethod
Definition: TDictionary.h:96
TMethod::fSetterMethod
TMethodCall * fSetterMethod
Definition: TMethod.h:45
TMethod::~TMethod
virtual ~TMethod()
Cleanup.
Definition: TMethod.cxx:88
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TInterpreter.h
TClass
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
ptr1
static byte * ptr1
Definition: gifdecode.c:16
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
gCling
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:561
TMethod::SetterMethod
virtual TMethodCall * SetterMethod()
Return call environment for this method in case this is a *TOGGLE method which takes a single boolean...
Definition: TMethod.cxx:295
TMethod::Clone
virtual TObject * Clone(const char *newname="") const
Clone method.
Definition: TMethod.cxx:97
TIter
Definition: TCollection.h:233
TDictionary::UpdateInterpreterStateMarker
Bool_t UpdateInterpreterStateMarker()
the Cling ID of the transaction that last updated the object
Definition: TDictionary.cxx:109
kMenuSubMenu
@ kMenuSubMenu
Definition: TMethod.h:35
TMethodCall
Method or function calling interface.
Definition: TMethodCall.h:37
xmlio::cnt
const char * cnt
Definition: TXMLSetup.cxx:75
kMenuNoMenu
@ kMenuNoMenu
Definition: TMethod.h:32
TMethod::CreateSignature
void CreateSignature()
Using the CINT method arg information create a complete signature string.
Definition: TMethod.cxx:116
TMethodArg.h
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TFunction::CreateSignature
virtual void CreateSignature()
Using the CINT method arg information to create a complete signature string.
Definition: TFunction.cxx:107
Char_t
char Char_t
Definition: RtypesCore.h:33
TFunction
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
TList
A doubly linked list.
Definition: TList.h:44
TFunction::TMethodCall
friend class TMethodCall
Definition: TFunction.h:33
TMethod::SetMenuItem
void SetMenuItem(const char *docstring)
Set the menu item as prescribed in the doctstring.
Definition: TMethod.cxx:319
TMethod::Update
virtual Bool_t Update(MethodInfo_t *info)
Update the TMethod to reflect the new info.
Definition: TMethod.cxx:344
int
TMethodCall.h