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 = 0;
184  TMethodArg *a = 0;
185  TMethodArg *ar = 0;
186  TDataMember *member = 0;
187 
188  for (i=0; i<token_cnt;i++) {
189  cnt = 0;
190  ptr1 = R__STRTOK_R(tokens[i], "=>", &rest); // LeftHandedSide=methodarg
191  ptr2 = R__STRTOK_R((char *)0, "=>", &rest); // RightHandedSide-points to datamember
192 
193  //find the MethodArg
194  a = 0;
195  ar = 0;
196  member = 0;
197  TIter nextarg(fMethodArgs); // iterate through all arguments.
198  while ((ar = (TMethodArg*)nextarg())) {
199  if (!strcmp(ptr1,ar->GetName())) {
200  a = ar;
201  break;
202  }
203  }
204 
205  //now find the data member
207  if (cl) {
208  member = cl->GetDataMember(ptr2);
209  if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
210  //We can do it - friend decl. in MethodArg
211  }
212  delete [] tokens[i];
213  }
214  delete [] argstr;
215  return member; // nothing else to do! We return a pointer to the last
216  // found data member
217 
218  // if not found in comment string - try to guess it from name!
219  } else {
220  if (fMethodArgs)
221  if (fMethodArgs->GetSize() != 1) return 0;
222 
223  TMethodArg *a = 0;
224  if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());
225 
226  char dataname[67] = "";
227  char basename[64] = "";
228  const char *funcname = GetName();
229  if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
230  snprintf(basename,64,"%s",funcname+3);
231  else if ( strncmp(funcname,"Is",2) == 0 )
232  snprintf(basename,64,"%s",funcname+2);
233  else if (strncmp(funcname, "Has", 3) == 0)
234  snprintf(basename,64,"%s", funcname+3);
235  else
236  return 0;
237 
238  snprintf(dataname,67,"f%s",basename);
239 
240  TClass *cl = GetClass()->GetBaseDataMember(dataname);
241  if (cl) {
242  TDataMember *member = cl->GetDataMember(dataname);
243  if (a) a->fDataMember = member;
244  return member;
245  } else {
246  snprintf(dataname,67,"fIs%s",basename); //in case of IsEditable()
247  //and fIsEditable
248  cl = GetClass()->GetBaseDataMember(dataname);
249  if (cl) {
250  TDataMember *member = cl->GetDataMember(dataname);
251  if (a) a->fDataMember = member;
252  return member;
253  }
254  }
255  }
256 
257  //if nothing found - return null -pointer:
258  return 0;
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// Return call environment for the getter method in case this is a
263 /// *TOGGLE method (for the context menu).
264 
266 {
267  if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
268  fGetterMethod = new TMethodCall(fClass, Getter(), "");
269  }
270  return fGetterMethod;
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Return true if this function object is pointing to a currently
275 /// loaded function. If a function is unloaded after the TMethod
276 /// is created, the TMethod will be set to be invalid.
277 
279 {
280  // Register the transaction when checking the validity of the object.
282  DeclId_t newId = gInterpreter->GetFunction(fClass->GetClassInfo(), fName);
283  if (newId) {
284  MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
285  Update(info);
286  }
287  return newId != 0;
288  }
289  return fInfo != 0;
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Return call environment for this method in case this is a
294 /// *TOGGLE method which takes a single boolean or integer argument.
295 
297 {
298  if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
299  fSetterMethod = new TMethodCall(fClass, GetName(), "1");
300  }
301  return fSetterMethod;
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// Returns methodarg list and additionally updates fDataMember in TMethod by
306 /// calling FindDataMember();
307 
309 {
310  if (!fMethodArgs){
312  FindDataMember();
313  }
314  return fMethodArgs;
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Set the menu item as prescribed in the doctstring.
319 
320 void TMethod::SetMenuItem(const char *docstring)
321 {
322  if (docstring && strstr(docstring, "*TOGGLE")) {
324  const char *s;
325  if ((s = strstr(docstring, "*GETTER="))) {
326  fGetter = s+8;
328  }
329  } else
330  if (docstring && strstr(docstring, "*MENU"))
332  else
333  if (docstring && strstr(docstring, "*SUBMENU"))
335  else
337 }
338 
339 ////////////////////////////////////////////////////////////////////////////////
340 /// Update the TMethod to reflect the new info.
341 ///
342 /// This can be used to implement unloading (info == 0) and then reloading
343 /// (info being the 'new' decl address).
344 
345 Bool_t TMethod::Update(MethodInfo_t *info)
346 {
347  if (TFunction::Update(info)) {
348  delete fGetterMethod; fGetterMethod = 0;
349  delete fSetterMethod; fSetterMethod = 0;
350  if (fInfo) {
352  }
353  return kTRUE;
354  } else {
355  return kFALSE;
356  }
357 }
TMethod::GetListOfMethodArgs
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition: TMethod.cxx:308
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:265
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:2784
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:278
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
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:1106
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
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:168
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:918
TDataMember
Definition: TDataMember.h:31
TNamed::fName
TString fName
Definition: TNamed.h:38
TInterpreter::MethodInfo_Title
virtual const char * MethodInfo_Title(MethodInfo_t *) const
Definition: TInterpreter.h:506
Strlen.h
TClass.h
TList.h
TDictionary::DeclId_t
const typedef void * DeclId_t
Definition: TDictionary.h:209
bool
TClass::GetDataMember
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3318
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:658
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
a
auto * a
Definition: textangle.C:12
TNamed
Definition: TNamed.h:29
TMethod::GetClass
TClass * GetClass() const
Definition: TMethod.h:55
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TFunction::fMethodArgs
TList * fMethodArgs
Definition: TFunction.h:39
TMethod
Definition: TMethod.h:38
kMenuDialog
@ kMenuDialog
Definition: TMethod.h:33
TClass::GetClassInfo
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:390
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:93
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
Definition: TClass.h:80
ptr1
static byte * ptr1
Definition: gifdecode.c:16
TObject
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:296
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
Definition: TMethodCall.h:37
xmlio::cnt
const char * cnt
Definition: TXMLSetup.cxx:81
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:53
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
Definition: TFunction.h:30
TList
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:320
TMethod::Update
virtual Bool_t Update(MethodInfo_t *info)
Update the TMethod to reflect the new info.
Definition: TMethod.cxx:345
int
TMethodCall.h