//*CMZ : 2.23/07 25/10/99 19.00.09 by Fons Rademakers
//*CMZ : 2.23/04 13/10/99 17.06.39 by Fons Rademakers
//*CMZ : 2.23/03 17/09/99 15.41.13 by Rene Brun
//*CMZ : 2.23/01 26/08/99 12.20.27 by Rene Brun
//*CMZ : 2.22/07 02/07/99 08.34.09 by Rene Brun
//*CMZ : 2.22/06 22/06/99 19.15.13 by Fons Rademakers
//*-- Author : Fons Rademakers 01/03/96
//*KEEP,CopyRight,T=C.
/*************************************************************************
* Copyright(c) 1995-1999, The ROOT System, All rights reserved. *
* Authors: Rene Brun and Fons Rademakers. *
* *
* For the licensing terms see $ROOTSYS/AA_LICENSE. *
* For the list of contributors see $ROOTSYS/AA_CREDITS. *
*************************************************************************/
//*KEND.
//////////////////////////////////////////////////////////////////////////
// //
// This class defines an interface to the CINT C/C++ interpreter made //
// by Masaharu Goto from HP Japan. //
// //
// CINT is an almost full ANSI compliant C/C++ interpreter. //
// //
//////////////////////////////////////////////////////////////////////////
//*KEEP,TCint,T=C++.
#include "TCint.h"
//*KEEP,TROOT.
#include "TROOT.h"
//*KEEP,TApplication.
#include "TApplication.h"
//*KEEP,TGlobal.
#include "TGlobal.h"
//*KEEP,TDataType.
#include "TDataType.h"
//*KEEP,TClass.
#include "TClass.h"
//*KEEP,TBaseClass.
#include "TBaseClass.h"
//*KEEP,TDataMember.
#include "TDataMember.h"
//*KEEP,TMethod.
#include "TMethod.h"
//*KEEP,TMethodArg.
#include "TMethodArg.h"
//*KEEP,TObjArray.
#include "TObjArray.h"
//*KEEP,TObjString.
#include "TObjString.h"
//*KEEP,TString.
#include "TString.h"
//*KEEP,TList.
#include "TList.h"
//*KEEP,TVirtualPad.
#include "TVirtualPad.h"
//*KEEP,TSystem.
#include "TSystem.h"
//*KEEP,G__ci.
#include "G__ci.h"
//*KEND.
#ifdef WIN32
# ifndef ROOT_TGWin32Command
# include "TGWin32Command.h"
# undef GetClassInfo
# endif
#endif
R__EXTERN int optind;
// reference cint includes
// make sure fproto.h is loaded (it was excluded in TCint.h)
#undef G__FPROTO_H
//*KEEP,fproto.
#include "fproto.h"
//*KEEP,Api.
#include "Api.h"
//*KEND.
extern "C" void G__clearfilebusy(int);
extern "C" int ScriptCompiler(const char* filename) {
return gSystem->CompileMacro(filename);
}
// It is a "fantom" method to synchronize user keyboard input
// and ROOT prompt line (for WIN32)
const char *fantomline = "TRint::EndOfLineAction();";
ClassImp(TCint)
//______________________________________________________________________________
TCint::TCint(const char *name, const char *title) : TInterpreter(name, title)
{
// Initialize the CINT interpreter interface.
fMore = 0;
fPrompt[0] = 0;
G__RegisterScriptCompiler(&ScriptCompiler);
G__InitUpdateClassInfo(&TCint::UpdateClassInfo);
G__InitGetSpecialObject(&TCint::FindObject);
ResetAll();
#ifndef WIN32
optind = 1; // make sure getopt() works in the main program
#endif
}
//______________________________________________________________________________
TCint::~TCint()
{
// Destroy the CINT interpreter interface.
if (fMore != -1)
G__scratch_all();
}
//______________________________________________________________________________
void TCint::ClearFileBusy()
{
// Reset CINT internal state in case a previous action was not correctly terminated
// by G__init_cint() and G__dlmod().
G__clearfilebusy(0);
}
//______________________________________________________________________________
Int_t TCint::InitializeDictionaries()
{
// Initialize all registered dictionaries. Normally this is already done
// by G__init_cint() and G__dlmod().
return G__call_setup_funcs();
}
//______________________________________________________________________________
void TCint::EndOfLineAction()
{
// It calls a "fantom" method to synchronize user keyboard input
// and ROOT prompt line.
ProcessLineSynch(fantomline);
}
//______________________________________________________________________________
void TCint::ExecThreadCB(TWin32SendClass *command)
{
// This function must be called from the "Command thread only".
#ifdef WIN32
char *line = (char *)(command->GetData(0));
Int_t iret = ProcessLine((const char *)line);
delete [] line;
if (LOWORD(command->GetCOP()) == kSendWaitClass)
((TWin32SendWaitClass *)command)->Release();
else
delete command;
#else
if (command) { }
#endif
}
//______________________________________________________________________________
void TCint::LoadMacro(const char *filename)
{
// Load a macro file in CINT's memory.
ProcessLine(Form(".L %s", filename));
}
//______________________________________________________________________________
Int_t TCint::ProcessLine(const char *line)
{
// Let CINT process a command line.
Int_t ret = 0;
if (gApplication && gApplication->IsCmdThread()) {
gROOT->SetLineIsProcessing();
// It checks whether the input line contains the "fantom" method
// to synchronize user keyboard input and ROOT prompt line
if (strstr(line,fantomline))
TCint::UpdateAllCanvases();
else
ret = G__process_cmd((char *)line, fPrompt, &fMore);
gROOT->SetLineHasBeenProcessed();
} else
ret = ProcessLineAsynch(line);
return ret;
}
//______________________________________________________________________________
Int_t TCint::ProcessLineAsynch(const char *line)
{
// Let CINT process a command line asynch.
#ifndef WIN32
return ProcessLine(line);
#else
char *cmd = new char[strlen(line)+1];
strcpy(cmd,line);
TWin32SendClass *code = new TWin32SendClass(this,(UInt_t)cmd,0,0,0);
ExecCommandThread(code,kFALSE);
return 0;
#endif
}
//______________________________________________________________________________
Int_t TCint::ProcessLineSynch(const char *line)
{
// Let CINT process a command line synchronously, i.e we are waiting
// it will be finished.
if (gApplication && gApplication->IsCmdThread())
return ProcessLine(line);
#ifdef WIN32
char *cmd = new char[strlen(line)+1];
strcpy(cmd,line);
TWin32SendWaitClass code(this,(UInt_t)cmd,0,0,0);
ExecCommandThread(&code,kFALSE);
code.Wait();
#endif
return 0;
}
//______________________________________________________________________________
Long_t TCint::Calc(const char *line)
{
// Directly execute an executable statement (e.g. "func()", "3+5", etc.
// however not declarations, like "Int_t x;").
Long_t result;
#ifdef WIN32
// Test on ApplicationImp not being 0 is needed because only at end of
// TApplication ctor the IsLineProcessing flag is set to 0, so before
// we can not use it.
if (gApplication && gApplication->GetApplicationImp()) {
while (gROOT->IsLineProcessing() && !gApplication) {
Warning("Calc", "waiting for CINT thread to free");
gSystem->Sleep(500);
}
gROOT->SetLineIsProcessing();
}
#endif
result = (Long_t) G__int(G__calc((char *)line));
#ifdef WIN32
if (gApplication && gApplication->GetApplicationImp())
gROOT->SetLineHasBeenProcessed();
#endif
return result;
}
//______________________________________________________________________________
void TCint::PrintIntro()
{
// Print CINT introduction and help message.
Printf("nCINT/ROOT C/C++ Interpreter version %s", G__cint_version());
Printf("Type ? for help. Commands must be C++ statements.");
Printf("Enclose multiple statements between { }.");
}
//______________________________________________________________________________
void TCint::Reset()
{
// Reset the CINT state to the state saved by the last call to
// TCint::SaveContext().
G__scratch_upto(&fDictPos);
}
//______________________________________________________________________________
void TCint::ResetAll()
{
// Reset the CINT state to its initial state.
G__init_cint("cint");
G__init_process_cmd();
}
//______________________________________________________________________________
void TCint::ResetGlobals()
{
// Reset the CINT global object state to the state saved by the last
// call to TCint::SaveGlobalsContext().
G__scratch_globals_upto(&fDictPosGlobals);
}
//______________________________________________________________________________
void TCint::RewindDictionary()
{
// Rewind CINT dictionary to the point where it was before executing
// the current macro. This function is typically called after SEGV or
// ctlr-C after doing a longjmp back to the prompt.
G__rewinddictionary();
}
//______________________________________________________________________________
Int_t TCint::DeleteGlobal(void *obj)
{
// Delete obj from CINT symbol table so it cannot be accessed anymore.
// Returns 1 in case of success and 0 in case object was not in table.
return G__deleteglobal(obj);
}
//______________________________________________________________________________
void TCint::SaveContext()
{
// Save the current CINT state.
G__store_dictposition(&fDictPos);
}
//______________________________________________________________________________
void TCint::SaveGlobalsContext()
{
// Save the current CINT state of global objects.
G__store_dictposition(&fDictPosGlobals);
}
//______________________________________________________________________________
void TCint::UpdateListOfGlobals()
{
// Update the list of pointers to global variables. This function
// is called by TROOT::GetListOfGlobals().
G__DataMemberInfo *a;
int last = 0;
int nglob = 0;
// find the number of global objects
G__DataMemberInfo t;
while (t.Next()) nglob++;
for (int i = 0; i < nglob; i++) {
a = new G__DataMemberInfo();
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name()) {
// first remove if already in list
TGlobal *g = (TGlobal *)gROOT->fGlobals->FindObject(a->Name());
if (g) {
gROOT->fGlobals->Remove(g);
delete g;
}
gROOT->fGlobals->Add(new TGlobal(a));
} else
delete a;
last++;
}
}
//______________________________________________________________________________
void TCint::UpdateListOfGlobalFunctions()
{
// Update the list of pointers to global functions. This function
// is called by TROOT::GetListOfGlobalFunctions().
G__MethodInfo *a;
int last = 0;
int nglob = 0;
// find the number of global functions
G__MethodInfo t;
while (t.Next()) nglob++;
for (int i = 0; i < nglob; i++) {
a = new G__MethodInfo();
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name()) {
// first remove if already in list
TFunction *f = (TFunction *)gROOT->fGlobalFunctions->FindObject(a->Name());
if (f) {
gROOT->fGlobalFunctions->Remove(f);
delete f;
}
gROOT->fGlobalFunctions->Add(new TFunction(a));
} else
delete a;
last++;
}
}
//______________________________________________________________________________
void TCint::UpdateListOfTypes()
{
// Update the list of pointers to datatype (typedef) definitions. This
// function is called by TROOT::GetListOfTypes().
G__TypedefInfo *a;
int last = 0;
int ntype = 0;
// find the number of typedefs
G__TypedefInfo t;
while (t.Next()) ntype++;
for (int i = 0; i < ntype; i++) {
a = new G__TypedefInfo();
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name()) {
TDataType *d = (TDataType *)gROOT->fTypes->FindObject(a->Name());
// only add new types, don't delete old ones with the same name
// (as is done in UpdateListOfGlobals())
if (!d)
gROOT->fTypes->Add(new TDataType(a));
} else
delete a;
last++;
}
}
//______________________________________________________________________________
void TCint::SetClassInfo(TClass *cl)
{
// Set pointer to CINT's G__ClassInfo in TClass.
if (!cl->fClassInfo) {
cl->fClassInfo = new G__ClassInfo(cl->GetName());
if (!cl->fClassInfo->IsValid()) {
// this happens when no CINT dictionary is available
delete cl->fClassInfo;
cl->fClassInfo = 0;
}
}
}
//______________________________________________________________________________
void TCint::CreateListOfBaseClasses(TClass *cl)
{
// Create list of pointers to base class(es) for TClass cl.
if (!cl->fBase) {
cl->fBase = new TList(cl);
G__BaseClassInfo *a;
int last = 0;
int nbase = 0;
G__BaseClassInfo t(*cl->GetClassInfo());
while (t.Next()) nbase++;
for (int i = 0; i < nbase; i++) {
a = new G__BaseClassInfo(*cl->GetClassInfo());
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name())
cl->fBase->Add(new TBaseClass(a, cl));
else
delete a;
last++;
}
}
}
//______________________________________________________________________________
void TCint::CreateListOfDataMembers(TClass *cl)
{
// Create list of pointers to data members for TClass cl.
if (!cl->fData) {
cl->fData = new TList(cl);
G__DataMemberInfo *a;
int last = 0;
int nmem = cl->GetClassInfo()->NDataMembers();
for (int i = 0; i < nmem; i++) {
a = new G__DataMemberInfo(*cl->GetClassInfo());
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name() && strcmp(a->Name(), "G__virtualinfo"))
cl->fData->Add(new TDataMember(a, cl));
else
delete a;
last++;
}
}
}
//______________________________________________________________________________
void TCint::CreateListOfMethods(TClass *cl)
{
// Create list of pointers to methods for TClass cl.
if (!cl->fMethod) {
cl->fMethod = new TList(cl);
G__MethodInfo *a;
int last = 0;
int nmet = cl->GetClassInfo()->NMethods();
for (int i = 0; i < nmet; i++) {
a = new G__MethodInfo(*cl->GetClassInfo());
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if name cannot be obtained no use to put in list
if (a->IsValid() && a->Name())
cl->fMethod->Add(new TMethod(a, cl));
else
delete a;
last++;
}
}
}
//______________________________________________________________________________
void TCint::CreateListOfMethodArgs(TFunction *m)
{
// Create list of pointers to method arguments for TMethod m.
if (!m->fMethodArgs) {
m->fMethodArgs = new TList(m);
G__MethodArgInfo *a;
int last = 0;
int narg = m->GetNargs();
for (int i = 0; i < narg; i++) {
a = new G__MethodArgInfo(*m->fInfo);
a->Next(); // initial positioning
for (int j = 0; j < last; j++)
a->Next();
// if type cannot be obtained no use to put in list
if (a->IsValid() && a->Type())
m->fMethodArgs->Add(new TMethodArg(a, m));
else
delete a;
last++;
}
}
}
//______________________________________________________________________________
void *TCint::GetInterfaceMethod(TClass *cl, Text_t *method, Text_t *params)
{
// Return pointer to CINT interface function for a method of a class with
// parameters params (params is a string of actual arguments, not formal
// ones). If the class is 0 the global function list will be searched.
G__CallFunc func;
long offset;
if (cl)
func.SetFunc(cl->GetClassInfo(), method, params, &offset);
else {
G__ClassInfo gcl; // default G__ClassInfo is global environment
func.SetFunc(&gcl, method, params, &offset);
}
return (void *)func.InterfaceMethod();
}
//______________________________________________________________________________
void *TCint::GetInterfaceMethodWithPrototype(TClass *cl, Text_t *method, Text_t *proto)
{
// Return pointer to CINT interface function for a method of a class with
// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
// function list will be searched.
G__InterfaceMethod f;
long offset;
if (cl)
f = cl->GetClassInfo()->GetMethod(method, proto, &offset).InterfaceMethod();
else {
G__ClassInfo gcl; // default G__ClassInfo is global environment
f = gcl.GetMethod(method, proto, &offset).InterfaceMethod();
}
return (void *)f;
}
//______________________________________________________________________________
void TCint::Execute(const Text_t *function, const Text_t *params)
{
// Execute a global function with arguments params.
long offset;
G__CallFunc func;
G__ClassInfo cl;
// set pointer to interface method and arguments
func.SetFunc(&cl, (char*)function, (char*)params, &offset);
// call function
func.Exec(0);
}
//______________________________________________________________________________
void TCint::Execute(TObject *obj, TClass *cl, const Text_t *method, const Text_t *params)
{
// Execute a method from class cl with arguments params.
void *address;
long offset;
G__CallFunc func;
// set pointer to interface method and arguments
func.SetFunc(cl->GetClassInfo(), (char*)method, (char*)params, &offset);
// call function
address = (void*)((Long_t)obj + offset);
func.Exec(address);
}
//______________________________________________________________________________
void TCint::Execute(TObject *obj, TClass *cl, TMethod *method, TObjArray *params)
{
// Execute a method from class cl with the arguments in array params
// (params[0] ... params[n] = array of TObjString parameters).
// Convert the TObjArray array of TObjString parameters to a character
// string of comma separated parameters.
// The parameters of type 'char' are enclosed in double quotes and all
// internal quotes are escaped.
if (!method) {
Error("Execute","No method was defined");
return;
}
TList *argList = method->GetListOfMethodArgs();
// Check number of actual parameters against of expected formal ones
Int_t nparms = argList->LastIndex()+1;
Int_t argc = params ? params->LastIndex()+1:0;
if (nparms != argc) {
Error("Execute","Wrong number of the parameters");
return;
}
const Text_t *listpar = "";
TString complete(10);
if (params)
{
// Create a character string of parameters from TObjArray
TIter next(params);
for (Int_t i = 0; i < argc; i ++)
{
TMethodArg *arg = (TMethodArg *) argList->At( i );
G__TypedefInfo type( arg->GetFullTypeName() );
TObjString *nxtpar = (TObjString *)next();
if (i) complete.Append(',');
if (!strncmp( type.TrueName(), "char", 4 ))
{
TString chpar('"');
chpar.Append((nxtpar->String()).ReplaceAll(""","\""));
// At this point we have to check if string contains \"
// and apply some more sophisticated parser. Not implemented yet!
complete.Append(chpar);
complete.Append('"');
}
else
complete.Append(nxtpar->String());
}
listpar = complete.Data();
}
Execute(obj, cl, (Text_t *)method->GetName(), (char *)listpar);
}
//______________________________________________________________________________
Int_t TCint::ExecuteMacro(const char *filename)
{
// Execute a CINT macro.
G__value result = G__exec_tempfile((char*)filename);
return 0; // could get return value from result, but what about return type?
}
//______________________________________________________________________________
const char *TCint::TypeName(const char *typeDesc)
{
// Return the absolute type of typeDesc.
// E.g.: typeDesc = "class TNamed**", returns "TNamed".
// You need to use the result immediately before it is being overwritten.
static char t[64];
char *s;
if (!strstr(typeDesc, "(*)(") && (s = strchr(typeDesc, ' ')))
strcpy(t, s+1);
else
strcpy(t, typeDesc);
int l = strlen(t);
while (l > 0 && t[l-1] == '*') t[--l] = 0;
return t;
}
//______________________________________________________________________________
void *TCint::FindObject(char *item, G__ClassInfo *type, void **prevObj,
void **assocPtr)
{
// Static function called by CINT when it finds an un-indentified object.
// This function tries to find the UO in the ROOT files, directories, etc.
// This functions has been registered by the TCint ctor.
if (!*prevObj || *assocPtr != gDirectory)
*prevObj = gROOT->FindObject(item, *assocPtr);
if (*prevObj) type->Init(((TObject *)*prevObj)->ClassName());
return *prevObj;
}
//______________________________________________________________________________
void TCint::UpdateClassInfo(char *item, Long_t tagnum)
{
// Static function called by CINT when it changes the tagnum for
// a class (e.g. after re-executing the setup function). In such
// cases we have to update the tagnum in the G__ClassInfo used by
// the TClass for class "item".
if (gROOT && gROOT->GetListOfClasses()) {
TClass *cl = gROOT->GetClass(item, kFALSE);
if (cl) {
G__ClassInfo *info = cl->GetClassInfo();
if (info && info->Tagnum() != tagnum) {
info->Init((int)tagnum);
if (cl->fBase)
cl->fBase->Delete();
delete cl->fBase;
cl->fBase = 0;
}
}
}
}
//______________________________________________________________________________
void TCint::UpdateAllCanvases()
{
// Update all canvases at end the terminal input command.
TIter next(gROOT->GetListOfCanvases());
TVirtualPad *canvas;
while ((canvas = (TVirtualPad *)next()))
canvas->Update();
}
//______________________________________________________________________________
const char* TCint::GetSharedLibs()
{
// Refresh the list of shared libraries and return it.
fSharedLibs = "";
G__SourceFileInfo cursor(0);
while (cursor.IsValid()) {
const char *filename = cursor.Name();
if (filename &&
(strstr(filename,".sl") != 0 ||
strstr(filename,".dl") != 0 ||
strstr(filename,".so") != 0 ||
strstr(filename,".dll") != 0 ||
strstr(filename,".DLL") != 0)) {
if (!fSharedLibs.IsNull())
fSharedLibs.Append(" ");
fSharedLibs.Append(filename);
}
cursor.Next();
}
return fSharedLibs;
}
//______________________________________________________________________________
const char* TCint::GetIncludePath()
{
// Refresh the list of include path known to the interpreter and return it,
// with -I prepended.
fIncludePath = "";
G__IncludePathInfo path;
while ( path.Next() ) {
const char *pathname = path.Name();
fIncludePath.Append(" -I").Append(pathname);
} ;
return fIncludePath;
}
ROOT page - Class index - 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.