Logo ROOT  
Reference Guide
TMacro.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Rene Brun 16/08/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, 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 TMacro
13\ingroup Base
14
15Class supporting a collection of lines with C++ code.
16A TMacro can be executed, saved to a ROOT file, edited, etc.
17
18A macro can be built line by line by calling the AddLine function.
19or it can be created directly from a file via the special constructor
20when the first argument is a file name.
21
22A macro can be executed via the Exec function.
23Arguments can be specified when calling Exec.
24
25A macro can be drawn in a pad. When the pad is updated, the macro is
26automatically executed.
27
28The code in the macro can be saved via the SaveSource function.
29If the macro is in the list of primitives of a pad/canvas, the macro
30will be saved in the script generated by TCanvas::SaveSource.
31
32A macro can be written to a ROOT file via TObject::Write.
33
34Examples:
35~~~ {.cpp}
36 TMacro m("Peaks.C"); //macro m with name "Peaks" is created
37 //from file Peaks.C
38 m.Exec(); //macro executed with default arguments
39 m.Exec("4"); //macro executed with argument
40 m.SaveSource("newPeaks.C");
41 TFile f("mymacros.root","recreate");
42 m.Write(); //macro saved to file with name "Peaks"
43~~~
44*/
45
46#include "Riostream.h"
47#include "TEnv.h"
48#include "TInterpreter.h"
49#include "TList.h"
50#include "TMacro.h"
51#include "TMD5.h"
52#include "TObjString.h"
53#include "TROOT.h"
54#include "TSystem.h"
55#include <sstream>
56
58
59////////////////////////////////////////////////////////////////////////////////
60/// Create an empty macro, use AddLine() or ReadFile() to fill this macro.
61
62TMacro::TMacro(): TNamed(), fLines(0)
63{
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Create a macro with a name and a title.
68/// If name contains a '.' it is assumed to be the name of a file, and
69/// - the macro is automatically filled by reading all the lines in the file,
70/// - if the title is empty, it will be set to the name of the file,
71/// - the name will be set to the filename without path or extension.
72
73TMacro::TMacro(const char *name, const char *title): TNamed(name,title)
74{
75 fLines = new TList();
76 if (!name) return;
77 Int_t nch = strlen(name);
78 char *s = new char[nch+1];
79 strlcpy(s,name,nch+1);
80 char *slash = (char*)strrchr(s,'/');
81 if (!slash) slash = s;
82 else ++slash;
83 char *dot = (char*)strchr(slash,'.');
84 if (dot) {
85 *dot = 0;
86 fName = slash;
87 if (fTitle.Length() == 0) fTitle = name;
89 }
90 delete [] s;
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Copy constructor.
95
96TMacro::TMacro(const TMacro &macro): TNamed(macro)
97{
98 fLines = new TList();
99 TIter next(macro.GetListOfLines());
100 TObjString *obj;
101 while ((obj = (TObjString*) next())) {
102 fLines->Add(new TObjString(obj->GetName()));
103 }
104 fParams = macro.fParams;
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Delete this macro.
109
111{
112 if (fLines) fLines->Delete();
113 delete fLines;
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Copy constructor.
118
120{
121 if(this!=&macro) {
122 TNamed::operator=(macro);
123 if (fLines) fLines->Delete();
124 delete fLines;
125 fLines = new TList();
126 TIter next(macro.GetListOfLines());
127 TObjString *obj;
128 while ((obj = (TObjString*) next())) {
129 fLines->Add(new TObjString(obj->GetName()));
130 }
131 fParams = macro.fParams;
132 }
133 return *this;
134}
135
136////////////////////////////////////////////////////////////////////////////////
137/// Add line with text in the list of lines of this macro.
138
140{
141 if (!fLines) fLines = new TList();
142 TObjString *obj = new TObjString(text);
143 fLines->Add(obj);
144 return obj;
145}
146
147////////////////////////////////////////////////////////////////////////////////
148/// When clicking in the browser, the following action is performed
149/// on this macro, depending the content of the variable TMacro.Browse.
150/// TMacro.Browse can be set in the system.rootrc or .rootrc file like:
151/// ~~~ {.cpp}
152/// TMacro.Browse : Action
153/// ~~~
154/// or set via gEnv->SetValue, eg
155/// ~~~ {.cpp}
156/// gEnv->SetValue("TMacro.Browse","Print");
157/// ~~~
158/// By default TMacro.Browse=""
159/// -if TMacro.Browse ="" the macro is executed
160/// -if TMacro.Browse ="Print" the macro is printed in stdout
161/// -if TMacro.Browse is of the form "mymacro.C"
162/// the macro void mymacro.C(TMacro *m) is called where m=this macro
163/// An example of macro.C saving the macro into a file and viewing it
164/// with emacs is shown below:
165/// ~~~ {.cpp}
166/// void mymacro(TMacro *m) {
167/// m->SaveSource("xx.log");
168/// gSystem->Exec("emacs xx.log&");
169/// }
170/// ~~~
171
173{
174 TString opt = gEnv->GetValue("TMacro.Browse","");
175 if (opt.IsNull()) {
176 Exec();
177 return;
178 }
179 if (opt == "Print") {
180 Print();
181 return;
182 }
183 if (opt.Contains(".C")) {
184 const char *cmd = Form(".x %s((TMacro*)0x%lx)",opt.Data(),(ULong_t)this);
185 gROOT->ProcessLine(cmd);
186 return;
187 }
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Returns checksum of the current content. The returned TMD5 object must
192/// be deleted by the user. Returns 0 in case of error.
193
195{
196 if (!fLines || fLines->GetSize() <= 0)
197 return (TMD5 *)0;
198
199 TMD5 *md5 = new TMD5;
200
201 // Fill (same params as in TMD5::FileChecksum)
202 const Int_t bufSize = 8192;
203 UChar_t buf[bufSize];
204 Long64_t pos = 0;
205 Long64_t left = bufSize;
206
207 TIter nxl(fLines);
208 TObjString *l;
209 while ((l = (TObjString *) nxl())) {
210 TString line = l->GetString();
211 line += '\n';
212 Int_t len = line.Length();
213 char *p = (char *) line.Data();
214 if (left > len) {
215 strlcpy((char *)&buf[pos], p, len+1);
216 pos += len;
217 left -= len;
218 } else if (left == len) {
219 strlcpy((char *)&buf[pos], p, len+1);
220 md5->Update(buf, bufSize);
221 pos = 0;
222 left = bufSize;
223 } else {
224 strlcpy((char *)&buf[pos], p, left+1);
225 md5->Update(buf, bufSize);
226 len -= left;
227 p += left;
228 pos = 0;
229 left = bufSize;
230 strlcpy((char *)&buf[pos], p, len+1);
231 pos += len;
232 left -= len;
233 }
234 }
235 md5->Update(buf, pos);
236
237 // Finalize
238 md5->Final();
239
240 return md5;
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// Load the macro into the interpreter.
245/// Return true in case the loading was successful.
246
248{
249 std::stringstream ss;
250
251 TIter next(fLines);
252 TObjString *obj;
253 while ((obj = (TObjString*) next())) {
254 ss << obj->GetName() << std::endl;
255 }
256 return gInterpreter->LoadText(ss.str().c_str());
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// Execute this macro with params, if params is 0, default parameters
261/// (set via SetParams) are used.
262/// error is set to an TInterpreter::EErrorCode by TApplication::ProcessLine().
263/// Returns the result of the macro (return value or value of the last
264/// expression), cast to a Long_t.
265
266Long_t TMacro::Exec(const char *params, Int_t* error)
267{
268 if ( !gROOT->GetGlobalFunction(GetName(), 0, kTRUE) ) {
269 if (!Load()) {
270 if (error) *error = 1;
271 return 0;
272 }
273 }
274
275 // if macro has been executed, look for global function with name
276 // of macro and re-execute this global function, if not found then
277 // macro is unnamed macro, which we re-execute from file
278 if ( gROOT->GetGlobalFunction(GetName(), 0, kTRUE) ) {
279 gROOT->SetExecutingMacro(kTRUE);
280 TString exec = GetName();
281 TString p = params;
282 if (p == "") p = fParams;
283 if (p != "")
284 exec += "(" + p + ")";
285 else
286 exec += "()";
287 Long_t ret = gROOT->ProcessLine(exec, error);
288 //enable gROOT->Reset
289 gROOT->SetExecutingMacro(kFALSE);
290 return ret;
291 }
292
293 Error("Exec","Macro does not contains function named %s.",GetName());
294 if (error) *error = 1;
295 return 0;
296}
297
298////////////////////////////////////////////////////////////////////////////////
299/// Search the first line containing text.
300
302{
303 if (!fLines) return 0;
304 TIter next(fLines);
305 TObjString *obj;
306 while ((obj = (TObjString*) next())) {
307 if (strstr(obj->GetName(),text)) return obj;
308 }
309 return 0;
310}
311
312////////////////////////////////////////////////////////////////////////////////
313/// Execute this macro (called by TPad::Paint).
314
316{
317 Exec(option);
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// Print contents of this macro.
322
323void TMacro::Print(Option_t * /*option*/) const
324{
325 if (!fLines) return;
326 TIter next(fLines);
327 TObjString *obj;
328 while ((obj = (TObjString*) next())) {
329 printf("%s\n",obj->GetName());
330 }
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// Read lines in filename in this macro.
335
336Int_t TMacro::ReadFile(const char *filename)
337{
338 if (!fLines) fLines = new TList();
339 std::ifstream in;
340 in.open(filename);
341 if (!in.good()) {
342 Error("ReadFile","Cannot open file: %s",filename);
343 return 0;
344 }
345 char *line = new char[10000];
346 Int_t nlines = 0;
347 while (1) {
348 in.getline(line,10000);
349 if (!in.good()) break;
350 if (in.eof()) break;
351 fLines->Add(new TObjString(line));
352 nlines++;
353 }
354 delete [] line;
355 return nlines;
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Save macro source in filename.
360
361void TMacro::SaveSource(const char *filename)
362{
363 std::ofstream out;
364 out.open(filename, std::ios::out);
365 if (!out.good ()) {
366 Printf("SaveSource cannot open file: %s",filename);
367 return;
368 }
369 if (!fLines) {out.close(); return;}
370 TIter next(fLines);
371 TObjString *obj;
372 while ((obj = (TObjString*) next())) {
373 out<<obj->GetName()<<std::endl;
374 }
375 out.close();
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Save macro source in file pointer fp.
380
381void TMacro::SaveSource(FILE *fp)
382{
383 if (!fLines) {fclose(fp); return;}
384 TIter next(fLines);
385 TObjString *obj;
386 while ((obj = (TObjString*) next())) {
387 fprintf(fp, "%s\n", obj->GetName());
388 }
389 fclose(fp);
390}
391
392////////////////////////////////////////////////////////////////////////////////
393/// Save macro source on stream out.
394
395void TMacro::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
396{
397 char quote = '"';
398 out<<" "<<std::endl;
399 if (gROOT->ClassSaved(TMacro::Class())) {
400 out<<" ";
401 } else {
402 out<<" "<<ClassName()<<" *";
403 }
404 out<<"macro = new "<<ClassName()<<"("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<");"<<std::endl;
405 if (!fLines) return;
406 TIter next(fLines);
407 TObjString *obj;
408 while ((obj = (TObjString*) next())) {
409 TString s = obj->GetName();
410 s.ReplaceAll("\"","\\\"");
411 out<<" macro->AddLine("<<quote<<s.Data()<<quote<<");"<<std::endl;
412 }
413 out<<" macro->Draw("<<quote<<option<<quote<<");"<<std::endl;
414}
415
416////////////////////////////////////////////////////////////////////////////////
417/// Set default parameters to execute this macro.
418
419void TMacro::SetParams(const char *params)
420{
421 if (params) fParams = params;
422}
void Class()
Definition: Class.C:29
unsigned char UChar_t
Definition: RtypesCore.h:36
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
long Long_t
Definition: RtypesCore.h:52
long long Long64_t
Definition: RtypesCore.h:71
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
char name[80]
Definition: TGX11.cxx:109
#define gInterpreter
Definition: TInterpreter.h:556
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
void Update(const UChar_t *buf, UInt_t len)
Update TMD5 object to reflect the concatenation of another buffer full of bytes.
Definition: TMD5.cxx:108
void Final()
MD5 finalization, ends an MD5 message-digest operation, writing the the message digest and zeroizing ...
Definition: TMD5.cxx:167
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
virtual Long_t Exec(const char *params=0, Int_t *error=0)
Execute this macro with params, if params is 0, default parameters (set via SetParams) are used.
Definition: TMacro.cxx:266
virtual TMD5 * Checksum()
Returns checksum of the current content.
Definition: TMacro.cxx:194
TString fParams
Definition: TMacro.h:35
TList * fLines
Definition: TMacro.h:34
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition: TMacro.cxx:247
virtual ~TMacro()
Delete this macro.
Definition: TMacro.cxx:110
virtual void Paint(Option_t *option="")
Execute this macro (called by TPad::Paint).
Definition: TMacro.cxx:315
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition: TMacro.cxx:139
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition: TMacro.cxx:336
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition: TMacro.cxx:381
TMacro()
Create an empty macro, use AddLine() or ReadFile() to fill this macro.
Definition: TMacro.cxx:62
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save macro source on stream out.
Definition: TMacro.cxx:395
virtual void Browse(TBrowser *b)
When clicking in the browser, the following action is performed on this macro, depending the content ...
Definition: TMacro.cxx:172
TMacro & operator=(const TMacro &)
Copy constructor.
Definition: TMacro.cxx:119
virtual void SetParams(const char *params=0)
Set default parameters to execute this macro.
Definition: TMacro.cxx:419
TList * GetListOfLines() const
Definition: TMacro.h:51
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition: TMacro.cxx:301
virtual void Print(Option_t *option="") const
Print contents of this macro.
Definition: TMacro.cxx:323
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TString fTitle
Definition: TNamed.h:33
TString fName
Definition: TNamed.h:32
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Collectable string class.
Definition: TObjString.h:28
const char * GetName() const
Returns name of object.
Definition: TObjString.h:38
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
const char * Data() const
Definition: TString.h:364
Bool_t IsNull() const
Definition: TString.h:402
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
TText * text
TLine * line
static constexpr double s
TCanvas * slash()
Definition: slash.C:1
auto * l
Definition: textangle.C:4