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