#include "TCint.h"
#include "G__ci.h"
#include "TROOT.h"
#include "TApplication.h"
#include "TGlobal.h"
#include "TDataType.h"
#include "TClass.h"
#include "TClassEdit.h"
#include "TBaseClass.h"
#include "TDataMember.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TString.h"
#include "THashList.h"
#include "TOrdCollection.h"
#include "TVirtualPad.h"
#include "TSystem.h"
#include "TVirtualMutex.h"
#include "TError.h"
#include "TEnv.h"
#include "THashTable.h"
#include <vector>
#include <set>
#include <string>
using namespace std;
R__EXTERN int optind;
#include "Api.h"
extern "C" int ScriptCompiler(const char *filename, const char *opt) {
   return gSystem->CompileMacro(filename, opt);
}
extern "C" int IgnoreInclude(const char *fname, const char *expandedfname) {
   return gROOT->IgnoreInclude(fname,expandedfname);
}
extern "C" void TCint_UpdateClassInfo(char *c, Long_t l) {
   TCint::UpdateClassInfo(c, l);
}
extern "C" int TCint_AutoLoadCallback(char *c, char *l) {
   ULong_t varp = G__getgvp();
   G__setgvp(G__PVOID);
   string cls(c);
   int result =  TCint::AutoLoadCallback(cls.c_str(), l);
   G__setgvp(varp);
   return result;
}
extern "C" void *TCint_FindSpecialObject(char *c, G__ClassInfo *ci, void **p1, void **p2) {
   return TCint::FindSpecialObject(c, ci, p1, p2);
}
const char *fantomline = "TRint::EndOfLineAction();";
void* TCint::fgSetOfSpecials = 0;
ClassImp(TCint)
TCint::TCint(const char *name, const char *title) : TInterpreter(name, title)
{
   
   fMore      = 0;
   fPrompt[0] = 0;
   fMapfile   = 0;
   fRootMapFiles = 0;
   fLockProcessLine = kTRUE;
   G__RegisterScriptCompiler(&ScriptCompiler);
   G__set_ignoreinclude(&IgnoreInclude);
   G__InitUpdateClassInfo(&TCint_UpdateClassInfo);
   G__InitGetSpecialObject(&TCint_FindSpecialObject);
   fDictPos.ptype = 0;
   fDictPosGlobals.ptype = 0;
   ResetAll();
#ifndef R__WIN32
   optind = 1;  
#endif
   
   G__LockCpp();
}
TCint::~TCint()
{
   
   if (fMore != -1) {
      
      
      G__close_inputfiles();
   }
   free(fDictPos.ptype);
   free(fDictPosGlobals.ptype);
   delete fMapfile;
   delete fRootMapFiles;
}
void TCint::ClearFileBusy()
{
   
   
   G__clearfilebusy(0);
}
void TCint::ClearStack()
{
   
   G__clearstack();
}
Int_t TCint::InitializeDictionaries()
{
   
   
   return G__call_setup_funcs();
}
void TCint::EnableAutoLoading()
{
   
   
   
   
   G__set_class_autoloading_callback(&TCint_AutoLoadCallback);
   LoadLibraryMap();
}
void TCint::EndOfLineAction()
{
   
   
   ProcessLineSynch(fantomline);
}
Bool_t TCint::IsLoaded(const char* filename) const
{
   
   
   
   
   
   
   G__SourceFileInfo file(filename);
   if (file.IsValid()) { return kTRUE; };
   char *next = gSystem->Which(TROOT::GetMacroPath(), filename, kReadPermission);
   if (next) {
      file.Init(next);
      delete [] next;
      if (file.IsValid()) { return kTRUE; };
   }
   TString incPath = gSystem->GetIncludePath(); 
   incPath.Append(":").Prepend(" ");
   incPath.ReplaceAll(" -I",":");       
   while ( incPath.Index(" :") != -1 ) {
      incPath.ReplaceAll(" :",":");
   }
   incPath.Prepend(".:");
   incPath.Append(":$ROOTSYS/cint/include:$ROOTSYS/cint/stl");
   next = gSystem->Which(incPath, filename, kReadPermission);
   if (next) {
      file.Init(next);
      delete [] next;
      if (file.IsValid()) { return kTRUE; };
   }
   next = gSystem->DynamicPathName(filename,kTRUE);
   if (next) {
      file.Init(next);
      delete [] next;
      if (file.IsValid()) { return kTRUE; };
   }
   return kFALSE;
}
Int_t TCint::Load(const char *filename, Bool_t system)
{
   
   
   R__LOCKGUARD2(gCINTMutex);
   int i;
   if (!system)
      i = G__loadfile(filename);
   else
      i = G__loadsystemfile(filename);
   UpdateListOfTypes();
   return i;
}
void TCint::LoadMacro(const char *filename, EErrorCode *error)
{
   
   ProcessLine(Form(".L %s", filename), error);
}
Long_t TCint::ProcessLine(const char *line, EErrorCode *error)
{
   
   
   
   
   Long_t ret = 0;
   if (gApplication) {
      if (gApplication->IsCmdThread()) {
         if (gGlobalMutex && !gCINTMutex && fLockProcessLine) {
            gGlobalMutex->Lock();
            if (!gCINTMutex)
               gCINTMutex = gGlobalMutex->Factory(kTRUE);
            gGlobalMutex->UnLock();
         }
         R__LOCKGUARD(fLockProcessLine ? gCINTMutex : 0);
         gROOT->SetLineIsProcessing();
         G__value local_res;
         G__setnull(&local_res);
         
         
         if (strstr(line,fantomline)) {
            G__free_tempobject();
            TCint::UpdateAllCanvases();
         } else {
            int local_error = 0;
            int prerun = G__getPrerun();
            G__setPrerun(0);
            ret = G__process_cmd((char *)line, fPrompt, &fMore, &local_error, &local_res);
            G__setPrerun(prerun);
            if (local_error == 0 && G__get_return(&fExitCode) == G__RETURN_EXIT2) {
               ResetGlobals();
               gApplication->Terminate(fExitCode);
            }
            if (error)
               *error = (EErrorCode)local_error;
         }
         if (ret==0) ret = G__int_cast(local_res);
         gROOT->SetLineHasBeenProcessed();
      } else
         ret = ProcessLineAsynch(line, error);
   }
   return ret;
}
Long_t TCint::ProcessLineAsynch(const char *line, EErrorCode *error)
{
   
   return ProcessLine(line, error);
}
Long_t TCint::ProcessLineSynch(const char *line, EErrorCode *error)
{
   
   
   if (gApplication && gApplication->IsCmdThread())
      return ProcessLine(line, error);
   return 0;
}
Long_t TCint::Calc(const char *line, EErrorCode *error)
{
   
   
   Long_t result;
#ifdef R__WIN32
   
   
   
   if (gApplication && gApplication->GetApplicationImp()) {
      while (gROOT->IsLineProcessing() && !gApplication) {
         Warning("Calc", "waiting for CINT thread to free");
         gSystem->Sleep(500);
      }
      gROOT->SetLineIsProcessing();
   }
#endif
   R__LOCKGUARD2(gCINTMutex);
   result = (Long_t) G__int_cast(G__calc((char *)line));
   if (error) *error = (EErrorCode)G__lasterror();
#ifdef R__WIN32
   if (gApplication && gApplication->GetApplicationImp())
      gROOT->SetLineHasBeenProcessed();
#endif
   return result;
}
void TCint::PrintIntro()
{
   
   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::RecursiveRemove(TObject *obj)
{
   
   
   if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
      std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
      if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
         DeleteGlobal(obj);
         ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
      }
   }
}
void TCint::Reset()
{
   
   
   G__scratch_upto(&fDictPos);
}
void TCint::ResetAll()
{
   
   G__init_cint("cint +V");
   G__init_process_cmd();
}
void TCint::ResetGlobals()
{
   
   
   G__scratch_globals_upto(&fDictPosGlobals);
}
void TCint::RewindDictionary()
{
   
   
   
   G__rewinddictionary();
}
Int_t TCint::DeleteGlobal(void *obj)
{
   
   
   return G__deleteglobal(obj);
}
void TCint::SaveContext()
{
   
   G__store_dictposition(&fDictPos);
}
void TCint::SaveGlobalsContext()
{
   
   G__store_dictposition(&fDictPosGlobals);
}
void TCint::UpdateListOfGlobals()
{
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__DataMemberInfo t, *a;
   while (t.Next()) {
      
      if (t.IsValid() && t.Name()) {
         
         TGlobal *g = (TGlobal *)gROOT->fGlobals->FindObject(t.Name());
         if (g) {
            gROOT->fGlobals->Remove(g);
            delete g;
         }
         a = new G__DataMemberInfo(t);
         gROOT->fGlobals->Add(new TGlobal(a));
      }
   }
}
void TCint::UpdateListOfGlobalFunctions()
{
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__MethodInfo t, *a;
   void* vt =0;
   while (t.Next()) {
      
      if (t.IsValid() && t.Name()) {
         Bool_t needToAdd = kTRUE;
         
         TList* listFuncs = ((THashTable*)(gROOT->fGlobalFunctions))->GetListForObject(t.Name());
         if (listFuncs && (vt = (void*)t.InterfaceMethod())) {
            Int_t prop = -1;
            TIter iFunc(listFuncs);
            TFunction* f = 0;
            Bool_t foundStart = kFALSE;
            while (needToAdd && (f = (TFunction*)iFunc())) {
               if (strcmp(f->GetName(),t.Name())) {
                  if (foundStart) break;
                  continue;
               }
               foundStart = kTRUE;
               if (vt == f->InterfaceMethod()) {
                  if (prop == -1)
                     prop = t.Property();
                  needToAdd = !((prop & G__BIT_ISCOMPILED)
                                || t.GetMangledName() == f->GetMangledName());
               }
            }
         }
         if (needToAdd) {
            a = new G__MethodInfo(t);
            gROOT->fGlobalFunctions->Add(new TFunction(a));
         }
      }
   }
}
void TCint::UpdateListOfTypes()
{
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__TypedefInfo t;
   while (t.Next()) {
      if (gROOT && gROOT->fTypes && t.IsValid() && t.Name()) {
         TDataType *d = (TDataType *)gROOT->fTypes->FindObject(t.Name());
         
         
         
         if (!d) {
            gROOT->fTypes->Add(new TDataType(new G__TypedefInfo(t)));
         }
      }
   }
}
void TCint::SetClassInfo(TClass *cl, Bool_t reload)
{
   
   R__LOCKGUARD2(gCINTMutex);
   if (!cl->fClassInfo || reload) {
      delete cl->fClassInfo; cl->fClassInfo = 0;
      if (CheckClassInfo(cl->GetName())) {
         cl->fClassInfo = new G__ClassInfo(cl->GetName());
         
         
         
         
         
         
         
         if (cl->fClassInfo->IsValid() &&
             !(cl->fClassInfo->Property() & (kIsClass|kIsStruct))) {
            cl->MakeZombie();
         }
         if (!cl->fClassInfo->IsLoaded()) {
            
            delete cl->fClassInfo;
            cl->fClassInfo = 0;
         }
      }
   }
}
Bool_t TCint::CheckClassInfo(const char *name)
{
   
   
   
   
   
   
   
   
   char *classname = new char[strlen(name)*2];
   strcpy(classname,name);
   char *current = classname;
   while (*current) {
      while (*current && *current != ':' && *current != '<')
         current++;
      if (!*current) break;
      if (*current == '<') {
         int level = 1;
         current++;
         while (*current && level > 0) {
            if (*current == '<') level++;
            if (*current == '>') level--;
            current++;
         }
         continue;
      }
      
      if (*(current+1) != ':') {
         Error("CheckClassInfo", "unexpected token : in %s", classname);
         delete [] classname;
         return kFALSE;
      }
      *current = '\0';
      G__ClassInfo info(classname);
      if (!info.IsValid()) {
         delete [] classname;
         return kFALSE;
      }
      *current = ':';
      current += 2;
   }
   strcpy(classname,name);
   Int_t tagnum = G__defined_tagname(classname, 2); 
   if (tagnum >= 0) {
      delete [] classname;
      return kTRUE;
   }
   G__TypedefInfo t(name);
   if (t.IsValid() && !(t.Property()&G__BIT_ISFUNDAMENTAL)) {
      delete [] classname;
      return kTRUE;
   }
   delete [] classname;
   return kFALSE;
}
void TCint::CreateListOfBaseClasses(TClass *cl)
{
   
   R__LOCKGUARD2(gCINTMutex);
   if (!cl->fBase) {
      cl->fBase = new TList;
      G__BaseClassInfo t(*cl->GetClassInfo()), *a;
      while (t.Next()) {
         
         if (t.IsValid() && t.Name()) {
            a = new G__BaseClassInfo(t);
            cl->fBase->Add(new TBaseClass(a, cl));
         }
      }
   }
}
void TCint::CreateListOfDataMembers(TClass *cl)
{
   
   R__LOCKGUARD2(gCINTMutex);
   if (!cl->fData) {
      cl->fData = new TList;
      G__DataMemberInfo t(*cl->GetClassInfo()), *a;
      while (t.Next()) {
         
         if (t.IsValid() && t.Name() && strcmp(t.Name(), "G__virtualinfo")) {
            a = new G__DataMemberInfo(t);
            cl->fData->Add(new TDataMember(a, cl));
         }
      }
   }
}
void TCint::CreateListOfMethods(TClass *cl)
{
   
   R__LOCKGUARD2(gCINTMutex);
   if (!cl->fMethod) {
      cl->fMethod = new TList;
      G__MethodInfo t(*cl->GetClassInfo()), *a;
      while (t.Next()) {
         
         if (t.IsValid() && t.Name()) {
            a = new G__MethodInfo(t);
            cl->fMethod->Add(new TMethod(a, cl));
         }
      }
   }
}
void TCint::CreateListOfMethodArgs(TFunction *m)
{
   
   R__LOCKGUARD2(gCINTMutex);
   if (!m->fMethodArgs) {
      m->fMethodArgs = new TList;
      G__MethodArgInfo t(*m->fInfo), *a;
      while (t.Next()) {
         
         if (t.IsValid() && t.Type()) {
            a = new G__MethodArgInfo(t);
            m->fMethodArgs->Add(new TMethodArg(a, m));
         }
      }
   }
}
TString TCint::GetMangledName(TClass *cl, const char *method,
                             const char *params)
{
   
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__CallFunc  func;
   Long_t       offset;
   if (cl)
      func.SetFunc(cl->GetClassInfo(), method, params, &offset);
   else {
      G__ClassInfo gcl;   
      func.SetFunc(&gcl, method, params, &offset);
   }
   return func.GetMethodInfo().GetMangledName();
}
TString TCint::GetMangledNameWithPrototype(TClass *cl, const char *method,
                                           const char *proto)
{
   
   
   
   R__LOCKGUARD2(gCINTMutex);
   Long_t             offset;
   if (cl)
      return cl->GetClassInfo()->GetMethod(method, proto, &offset).GetMangledName();
   G__ClassInfo gcl;   
   return gcl.GetMethod(method, proto, &offset).GetMangledName();
}
void *TCint::GetInterfaceMethod(TClass *cl, const char *method,
                                const char *params)
{
   
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__CallFunc  func;
   Long_t       offset;
   if (cl)
      func.SetFunc(cl->GetClassInfo(), method, params, &offset);
   else {
      G__ClassInfo gcl;   
      func.SetFunc(&gcl, method, params, &offset);
   }
   return (void *)func.InterfaceMethod();
}
void *TCint::GetInterfaceMethodWithPrototype(TClass *cl, const char *method,
                                             const char *proto)
{
   
   
   
   R__LOCKGUARD2(gCINTMutex);
   G__InterfaceMethod f;
   Long_t             offset;
   if (cl)
      f = cl->GetClassInfo()->GetMethod(method, proto, &offset).InterfaceMethod();
   else {
      G__ClassInfo gcl;   
      f = gcl.GetMethod(method, proto, &offset).InterfaceMethod();
   }
   return (void *)f;
}
const char *TCint::GetInterpreterTypeName(const char *name, Bool_t full)
{
   
   
   
   
   
   if (!gInterpreter->CheckClassInfo(name)) return 0;
   G__ClassInfo cl(name);
   if (cl.IsValid()) {
      if (full) return cl.Fullname();
      else return cl.Name();
   }
   else return 0;
}
void TCint::Execute(const char *function, const char *params, int *error)
{
   
   R__LOCKGUARD2(gCINTMutex);
   G__CallFunc  func;
   G__ClassInfo cl;
   Long_t       offset;
   
   func.SetFunc(&cl, function, params, &offset);
   
   func.Exec(0);
   if (error) *error = G__lasterror();
}
void TCint::Execute(TObject *obj, TClass *cl, const char *method,
                    const char *params, int *error)
{
   
   R__LOCKGUARD2(gCINTMutex);
   void       *address;
   Long_t      offset;
   G__CallFunc func;
   
   
   
   void *addr = cl->DynamicCast( TObject::Class(), obj, kFALSE);
   
   func.SetFunc(cl->GetClassInfo(), method, params, &offset);
   
   address = (void*)((Long_t)addr + offset);
   func.Exec(address);
   if (error) *error = G__lasterror();
}
void TCint::Execute(TObject *obj, TClass *cl, TMethod *method, TObjArray *params,
                    int *error)
{
   
   
   
   
   
   
   if (!method) {
      Error("Execute","No method was defined");
      return;
   }
   TList *argList = method->GetListOfMethodArgs();
   
   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 char *listpar = "";
   TString complete(10);
   if (params)
   {
      
      TIter next(params);
      for (Int_t i = 0; i < argc; i ++)
      {
         TMethodArg *arg = (TMethodArg *) argList->At( i );
         G__TypeInfo type( arg->GetFullTypeName() );
         TObjString *nxtpar = (TObjString *)next();
         if (i) complete += ',';
         if (strstr( type.TrueName(), "char" )) {
            TString chpar('\"');
            chpar += (nxtpar->String()).ReplaceAll("\"","\\\"");
            
            
            complete += chpar;
            complete += '\"';
         }
         else
            complete += nxtpar->String();
      }
      listpar = complete.Data();
   }
   Execute(obj, cl, (char *)method->GetName(), (char *)listpar, error);
}
Long_t TCint::ExecuteMacro(const char *filename, EErrorCode *error)
{
   
   if (gApplication)
      return gApplication->ProcessFile(filename, (int*)error);
   else
       G__exec_tempfile((char*)filename);
   return 0;  
}
const char *TCint::GetTopLevelMacroName()
{
   
   
   G__SourceFileInfo srcfile(G__get_ifile()->filenum);
   while (srcfile.IncludedFrom().IsValid())
      srcfile = srcfile.IncludedFrom();
   return srcfile.Name();
}
const char *TCint::GetCurrentMacroName()
{
   
   
   
   
   /* -->
      <span style="color:#ffffff;background-color:#7777ff;padding-left:0.3em;padding-right:0.3em">inclfile.h</span>
      <!--div style="border:solid 1px #ffff77;background-color: #ffffdd;float:left;padding:0.5em;margin-bottom:0.7em;"-->
      <div class="code">
      <pre style="margin:0pt">#include <iostream>
void inclfunc() {
   std::cout << "In inclfile.h" << std::endl;
   std::cout << "  TCint::GetCurrentMacroName() returns  " <<
      TCint::GetCurrentMacroName() << std::endl;
   std::cout << "  TCint::GetTopLevelMacroName() returns " <<
      TCint::GetTopLevelMacroName() << std::endl;
}</pre></div>
      <div style="clear:both"></div>
      <span style="color:#ffffff;background-color:#7777ff;padding-left:0.3em;padding-right:0.3em">mymacro.C</span>
      <div style="border:solid 1px #ffff77;background-color: #ffffdd;float:left;padding:0.5em;margin-bottom:0.7em;">
      <pre style="margin:0pt">#include <iostream>
#include "inclfile.h"
void mymacro() {
   std::cout << "In mymacro.C" << std::endl;
   std::cout << "  TCint::GetCurrentMacroName() returns  " <<
      TCint::GetCurrentMacroName() << std::endl;
   std::cout << "  TCint::GetTopLevelMacroName() returns " <<
      TCint::GetTopLevelMacroName() << std::endl;
   std::cout << "  Now calling inclfunc..." << std::endl;
   inclfunc();
}</pre></div>
<div style="clear:both"></div>
<!-- */
// --> END_HTML
   
   
   
   
   
   
   
   
   
   
   return G__get_ifile()->name;
}
const char *TCint::TypeName(const char *typeDesc)
{
   
   
   
   static char t[1024];
   char *s, *template_start;
   if (!strstr(typeDesc, "(*)(")) {
      s = (char*)strchr(typeDesc, ' ');
      template_start = (char*)strchr(typeDesc, '<');
      if (!strcmp(typeDesc, "long long"))
         strcpy(t, typeDesc);
      
      
      
      
      else if (s && (template_start==0 || (s < template_start)) )
         strcpy(t, s+1);
      else
         strcpy(t, typeDesc);
   }
   int l = strlen(t);
   while (l > 0 && (t[l-1] == '*' || t[l-1] == '&') ) t[--l] = 0;
   return t;
}
Int_t TCint::LoadLibraryMap(const char *rootmapfile)
{
   
   
   
   
   
   
   
   if (!fMapfile) {
      fMapfile = new TEnv(".rootmap");
      fMapfile->IgnoreDuplicates(kTRUE);
      fRootMapFiles = new TObjArray;
      fRootMapFiles->SetOwner();
      
      
      TString ldpath = gSystem->GetDynamicPath();
#ifdef WIN32
      TObjArray *paths = ldpath.Tokenize(";");
#else
      TObjArray *paths = ldpath.Tokenize(":");
#endif
      TString d;
      for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
         d = ((TObjString*)paths->At(i))->GetString();
         
         Int_t skip = 0;
         for (Int_t j = 0; j < i; j++) {
            TString pd = ((TObjString*)paths->At(j))->GetString();
            if (pd == d) {
               skip++;
               break;
            }
         }
         if (!skip) {
            void *dirp = gSystem->OpenDirectory(d);
            if (dirp) {
               if (gDebug > 0)
                  Info("LoadLibraryMap", "%s", d.Data());
               const char *f1;
               while ((f1 = gSystem->GetDirEntry(dirp))) {
                  TString f = f1;
                  if (f.EndsWith(".rootmap")) {
                     TString p;
                     p = d + "/" + f;
                     if (!gSystem->AccessPathName(p, kReadPermission)) {
                        if (gDebug > 1)
                           Info("LoadLibraryMap", "   rootmap file: %s", p.Data());
                        fMapfile->ReadFile(p, kEnvGlobal);
                        fRootMapFiles->Add(new TObjString(p));
                     }
                  }
                  if (f.BeginsWith("rootmap")) {
                     TString p;
                     p = d + "/" + f;
                     FileStat_t stat;
                     if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode))
                        Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
                  }
               }
            }
            gSystem->FreeDirectory(dirp);
         }
      }
      delete paths;
      if (!fMapfile->GetTable()->GetEntries()) {
         return -1;
      }
   }
   if (rootmapfile && *rootmapfile) {
      
      fMapfile->IgnoreDuplicates(kFALSE);
      fMapfile->ReadFile(rootmapfile, kEnvGlobal);
   }
   TEnvRec *rec;
   TIter next(fMapfile->GetTable());
   while ((rec = (TEnvRec*) next())) {
      TString cls = rec->GetName();
      if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
         
         TString libs = rec->GetValue();
         if (libs == "") continue;
         TString delim(" ");
         TObjArray *tokens = libs.Tokenize(delim);
         char *lib = (char *)((TObjString*)tokens->At(0))->GetName();
         
         
         cls.Remove(0,8);
         cls.ReplaceAll("@@", "::");
         
         
         cls.ReplaceAll("-", " ");
         if (cls.Contains(":")) {
            
            int slen = cls.Length();
            for (int k = 0; k < slen; k++) {
               if (cls[k] == ':') {
                  if (k+1 >= slen || cls[k+1] != ':') {
                     
                     break;
                  }
                  if (k) {
                     TString base = cls(0, k);
                     if (base == "std") {
                        
                        break;
                     } else {
                        
                        
                        
                        G__set_class_autoloading_table((char*)base.Data(), "");
                     }
                     ++k;
                  }
               } else if (cls[k] == '<') {
                  
                  break;
               }
            }
         }
         G__set_class_autoloading_table((char*)cls.Data(), lib);
         G__security_recover(stderr); 
         if (gDebug > 2) {
            const char *wlib = gSystem->Which(gSystem->GetDynamicPath(), lib);
            Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
            delete [] wlib;
         }
         delete tokens;
      }
   }
   return 0;
}
Int_t TCint::UnloadLibraryMap(const char *library)
{
   
   
   
   if (!fMapfile || !library || !*library)
      return 0;
   TEnvRec *rec;
   TIter next(fMapfile->GetTable());
   Int_t ret = 0;
   while ((rec = (TEnvRec*) next())) {
      TString cls = rec->GetName();
      if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
         
         TString libs = rec->GetValue();
         if (libs == "") continue;
         TString delim(" ");
         TObjArray *tokens = libs.Tokenize(delim);
         const char *lib = ((TObjString*)tokens->At(0))->GetName();
         
         
         cls.Remove(0,8);
         cls.ReplaceAll("@@", "::");
         
         
         cls.ReplaceAll("-", " ");
         if (cls.Contains(":")) {
            
            int slen = cls.Length();
            for (int k = 0; k < slen; k++) {
               if (cls[k] == ':') {
                  if (k+1 >= slen || cls[k+1] != ':') {
                     
                     break;
                  }
                  if (k) {
                     TString base = cls(0, k);
                     if (base == "std") {
                        
                        break;
                     } else {
                        
                        
                        
                        
                     }
                     ++k;
                  }
               } else if (cls[k] == '<') {
                  
                  break;
               }
            }
         }
         if (!strcmp(library, lib)) {
            if (fMapfile->GetTable()->Remove(rec) == 0) {
               Error("UnloadLibraryMap", "entry for <%s,%s> not found in library map table", cls.Data(), lib);
               ret = -1;
            }
         }
         G__set_class_autoloading_table((char*)cls.Data(), "");
         G__security_recover(stderr); 
         delete tokens;
      }
   }
   return ret;
}
Int_t TCint::AutoLoad(const char *cls)
{
   
   
   Int_t status = 0;
   if (!gROOT || !gInterpreter) return status;
   
   Int_t oldvalue = G__set_class_autoloading(0);
   
   TString deplibs = gInterpreter->GetClassSharedLibs(cls);
   if (!deplibs.IsNull()) {
      TString delim(" ");
      TObjArray *tokens = deplibs.Tokenize(delim);
      for (Int_t i = tokens->GetEntriesFast()-1; i > 0; i--) {
         const char *deplib = ((TObjString*)tokens->At(i))->GetName();
         if (gROOT->LoadClass(cls, deplib) == 0) {
            if (gDebug > 0)
               ::Info("TCint::AutoLoad", "loaded dependent library %s for class %s",
                      deplib, cls);
         } else
            ::Error("TCint::AutoLoad", "failure loading dependent library %s for class %s",
                    deplib, cls);
      }
      const char *lib = ((TObjString*)tokens->At(0))->GetName();
      if (lib[0]) {
         if (gROOT->LoadClass(cls, lib) == 0) {
            if (gDebug > 0)
               ::Info("TCint::AutoLoad", "loaded library %s for class %s",
                      lib, cls);
            status = 1;
         } else
            ::Error("TCint::AutoLoad", "failure loading library %s for class %s",
                    lib, cls);
      }
      delete tokens;
   }
   G__set_class_autoloading(oldvalue);
   return status;
}
Int_t TCint::AutoLoadCallback(const char *cls, const char *lib)
{
   
   
   if (!gROOT || !gInterpreter || !cls || !lib) return 0;
   
   
   
   if (strstr(lib, "libCore")) return 1;
   
   TString deplibs = gInterpreter->GetClassSharedLibs(cls);
   if (!deplibs.IsNull()) {
      TString delim(" ");
      TObjArray *tokens = deplibs.Tokenize(delim);
      for (Int_t i = tokens->GetEntriesFast()-1; i > 0; i--) {
         const char *deplib = ((TObjString*)tokens->At(i))->GetName();
         gROOT->LoadClass(cls, deplib);
         if (gDebug > 0)
            ::Info("TCint::AutoLoadCallback", "loaded dependent library %s for class %s",
                   deplib, cls);
      }
      delete tokens;
   }
   if (lib[0]) {
      if (gROOT->LoadClass(cls, lib) == 0) {
         if (gDebug > 0)
            ::Info("TCint::AutoLoadCallback", "loaded library %s for class %s",
            lib, cls);
         return 1;
      } else
         ::Error("TCint::AutoLoadCallback", "failure loading library %s for class %s",
         lib, cls);
   }
   return 0;
}
void *TCint::FindSpecialObject(const char *item, G__ClassInfo *type,
                               void **prevObj, void **assocPtr)
{
   
   
   
   if (!*prevObj || *assocPtr != gDirectory) {
      *prevObj = gROOT->FindSpecialObject(item, *assocPtr);
      if (!fgSetOfSpecials) fgSetOfSpecials = new std::set<TObject*>;
      if (*prevObj) ((std::set<TObject*>*)fgSetOfSpecials)->insert((TObject*)*prevObj);
   }
   if (*prevObj) type->Init(((TObject *)*prevObj)->ClassName());
   return *prevObj;
}
namespace {
   class TInfoNode {
   private:
      string fName;
      Long_t fTagnum;
   public:
      TInfoNode(const char *item, Long_t tagnum)
         : fName(item),fTagnum(tagnum)
      {}
      void Update() {
         Update(fName.c_str(),fTagnum);
      }
      static void Update(const char *item, Long_t tagnum)
      {
         Bool_t load = kFALSE;
         if (strchr(item,'<')) {
            
            TIter next( gROOT->GetListOfClasses() );
            TClass *cl;
            TString resolvedItem(
               TClassEdit::ResolveTypedef(TClassEdit::ShortType(item,
                  TClassEdit::kDropStlDefault).c_str(), kTRUE) );
            TString resolved;
            while ( (cl = (TClass*)next()) ) {
               resolved = TClassEdit::ResolveTypedef(TClassEdit::ShortType(cl->GetName(),
                  TClassEdit::kDropStlDefault).c_str(), kTRUE);
               if (resolved==resolvedItem) {
                  
                  
                  load = kTRUE;
               }
            }
         }
         TClass *cl = TClass::GetClass(item, load);
         if (cl) cl->ResetClassInfo(tagnum);
      }
   };
}
void TCint::UpdateClassInfo(char *item, Long_t tagnum)
{
   
   
   
   
   if (gROOT && gROOT->GetListOfClasses()) {
      static Bool_t entered = kFALSE;
      static vector<TInfoNode> updateList;
      Bool_t topLevel;
      if (entered) topLevel = kFALSE;
      else {
         entered = kTRUE;
         topLevel = kTRUE;
      }
      if (topLevel) {
         TInfoNode::Update(item,tagnum);
      } else {
         
         
         
         
         
         
         
         updateList.push_back(TInfoNode(item,tagnum));
      }
      if (topLevel) {
         while (!updateList.empty()) {
            TInfoNode current( updateList.back() );
            updateList.pop_back();
            current.Update();
         }
         entered = kFALSE;
      }
   }
}
void TCint::UpdateAllCanvases()
{
   
   TIter next(gROOT->GetListOfCanvases());
   TVirtualPad *canvas;
   while ((canvas = (TVirtualPad *)next()))
      canvas->Update();
}
const char* TCint::GetSharedLibs()
{
   
   fSharedLibs = "";
   G__SourceFileInfo cursor(0);
   while (cursor.IsValid()) {
      const char *filename = cursor.Name();
      if (filename==0) continue;
      Int_t len = strlen(filename);
      const char *end = filename+len;
      Bool_t needToSkip = kFALSE;
      if ( len>5 && (strcmp(end-4,".dll") == 0 ) ) {
         
         static const char *excludelist [] = {
            "stdfunc.dll","stdcxxfunc.dll","posix.dll","ipc.dll","posix.dll"
            "string.dll","vector.dll","vectorbool.dll","list.dll","deque.dll",
            "map.dll", "map2.dll","set.dll","multimap.dll","multimap2.dll",
            "multiset.dll","stack.dll","queue.dll","valarray.dll",
            "exception.dll","stdexcept.dll","complex.dll","climits.dll"};
         for (unsigned int i=0; i < sizeof(excludelist)/sizeof(excludelist[0]); ++i) {
            if (strcmp(filename,excludelist[i])==0) { needToSkip = kTRUE; break; }
         }
      }
      if ( !needToSkip &&
           ( (len>3 && strcmp(end-2,".a") == 0) ||
             (len>4 && (strcmp(end-3,".sl") == 0 ||
                        strcmp(end-3,".dl") == 0 ||
                      strcmp(end-3,".so") == 0)) ||
             (len>5 && (strcmp(end-4,".dll") == 0 ||
                        strcmp(end-4,".DLL") == 0)))) {
         if (!fSharedLibs.IsNull())
            fSharedLibs.Append(" ");
         fSharedLibs.Append(filename);
      }
      cursor.Next();
   }
   return fSharedLibs;
}
const char *TCint::GetClassSharedLibs(const char *cls)
{
   
   
   
   
   if (!cls || !*cls)
      return 0;
   
   if (fMapfile) {
      TString c = TString("Library.") + cls;
      
      
      c.ReplaceAll("::", "@@");
      
      
      c.ReplaceAll(" ", "-");
      const char *libs = fMapfile->GetValue(c, "");
      return (*libs) ? libs : 0;
   }
   return 0;
}
const char *TCint::GetSharedLibDeps(const char *lib)
{
   
   
   
   
   if (!fMapfile || !lib || !lib[0])
      return 0;
   TString libname(lib);
   Ssiz_t idx = libname.Last('.');
   if (idx != kNPOS) {
      libname.Remove(idx);
   }
   TEnvRec *rec;
   TIter next(fMapfile->GetTable());
   size_t len = libname.Length();
   while ((rec = (TEnvRec*) next())) {
      const char *libs = rec->GetValue();
      if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
          && (!libs[len] || libs[len] == '.')) {
         return libs;
      }
   }
   return 0;
}
Bool_t TCint::IsErrorMessagesEnabled() const
{
   
   
   return !G__const_whatnoerror();
}
Bool_t TCint::SetErrorMessages(Bool_t enable)
{
   
   
   if (enable)
      G__const_resetnoerror();
   else
      G__const_setnoerror();
   return !G__const_whatnoerror();
}
void TCint::AddIncludePath(const char *path)
{
   
   
   
   char *incpath = gSystem->ExpandPathName(path);
   G__add_ipath(incpath);
   delete [] incpath;
}
const char *TCint::GetIncludePath()
{
   
   
   fIncludePath = "";
   G__IncludePathInfo path;
   while (path.Next()) {
      const char *pathname = path.Name();
      fIncludePath.Append(" -I\"").Append(pathname).Append("\" ");
   }
   return fIncludePath;
}
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.