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
41TMethod::TMethod(MethodInfo_t *info, TClass *cl) : TFunction(info)
42{
43 fClass = cl;
44 fGetterMethod = nullptr;
45 fSetterMethod = nullptr;
47
48 if (fInfo) {
50 }
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Copy ctor.
55
57{
58 fClass = orig.fClass;
59 fMenuItem = orig.fMenuItem;
60 fGetter = orig.fGetter;
61 fGetterMethod = nullptr;
62 fSetterMethod = nullptr;
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 = nullptr;
78 if (fSetterMethod)
79 delete fSetterMethod;
80 fSetterMethod = nullptr;
81 }
82 return *this;
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// Cleanup.
87
89{
90 delete fGetterMethod;
91 delete fSetterMethod;
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Clone method.
96
97TObject *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 nullptr;
148
149 Int_t nchs = strlen(argstring); // workspace...
150 char *argstr = new char[nchs+1]; // workspace...
151 char *ptr1 = nullptr;
152 char *tok = nullptr;
153 char *ptr2 = nullptr;
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 == nullptr) {
160 Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
161 delete [] argstr;
162 return nullptr;
163 }
164 ptr2 = R__STRTOK_R((char *)nullptr, "{}", &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++ ? nullptr : 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 = nullptr;
194 ar = nullptr;
195 member = nullptr;
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 nullptr;
221
222 TMethodArg *a = nullptr;
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 nullptr;
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 nullptr;
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) {
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 != nullptr;
287 }
288 return fInfo != nullptr;
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{
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){
312 }
313 return fMethodArgs;
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Set the menu item as prescribed in the doctstring.
318
319void 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
344Bool_t TMethod::Update(MethodInfo_t *info)
345{
346 if (TFunction::Update(info)) {
347 delete fGetterMethod; fGetterMethod = nullptr;
348 delete fSetterMethod; fSetterMethod = nullptr;
349 if (fInfo) {
351 }
352 return kTRUE;
353 } else {
354 return kFALSE;
355 }
356}
char Char_t
Definition: RtypesCore.h:37
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
@ kIsConstMethod
Definition: TDictionary.h:96
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:565
#define gInterpreter
Definition: TInterpreter.h:564
@ kMenuSubMenu
Definition: TMethod.h:35
@ kMenuDialog
Definition: TMethod.h:33
@ kMenuToggle
Definition: TMethod.h:34
@ kMenuNoMenu
Definition: TMethod.h:32
#define snprintf
Definition: civetweb.c:1540
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3428
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:431
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2827
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
Bool_t UpdateInterpreterStateMarker()
the Cling ID of the transaction that last updated the object
const void * DeclId_t
Definition: TDictionary.h:223
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:30
friend class TMethodCall
Definition: TFunction.h:33
TList * fMethodArgs
Definition: TFunction.h:39
TString fSignature
Definition: TFunction.h:38
virtual void CreateSignature()
Using the CINT method arg information to create a complete signature string.
Definition: TFunction.cxx:107
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:184
MethodInfo_t * fInfo
Definition: TFunction.h:36
virtual bool Update(MethodInfo_t *info)
Update the TFunction to reflect the new info.
Definition: TFunction.cxx:279
TList * GetListOfMethodArgs()
Return list containing the TMethodArgs of a TFunction.
Definition: TFunction.cxx:127
TFunction & operator=(const TFunction &rhs)
Assignment operator.
Definition: TFunction.cxx:63
virtual const char * MethodInfo_Title(MethodInfo_t *) const
Definition: TInterpreter.h:510
A doubly linked list.
Definition: TList.h:38
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:659
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:36
Method or function calling interface.
Definition: TMethodCall.h:37
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
TMethodCall * fSetterMethod
Definition: TMethod.h:45
virtual const char * GetCommentString()
Returns a comment string from the class declaration.
Definition: TMethod.cxx:107
TString fGetter
Definition: TMethod.h:43
TMethod & operator=(const TMethod &rhs)
Assignment operator.
Definition: TMethod.cxx:68
virtual const char * Getter() const
Definition: TMethod.h:59
TClass * fClass
Definition: TMethod.h:41
virtual TDataMember * FindDataMember()
Tries to guess DataMember from comment string and Method's name <==(only if 1 Argument!...
Definition: TMethod.cxx:134
TClass * GetClass() const
Definition: TMethod.h:55
Bool_t Update(MethodInfo_t *info) override
Update the TMethod to reflect the new info.
Definition: TMethod.cxx:344
void SetMenuItem(const char *docstring)
Set the menu item as prescribed in the doctstring.
Definition: TMethod.cxx:319
virtual ~TMethod()
Cleanup.
Definition: TMethod.cxx:88
EMenuItemKind fMenuItem
Definition: TMethod.h:42
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
TMethodCall * fGetterMethod
Definition: TMethod.h:44
Bool_t IsValid() override
Return true if this function object is pointing to a currently loaded function.
Definition: TMethod.cxx:277
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition: TMethod.cxx:307
void CreateSignature() override
Using the CINT method arg information create a complete signature string.
Definition: TMethod.cxx:116
TMethod(MethodInfo_t *info=nullptr, TClass *cl=nullptr)
Default TMethod ctor.
Definition: TMethod.cxx:41
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
TObject * Clone(const char *newname="") const override
Clone method.
Definition: TMethod.cxx:97
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
TString fName
Definition: TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
Mother of all ROOT objects.
Definition: TObject.h:41
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:998
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1152
@ kBoth
Definition: TString.h:267
static constexpr double s
const char * cnt
Definition: TXMLSetup.cxx:75
TArc a
Definition: textangle.C:12
static byte * ptr1
Definition: gifdecode.c:16
static byte * ptr2
Definition: gifdecode.c:17