// @(#)root/base:$Name:  $:$Id: TMacro.cxx,v 1.3 2005/08/16 17:25:54 brun Exp $
// Author: Rene Brun   16/08/2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMacro                                                               //
//                                                                      //
// class supporting a collection of lines with C++ code.                //
// A TMacro can be executed, saved to a ROOT file, edited, etc          //
//                                                                      //
// A macro can be built line by line by calling the AddLine function.   //
// or it can be created directly from a file via the special constructor//
// when the first argument is a file name.                              //
//                                                                      //
// A macro can be executed via the Exec function.                       //
// Arguments can be specified when calling Exec.                        //
//                                                                      //
// A macro can be drawn in a pad. When the pad is updated, the macro is //
// automatically executed.                                              //
//                                                                      //
// The code in the macro can be saved via the SaveSource function.      //
// If the macro is in the list of primitives of a pad/canvas, the macro //
// will be saved in the script generated by TCanvas::SaveSource.        //
//                                                                      //
// A macro can be written to a ROOT file via TObject::Write.            //
//                                                                      //
// Examples:                                                            //
//   TMacro m("Peaks.C");  //macro m with name "Peaks" is created       //
//                         //from file  Peaks.C                         //
//   m.Exec();             //macro executed with default arguments      //
//   m.Exec("4");          //macro executed with argument               //
//   m.SaveSource("newPeaks.C");                                        //
//   TFile f("mymacros.root","recreate");                               //
//   m.Write();   //macro saved to file with name "Peaks"               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TMacro.h"

ClassImp(TMacro)

//______________________________________________________________________________
 TMacro::TMacro(): TNamed()
{
   // create an empty macro
   // use AddLine or ReadFile to fill this macro.
   fLines  = 0;
   fParams = "";
}


//______________________________________________________________________________
 TMacro::TMacro(const char *name, const char *title)
       :TNamed(name,title)
{
   // create a macro with a name and a title.
   // if name is the name of a file, the macro is automatically filled
   // by reading all the lines in the file. In this case, if the title
   // is empty, it will be the name of the file.
   
   fLines  = new TList();
   fParams = "";
   if (!name) return;
   Int_t nch = strlen(name);
   char *s = new char[nch+1];
   strcpy(s,name);
   char *dot   = (char*)strchr(s,'.');
   char *slash = (char*)strrchr(s,'/');
   if (dot) {
      *dot = 0;
      if (slash) fName = slash+1;
      else       fName = s;
      if (fTitle.Length() == 0) fTitle = name;
      ReadFile(name);
   }
   delete [] s;
}

//______________________________________________________________________________
 TMacro::TMacro(const TMacro &macro): TNamed(macro)
{
  // copy constructor

  fLines = new TList();
  TIter next(macro.GetListOfLines());
  TObjString *obj;
  while ((obj = (TObjString*) next())) {
     fLines->Add(new TObjString(obj->GetName()));
  }   
}



//______________________________________________________________________________
 TMacro::~TMacro()
{
   // delete this macro
   
   if (fLines) fLines->Delete();
   delete fLines;
}

//______________________________________________________________________________
 TObjString *TMacro::AddLine(const char *text)
{
   //add line with text in the list of lines of this macro
   
   if (!fLines) fLines = new TList();
   TObjString *obj = new TObjString(text);
   fLines->Add(obj);
   return obj;
}

//______________________________________________________________________________
 void TMacro::Browse(TBrowser * /*b*/)
{
    // when clicking in the browser, the macro will be executed.
   
   Exec();
}

//______________________________________________________________________________
 void TMacro::Exec(const char *params)
{
   // execute this macro with params
   // if params is null, default parameters (set via SetParams)  are used
   
   //the current implementation uses a file in the current directory.
   //should be replaced by a direct execution from memory by CINT
   char fname[1000];
   sprintf(fname,"%s.Cexec",GetName());
   SaveSource(fname);
   //disable a possible call to gROOT->Reset from the executed script
   gROOT->SetExecutingMacro(kTRUE);
   //execute script in /tmp
   if (!params) params = fParams.Data();
   if (strlen(params) > 0) gROOT->ProcessLine(Form(".x %s(%s)",fname,params));
   else                    gROOT->ProcessLine(Form(".x %s",fname));
   //enable gROOT->Reset
   gROOT->SetExecutingMacro(kFALSE);
   //delete the temporary file
   gSystem->Unlink(fname);
}

//______________________________________________________________________________
 TObjString *TMacro::GetLineWith(const char *text) const 
{
   //search the first line containing text
   
   if (!fLines) return 0;
   TIter next(fLines);
   TObjString *obj;
   while ((obj = (TObjString*) next())) {
      if (strstr(obj->GetName(),text)) return obj;
   }
   return 0;
}

//______________________________________________________________________________
 void TMacro::Paint(Option_t *option)
{
   // execute this macro (called by TPad::Paint)

   Exec(option);
}   

//______________________________________________________________________________
 void TMacro::Print(Option_t * /*option*/) const
{
   // print contents of this macro

   if (!fLines) return;
   TIter next(fLines);
   TObjString *obj;
   while ((obj = (TObjString*) next())) {
      printf("%s\n",obj->GetName());
   }
}   

//______________________________________________________________________________
 Int_t TMacro::ReadFile(const char *filename)
{
   //read lines in filename in this macro
   
   if (!fLines) fLines = new TList();
   ifstream in;
   in.open(filename);
   if (!in.good()) {
      Error("ReadFile","Cannot open file: %s",filename);
      return 0;
   }
   char *line = new char[10000];
   Int_t nlines = 0;
   while (1) {
      in.getline(line,10000);
      if (in.eof()) break;
      fLines->Add(new TObjString(line));
      nlines++;
   }
   delete [] line;
   return nlines;
}
     

//______________________________________________________________________________
 void TMacro::SaveSource(const char *filename)
{
   //save macro source in filename
     
   ofstream out;
   out.open(filename, ios::out
   if (!out.good ()) {
      Printf("SaveSource cannot open file: %s",filename);
      return;
   }
   if (!fLines) {out.close(); return;}
   TIter next(fLines);
   TObjString *obj;
   while ((obj = (TObjString*) next())) {
      out<<obj->GetName()<<endl;
   }
   out.close();
}

//______________________________________________________________________________
 void TMacro::SavePrimitive(ofstream &out, Option_t *option)
{
   //save macro source on stream out
   char quote = '"';
   out<<"   "<<endl;
   if (gROOT->ClassSaved(TMacro::Class())) {
       out<<"   ";
   } else {
       out<<"   "<<ClassName()<<" *";
   }
   out<<"macro = new "<<ClassName()<<"("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<");"<<endl;
   if (!fLines) return;
   TIter next(fLines);
   TObjString *obj;
   while ((obj = (TObjString*) next())) {
      TString s = obj->GetName();
      s.ReplaceAll("\"","\\\"");
      out<<"   macro->AddLine("<<quote<<s.Data()<<quote<<");"<<endl;
   }
   out<<"   macro->Draw("<<quote<<option<<quote<<");"<<endl;
}
     

//______________________________________________________________________________
 void TMacro::SetParams(const char *params)
{
  //set default parameters to execute this macro
   
   if (params) fParams = params;
}


ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.