Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 "TEnv.h"
47#include "TInterpreter.h"
48#include "TList.h"
49#include "TMacro.h"
50#include "TMD5.h"
51#include "TObjString.h"
52#include "TROOT.h"
53#include "TSystem.h"
54#include "strlcpy.h"
55#include <iostream>
56#include <fstream>
57#include <sstream>
58
60
61////////////////////////////////////////////////////////////////////////////////
62/// Create an empty macro, use AddLine() or ReadFile() to fill this macro.
63
64TMacro::TMacro(): TNamed(), fLines(nullptr)
65{
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Create a macro with a name and a title.
70/// If name contains a '.' it is assumed to be the name of a file, and
71/// - the macro is automatically filled by reading all the lines in the file,
72/// - if the title is empty, it will be set to the name of the file,
73/// - the name will be set to the filename without path or extension.
74
75TMacro::TMacro(const char *name, const char *title): TNamed(name,title)
76{
77 fLines = new TList();
78 if (!name) return;
79 Int_t nch = strlen(name);
80 char *s = new char[nch+1];
81 strlcpy(s,name,nch+1);
82 char *slash = (char*)strrchr(s,'/');
83 if (!slash) slash = s;
84 else ++slash;
85 char *dot = (char*)strchr(slash,'.');
86 if (dot) {
87 *dot = 0;
88 fName = slash;
89 if (fTitle.Length() == 0) fTitle = name;
91 }
92 delete [] s;
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Copy constructor.
97
98TMacro::TMacro(const TMacro &macro): TNamed(macro)
99{
100 fLines = new TList();
101 TIter next(macro.GetListOfLines());
102 while (auto obj = next())
103 fLines->Add(new TObjString(obj->GetName()));
104
105 fParams = macro.fParams;
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// Delete this macro.
110
112{
113 if (fLines) fLines->Delete();
114 delete fLines;
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Copy constructor.
119
121{
122 if(this!=&macro) {
123 TNamed::operator=(macro);
124 if (fLines) fLines->Delete();
125 delete fLines;
126 fLines = new TList();
127 TIter next(macro.GetListOfLines());
128 while (auto obj = next())
129 fLines->Add(new TObjString(obj->GetName()));
130 fParams = macro.fParams;
131 }
132 return *this;
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Add line with text in the list of lines of this macro.
137
139{
140 if (!fLines) fLines = new TList();
141 TObjString *obj = new TObjString(text);
142 fLines->Add(obj);
143 return obj;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// When clicking in the browser, the following action is performed
148/// on this macro, depending the content of the variable TMacro.Browse.
149/// TMacro.Browse can be set in the system.rootrc or .rootrc file like:
150/// ~~~ {.cpp}
151/// TMacro.Browse : Action
152/// ~~~
153/// or set via gEnv->SetValue, eg
154/// ~~~ {.cpp}
155/// gEnv->SetValue("TMacro.Browse","Print");
156/// ~~~
157/// By default TMacro.Browse=""
158/// -if TMacro.Browse ="" the macro is executed
159/// -if TMacro.Browse ="Print" the macro is printed in stdout
160/// -if TMacro.Browse is of the form "mymacro.C"
161/// the macro void mymacro.C(TMacro *m) is called where m=this macro
162/// An example of macro.C saving the macro into a file and viewing it
163/// with emacs is shown below:
164/// ~~~ {.cpp}
165/// void mymacro(TMacro *m) {
166/// m->SaveSource("xx.log");
167/// gSystem->Exec("emacs xx.log&");
168/// }
169/// ~~~
170
172{
173 TString opt = gEnv->GetValue("TMacro.Browse","");
174 if (opt.IsNull()) {
175 Exec();
176 return;
177 }
178 if (opt == "Print") {
179 Print();
180 return;
181 }
182 if (opt.Contains(".C")) {
183 gROOT->ProcessLine(TString::Format(".x %s((TMacro*)0x%zx)", opt.Data(), (size_t)this).Data());
184 return;
185 }
186}
187
188////////////////////////////////////////////////////////////////////////////////
189/// Returns checksum of the current content. The returned TMD5 object must
190/// be deleted by the user. Returns 0 in case of error.
191
193{
194 if (!fLines || fLines->GetSize() <= 0)
195 return (TMD5 *)nullptr;
196
197 TMD5 *md5 = new TMD5;
198
199 // Fill (same params as in TMD5::FileChecksum)
200 const Int_t bufSize = 8192;
201 UChar_t buf[bufSize];
202 Long64_t pos = 0;
203 Long64_t left = bufSize;
204
205 TIter nxl(fLines);
206 while (auto l = (TObjString *) nxl()) {
207 TString line = l->GetString();
208 line += '\n';
209 Int_t len = line.Length();
210 const char *p = line.Data();
211 if (left > len) {
212 strlcpy((char *)&buf[pos], p, len+1);
213 pos += len;
214 left -= len;
215 } else if (left == len) {
216 strlcpy((char *)&buf[pos], p, len+1);
217 md5->Update(buf, bufSize);
218 pos = 0;
219 left = bufSize;
220 } else {
221 strlcpy((char *)&buf[pos], p, left+1);
222 md5->Update(buf, bufSize);
223 len -= left;
224 p += left;
225 pos = 0;
226 left = bufSize;
227 strlcpy((char *)&buf[pos], p, len+1);
228 pos += len;
229 left -= len;
230 }
231 }
232 md5->Update(buf, pos);
233
234 // Finalize
235 md5->Final();
236
237 return md5;
238}
239
240////////////////////////////////////////////////////////////////////////////////
241/// Load the macro into the interpreter.
242/// Return true in case the loading was successful.
243
245{
246 std::stringstream ss;
247
248 TIter next(fLines);
249 while (auto obj = (TObjString*) next())
250 ss << obj->GetName() << std::endl;
251
252 return gInterpreter->LoadText(ss.str().c_str());
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// Execute this macro with params, if params is 0, default parameters
257/// (set via SetParams) are used.
258/// error is set to an TInterpreter::EErrorCode by TApplication::ProcessLine().
259/// Returns the result of the macro (return value or value of the last
260/// expression), cast to a Long_t.
261
262Longptr_t TMacro::Exec(const char *params, Int_t* error)
263{
264 if ( !gROOT->GetGlobalFunction(GetName(), nullptr, kTRUE) ) {
265 if (!Load()) {
266 if (error) *error = 1;
267 return 0;
268 }
269 }
270
271 // if macro has been executed, look for global function with name
272 // of macro and re-execute this global function, if not found then
273 // macro is unnamed macro, which we re-execute from file
274 if ( gROOT->GetGlobalFunction(GetName(), nullptr, kTRUE) ) {
275 gROOT->SetExecutingMacro(kTRUE);
276 TString exec = GetName();
277 TString p = params;
278 if (p == "") p = fParams;
279 if (p != "")
280 exec += "(" + p + ")";
281 else
282 exec += "()";
283 Longptr_t ret = gROOT->ProcessLine(exec, error);
284 //enable gROOT->Reset
285 gROOT->SetExecutingMacro(kFALSE);
286 return ret;
287 }
288
289 Error("Exec","Macro does not contains function named %s.",GetName());
290 if (error) *error = 1;
291 return 0;
292}
293
294////////////////////////////////////////////////////////////////////////////////
295/// Search the first line containing text.
296
298{
299 if (!fLines) return nullptr;
300 TIter next(fLines);
301 while (auto obj = (TObjString*) next()) {
302 if (strstr(obj->GetName(),text))
303 return obj;
304 }
305 return nullptr;
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Execute this macro (called by TPad::Paint).
310
312{
313 Exec(option);
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Print contents of this macro.
318
319void TMacro::Print(Option_t * /*option*/) const
320{
321 TIter next(fLines);
322 while (auto obj = next())
323 printf("%s\n", obj->GetName());
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Read lines in filename in this macro.
328
330{
331 if (!fLines) fLines = new TList();
332 std::ifstream in;
333 in.open(filename);
334 if (!in.good()) {
335 Error("ReadFile","Cannot open file: %s",filename);
336 return 0;
337 }
338 char *line = new char[10000];
339 Int_t nlines = 0;
340 while (1) {
341 in.getline(line,10000);
342 if (!in.good()) break;
343 if (in.eof()) break;
344 fLines->Add(new TObjString(line));
345 nlines++;
346 }
347 delete [] line;
348 return nlines;
349}
350
351////////////////////////////////////////////////////////////////////////////////
352/// Save macro source in filename.
353
355{
356 std::ofstream out;
357 out.open(filename, std::ios::out);
358 if (!out.good()) {
359 Error("SaveSource", "cannot open file: %s",filename);
360 return;
361 }
362 TIter next(fLines);
363 while (auto obj = next())
364 out << obj->GetName() << std::endl;
365 out.close();
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Save macro source in file pointer fp.
370
371void TMacro::SaveSource(FILE *fp)
372{
373 TIter next(fLines);
374 while (auto obj = next())
375 fprintf(fp, "%s\n", obj->GetName());
376 fclose(fp);
377}
378
379////////////////////////////////////////////////////////////////////////////////
380/// Save macro source on stream out.
381
382void TMacro::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
383{
384 char quote = '"';
385 out<<" "<<std::endl;
386 if (gROOT->ClassSaved(TMacro::Class()))
387 out<<" ";
388 else
389 out<<" "<<ClassName()<<" *";
390
391 out<<"macro = new "<<ClassName()<<"("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<");"<<std::endl;
392
393 TIter next(fLines);
394 while (auto obj = next()) {
395 TString s = obj->GetName();
396 out<<" macro->AddLine("<<quote<<s.ReplaceSpecialCppChars()<<quote<<");"<<std::endl;
397 }
398 out<<" macro->Draw("<<quote<<option<<quote<<");"<<std::endl;
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// Set default parameters to execute this macro.
403
404void TMacro::SetParams(const char *params)
405{
406 if (params) fParams = params;
407}
long Longptr_t
Definition RtypesCore.h:75
unsigned char UChar_t
Definition RtypesCore.h:38
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
long long Long64_t
Definition RtypesCore.h:69
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
#define gROOT
Definition TROOT.h:406
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.
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:38
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
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 TMD5 * Checksum()
Returns checksum of the current content.
Definition TMacro.cxx:192
TString fParams
Definition TMacro.h:35
TList * fLines
Definition TMacro.h:34
void Print(Option_t *option="") const override
Print contents of this macro.
Definition TMacro.cxx:319
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition TMacro.cxx:244
virtual ~TMacro()
Delete this macro.
Definition TMacro.cxx:111
virtual void SetParams(const char *params=nullptr)
Set default parameters to execute this macro.
Definition TMacro.cxx:404
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save macro source on stream out.
Definition TMacro.cxx:382
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition TMacro.cxx:138
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition TMacro.cxx:329
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition TMacro.cxx:371
virtual Longptr_t Exec(const char *params=nullptr, Int_t *error=nullptr)
Execute this macro with params, if params is 0, default parameters (set via SetParams) are used.
Definition TMacro.cxx:262
TMacro()
Create an empty macro, use AddLine() or ReadFile() to fill this macro.
Definition TMacro.cxx:64
static TClass * Class()
TMacro & operator=(const TMacro &)
Copy constructor.
Definition TMacro.cxx:120
TList * GetListOfLines() const
Definition TMacro.h:51
void Paint(Option_t *option="") override
Execute this macro (called by TPad::Paint).
Definition TMacro.cxx:311
void Browse(TBrowser *b) override
When clicking in the browser, the following action is performed on this macro, depending the content ...
Definition TMacro.cxx:171
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition TMacro.cxx:297
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
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:51
Collectable string class.
Definition TObjString.h:28
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:213
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:993
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1114
const char * Data() const
Definition TString.h:376
Bool_t IsNull() const
Definition TString.h:414
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
TLine * line
TCanvas * slash()
Definition slash.C:1
TLine l
Definition textangle.C:4