Logo ROOT   6.08/07
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;
44  fMenuItem = kMenuNoMenu;
45 
46  if (fInfo) {
47  SetMenuItem(gCling->MethodInfo_Title(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  ptr2 = strtok(argstr,"{}"); //extract the data!
156  if (ptr2 == 0) {
157  Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
158  delete [] argstr;
159  return 0;
160  }
161  ptr2 = strtok((char*)0,"{}");
162 
163  //extract argument tokens//
164  char *tokens[20];
165  Int_t cnt = 0;
166  Int_t token_cnt = 0;
167  do {
168  ptr1 = strtok((char*) (cnt++ ? 0:ptr2),",;"); //extract tokens
169  // separated by , or ;
170  if (ptr1) {
171  Int_t nch = strlen(ptr1);
172  tok = new char[nch+1];
173  strlcpy(tok,ptr1,nch+1);
174  tokens[token_cnt] = tok; //store this token.
175  token_cnt++;
176  }
177  } while (ptr1);
178 
179  //now let's parse all argument tokens...
180  TClass *cl = 0;
181  TMethodArg *a = 0;
182  TMethodArg *ar = 0;
183  TDataMember *member = 0;
184 
185  for (i=0; i<token_cnt;i++) {
186  cnt = 0;
187  ptr1 = strtok(tokens[i],"=>"); //LeftHandedSide=methodarg
188  ptr2 = strtok((char*)0,"=>"); //RightHandedSide-points to datamember
189 
190  //find the MethodArg
191  a = 0;
192  ar = 0;
193  member = 0;
194  TIter nextarg(fMethodArgs); // iterate through all arguments.
195  while ((ar = (TMethodArg*)nextarg())) {
196  if (!strcmp(ptr1,ar->GetName())) {
197  a = ar;
198  break;
199  }
200  }
201 
202  //now find the data member
203  cl = GetClass()->GetBaseDataMember(ptr2);
204  if (cl) {
205  member = cl->GetDataMember(ptr2);
206  if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
207  //We can do it - friend decl. in MethodArg
208  }
209  delete [] tokens[i];
210  }
211  delete [] argstr;
212  return member; // nothing else to do! We return a pointer to the last
213  // found data member
214 
215  // if not found in comment string - try to guess it from name!
216  } else {
217  if (fMethodArgs)
218  if (fMethodArgs->GetSize() != 1) return 0;
219 
220  TMethodArg *a = 0;
221  if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());
222 
223  char dataname[64] = "";
224  char basename[64] = "";
225  const char *funcname = GetName();
226  if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
227  snprintf(basename,64,"%s",funcname+3);
228  else if ( strncmp(funcname,"Is",2) == 0 )
229  snprintf(basename,64,"%s",funcname+2);
230  else if (strncmp(funcname, "Has", 3) == 0)
231  snprintf(basename,64,"%s", funcname+3);
232  else
233  return 0;
234 
235  snprintf(dataname,64,"f%s",basename);
236 
237  TClass *cl = GetClass()->GetBaseDataMember(dataname);
238  if (cl) {
239  TDataMember *member = cl->GetDataMember(dataname);
240  if (a) a->fDataMember = member;
241  return member;
242  } else {
243  snprintf(dataname,64,"fIs%s",basename); //in case of IsEditable()
244  //and fIsEditable
245  cl = GetClass()->GetBaseDataMember(dataname);
246  if (cl) {
247  TDataMember *member = cl->GetDataMember(dataname);
248  if (a) a->fDataMember = member;
249  return member;
250  }
251  }
252  }
253 
254  //if nothing found - return null -pointer:
255  return 0;
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Return call environment for the getter method in case this is a
260 /// *TOGGLE method (for the context menu).
261 
263 {
264  if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
265  fGetterMethod = new TMethodCall(fClass, Getter(), "");
266  }
267  return fGetterMethod;
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// Return true if this function object is pointing to a currently
272 /// loaded function. If a function is unloaded after the TMethod
273 /// is created, the TMethod will be set to be invalid.
274 
276 {
277  // Register the transaction when checking the validity of the object.
279  DeclId_t newId = gInterpreter->GetFunction(fClass->GetClassInfo(), fName);
280  if (newId) {
281  MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
282  Update(info);
283  }
284  return newId != 0;
285  }
286  return fInfo != 0;
287 }
288 
289 ////////////////////////////////////////////////////////////////////////////////
290 /// Return call environment for this method in case this is a
291 /// *TOGGLE method which takes a single boolean or integer argument.
292 
294 {
295  if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
296  fSetterMethod = new TMethodCall(fClass, GetName(), "1");
297  }
298  return fSetterMethod;
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Returns methodarg list and additionally updates fDataMember in TMethod by
303 /// calling FindDataMember();
304 
306 {
307  if (!fMethodArgs){
309  FindDataMember();
310  }
311  return fMethodArgs;
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Set the menu item as prescribed in the doctstring.
316 
317 void TMethod::SetMenuItem(const char *docstring)
318 {
319  if (docstring && strstr(docstring, "*TOGGLE")) {
321  const char *s;
322  if ((s = strstr(docstring, "*GETTER="))) {
323  fGetter = s+8;
325  }
326  } else
327  if (docstring && strstr(docstring, "*MENU"))
329  else
330  if (docstring && strstr(docstring, "*SUBMENU"))
332  else
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Update the TMethod to reflect the new info.
338 ///
339 /// This can be used to implement unloading (info == 0) and then reloading
340 /// (info being the 'new' decl address).
341 
342 Bool_t TMethod::Update(MethodInfo_t *info)
343 {
344  if (TFunction::Update(info)) {
345  delete fGetterMethod; fGetterMethod = 0;
346  delete fSetterMethod; fSetterMethod = 0;
347  if (fInfo) {
349  }
350  return kTRUE;
351  } else {
352  return kFALSE;
353  }
354 }
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:51
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:33
EMenuItemKind fMenuItem
Definition: TMethod.h:44
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:33
static byte * ptr1
Definition: gifdecode.c:16
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
virtual const char * Getter() const
Definition: TMethod.h:61
virtual Bool_t IsValid()
Return true if this function object is pointing to a currently loaded function.
Definition: TMethod.cxx:275
void SetMenuItem(const char *docstring)
Set the menu item as prescribed in the doctstring.
Definition: TMethod.cxx:317
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
#define gInterpreter
Definition: TInterpreter.h:517
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
TMethodCall * fSetterMethod
Definition: TMethod.h:47
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:36
TString fSignature
Definition: TFunction.h:38
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:33
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:391
virtual const char * MethodInfo_Title(MethodInfo_t *) const
Definition: TInterpreter.h:463
virtual const char * GetCommentString()
Returns a comment string from the class declaration.
Definition: TMethod.cxx:105
Method or function calling interface.
Definition: TMethodCall.h:41
TList * fMethodArgs
Definition: TFunction.h:39
A doubly linked list.
Definition: TList.h:47
virtual TMethodCall * SetterMethod()
Return call environment for this method in case this is a *TOGGLE method which takes a single boolean...
Definition: TMethod.cxx:293
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();...
Definition: TMethod.cxx:305
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:557
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:1070
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
TClass * fClass
Definition: TMethod.h:43
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2752
virtual TObject * Clone(const char *newname="") const
Clone method.
Definition: TMethod.cxx:95
TString fName
Definition: TNamed.h:36
virtual Bool_t Update(MethodInfo_t *info)
Update the TMethod to reflect the new info.
Definition: TMethod.cxx:342
virtual bool Update(MethodInfo_t *info)
Update the TFunction to reflect the new info.
Definition: TFunction.cxx:278
TString fGetter
Definition: TMethod.h:45
#define ClassImp(name)
Definition: Rtypes.h:279
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:30
virtual TMethodCall * GetterMethod()
Return call environment for the getter method in case this is a *TOGGLE method (for the context menu)...
Definition: TMethod.cxx:262
char Char_t
Definition: RtypesCore.h:29
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:40
TClass * GetClass() const
Definition: TMethod.h:57
#define snprintf
Definition: civetweb.c:822
virtual ~TMethod()
Cleanup.
Definition: TMethod.cxx:86
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3233
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:953
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:519
virtual Int_t GetSize() const
Definition: TCollection.h:95
TMethodCall * fGetterMethod
Definition: TMethod.h:46
const Bool_t kTRUE
Definition: Rtypes.h:91
const char * cnt
Definition: TXMLSetup.cxx:75
TDataMember * fDataMember
Definition: TMethodArg.h:43