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
59
60////////////////////////////////////////////////////////////////////////////////
61/// Create an empty macro, use AddLine() or ReadFile() to fill this macro.
62
63TMacro::TMacro(): TNamed(), fLines(nullptr)
64{
65}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Create a macro with a name and a title.
69/// If name contains a '.' it is assumed to be the name of a file, and
70/// - the macro is automatically filled by reading all the lines in the file,
71/// - if the title is empty, it will be set to the name of the file,
72/// - the name will be set to the filename without path or extension.
73
74TMacro::TMacro(const char *name, const char *title): TNamed(name,title)
75{
76 fLines = new TList();
77 if (!name) return;
79 char *s = new char[nch+1];
80 strlcpy(s,name,nch+1);
81 char *slash = (char*)strrchr(s,'/');
82 if (!slash) slash = s;
83 else ++slash;
84 char *dot = (char*)strchr(slash,'.');
85 if (dot) {
86 *dot = 0;
87 fName = slash;
88 if (fTitle.Length() == 0) fTitle = name;
90 }
91 delete [] s;
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Copy constructor.
96
98{
99 fLines = new TList();
100 TIter next(macro.GetListOfLines());
101 while (auto obj = 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) {
123 if (fLines) fLines->Delete();
124 delete fLines;
125 fLines = new TList();
126 TIter next(macro.GetListOfLines());
127 while (auto obj = next())
128 fLines->Add(new TObjString(obj->GetName()));
129 fParams = macro.fParams;
130 }
131 return *this;
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// Add line with text in the list of lines of this macro.
136
138{
139 if (!fLines) fLines = new TList();
140 TObjString *obj = new TObjString(text);
141 fLines->Add(obj);
142 return obj;
143}
144
145////////////////////////////////////////////////////////////////////////////////
146/// When clicking in the browser, the following action is performed
147/// on this macro, depending the content of the variable TMacro.Browse.
148/// TMacro.Browse can be set in the system.rootrc or .rootrc file like:
149/// ~~~ {.cpp}
150/// TMacro.Browse : Action
151/// ~~~
152/// or set via gEnv->SetValue, eg
153/// ~~~ {.cpp}
154/// gEnv->SetValue("TMacro.Browse","Print");
155/// ~~~
156/// By default TMacro.Browse=""
157/// -if TMacro.Browse ="" the macro is executed
158/// -if TMacro.Browse ="Print" the macro is printed in stdout
159/// -if TMacro.Browse is of the form "mymacro.C"
160/// the macro void mymacro.C(TMacro *m) is called where m=this macro
161/// An example of macro.C saving the macro into a file and viewing it
162/// with emacs is shown below:
163/// ~~~ {.cpp}
164/// void mymacro(TMacro *m) {
165/// m->SaveSource("xx.log");
166/// gSystem->Exec("emacs xx.log&");
167/// }
168/// ~~~
169
171{
172 TString opt = gEnv->GetValue("TMacro.Browse","");
173 if (opt.IsNull()) {
174 Exec();
175 return;
176 }
177 if (opt == "Print") {
178 Print();
179 return;
180 }
181 if (opt.Contains(".C")) {
182 gROOT->ProcessLine(TString::Format(".x %s((TMacro*)0x%zx)", opt.Data(), (size_t)this).Data());
183 return;
184 }
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Returns checksum of the current content. The returned TMD5 object must
189/// be deleted by the user. Returns 0 in case of error.
190
192{
193 if (!fLines || fLines->GetSize() <= 0)
194 return (TMD5 *)nullptr;
195
196 TMD5 *md5 = new TMD5;
197
198 // Fill (same params as in TMD5::FileChecksum)
199 const Int_t bufSize = 8192;
200 UChar_t buf[bufSize];
201 Long64_t pos = 0;
202 Long64_t left = bufSize;
203
205 while (auto l = (TObjString *) nxl()) {
206 TString line = l->GetString();
207 line += '\n';
208 Int_t len = line.Length();
209 const char *p = line.Data();
210 if (left > len) {
211 strlcpy((char *)&buf[pos], p, len+1);
212 pos += len;
213 left -= len;
214 } else if (left == len) {
215 strlcpy((char *)&buf[pos], p, len+1);
216 md5->Update(buf, bufSize);
217 pos = 0;
218 left = bufSize;
219 } else {
220 strlcpy((char *)&buf[pos], p, left+1);
221 md5->Update(buf, bufSize);
222 len -= left;
223 p += left;
224 pos = 0;
225 left = bufSize;
226 strlcpy((char *)&buf[pos], p, len+1);
227 pos += len;
228 left -= len;
229 }
230 }
231 md5->Update(buf, pos);
232
233 // Finalize
234 md5->Final();
235
236 return md5;
237}
238
239////////////////////////////////////////////////////////////////////////////////
240/// Load the macro into the interpreter.
241/// Return true in case the loading was successful.
242
244{
245 std::stringstream ss;
246
247 TIter next(fLines);
248 while (auto obj = (TObjString*) next())
249 ss << obj->GetName() << std::endl;
250
251 return gInterpreter->LoadText(ss.str().c_str());
252}
253
254////////////////////////////////////////////////////////////////////////////////
255/// Execute this macro with params, if params is 0, default parameters
256/// (set via SetParams) are used.
257/// error is set to an TInterpreter::EErrorCode by TApplication::ProcessLine().
258/// Returns the result of the macro (return value or value of the last
259/// expression), cast to a Long_t.
260
261Longptr_t TMacro::Exec(const char *params, Int_t* error)
262{
263 if ( !gROOT->GetGlobalFunction(GetName(), nullptr, kTRUE) ) {
264 if (!Load()) {
265 if (error) *error = 1;
266 return 0;
267 }
268 }
269
270 // if macro has been executed, look for global function with name
271 // of macro and re-execute this global function, if not found then
272 // macro is unnamed macro, which we re-execute from file
273 if ( gROOT->GetGlobalFunction(GetName(), nullptr, kTRUE) ) {
274 gROOT->SetExecutingMacro(kTRUE);
275 TString exec = GetName();
276 TString p = params;
277 if (p == "") p = fParams;
278 if (p != "")
279 exec += "(" + p + ")";
280 else
281 exec += "()";
282 Longptr_t ret = gROOT->ProcessLine(exec, error);
283 //enable gROOT->Reset
284 gROOT->SetExecutingMacro(kFALSE);
285 return ret;
286 }
287
288 Error("Exec","Macro does not contains function named %s.",GetName());
289 if (error) *error = 1;
290 return 0;
291}
292
293////////////////////////////////////////////////////////////////////////////////
294/// Search the first line containing text.
295
297{
298 if (!fLines) return nullptr;
299 TIter next(fLines);
300 while (auto obj = (TObjString*) next()) {
301 if (strstr(obj->GetName(),text))
302 return obj;
303 }
304 return nullptr;
305}
306
307////////////////////////////////////////////////////////////////////////////////
308/// Execute this macro (called by TPad::Paint).
309
311{
312 Exec(option);
313}
314
315////////////////////////////////////////////////////////////////////////////////
316/// Print contents of this macro.
317
318void TMacro::Print(Option_t * /*option*/) const
319{
320 TIter next(fLines);
321 while (auto obj = next())
322 printf("%s\n", obj->GetName());
323}
324
325////////////////////////////////////////////////////////////////////////////////
326/// Read lines in filename in this macro.
327
329{
330 if (!fLines) fLines = new TList();
331 std::ifstream in;
332 in.open(filename);
333 if (!in.good()) {
334 Error("ReadFile","Cannot open file: %s",filename);
335 return 0;
336 }
337 char *line = new char[10000];
338 Int_t nlines = 0;
339 while (1) {
340 in.getline(line,10000);
341 if (!in.good()) break;
342 if (in.eof()) break;
343 fLines->Add(new TObjString(line));
344 nlines++;
345 }
346 delete [] line;
347 return nlines;
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Save macro source in filename.
352
354{
355 std::ofstream out;
356 out.open(filename, std::ios::out);
357 if (!out.good()) {
358 Error("SaveSource", "cannot open file: %s",filename);
359 return;
360 }
361 TIter next(fLines);
362 while (auto obj = next())
363 out << obj->GetName() << std::endl;
364 out.close();
365}
366
367////////////////////////////////////////////////////////////////////////////////
368/// Save macro source in file pointer fp.
369
371{
372 TIter next(fLines);
373 while (auto obj = next())
374 fprintf(fp, "%s\n", obj->GetName());
375 fclose(fp);
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Save macro source on stream out.
380
381void TMacro::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
382{
384 out, Class(), "macro",
385 TString::Format("\"%s\", \"%s\"", GetName(), TString(GetTitle()).ReplaceSpecialCppChars().Data()));
386
387 TIter next(fLines);
388 while (auto obj = next()) {
389 TString s = obj->GetName();
390 out << " macro->AddLine(\"" << s.ReplaceSpecialCppChars() << "\");\n";
391 }
392 out << " macro->Draw(\"" << TString(option).ReplaceSpecialCppChars() << "\");\n";
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Set default parameters to execute this macro.
397
398void TMacro::SetParams(const char *params)
399{
400 if (params) fParams = params;
401}
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:411
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:490
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:467
This code implements the MD5 message-digest algorithm.
Definition TMD5.h:44
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:191
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:318
virtual Bool_t Load() const
Load the macro into the interpreter.
Definition TMacro.cxx:243
virtual ~TMacro()
Delete this macro.
Definition TMacro.cxx:110
virtual void SetParams(const char *params=nullptr)
Set default parameters to execute this macro.
Definition TMacro.cxx:398
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save macro source on stream out.
Definition TMacro.cxx:381
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition TMacro.cxx:137
virtual Int_t ReadFile(const char *filename)
Read lines in filename in this macro.
Definition TMacro.cxx:328
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition TMacro.cxx:370
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:261
TMacro()
Create an empty macro, use AddLine() or ReadFile() to fill this macro.
Definition TMacro.cxx:63
static TClass * Class()
TMacro & operator=(const TMacro &)
Copy constructor.
Definition TMacro.cxx:119
void Paint(Option_t *option="") override
Execute this macro (called by TPad::Paint).
Definition TMacro.cxx:310
void Browse(TBrowser *b) override
When clicking in the browser, the following action is performed on this macro, depending the content ...
Definition TMacro.cxx:170
virtual TObjString * GetLineWith(const char *text) const
Search the first line containing text.
Definition TMacro.cxx:296
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:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:50
Collectable string class.
Definition TObjString.h:28
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:771
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
Bool_t IsNull() const
Definition TString.h:422
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:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
TLine * line
TCanvas * slash()
Definition slash.C:1
TLine l
Definition textangle.C:4