#ifdef WIN32
#include <io.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <algorithm>
#include "Riostream.h"
#include "TSystem.h"
#include "TApplication.h"
#include "TException.h"
#include "TROOT.h"
#include "TClass.h"
#include "TClassTable.h"
#include "TEnv.h"
#include "TBrowser.h"
#include "TString.h"
#include "TOrdCollection.h"
#include "TInterpreter.h"
#include "TRegexp.h"
#include "TTimer.h"
#include "TObjString.h"
#include "TError.h"
#include "TPluginManager.h"
#include "TUrl.h"
#include "TVirtualMutex.h"
#include "compiledata.h"
#include "RConfigure.h"
const char *gRootDir;
const char *gProgName;
const char *gProgPath;
TSystem *gSystem = 0;
TFileHandler *gXDisplay = 0;
static Int_t *gLibraryVersion = 0;
static Int_t gLibraryVersionIdx = 0;
static Int_t gLibraryVersionMax = 256;
ClassImp(TProcessEventTimer)
TProcessEventTimer::TProcessEventTimer(Long_t delay) : TTimer(delay, kFALSE)
{
gROOT->SetInterrupt(kFALSE);
TurnOn();
}
Bool_t TProcessEventTimer::ProcessEvents()
{
if (fTimeout) {
if (gSystem->ProcessEvents()) {
Remove();
return kTRUE;
} else {
Reset();
return kFALSE;
}
}
return kFALSE;
}
ClassImp(TSystem)
TVirtualMutex* gSystemMutex = 0;
TSystem::TSystem(const char *name, const char *title) : TNamed(name, title)
{
if (gSystem && name[0] != '-' && strcmp(name, "Generic"))
Error("TSystem", "only one instance of TSystem allowed");
fOnExitList = 0;
fSignalHandler = 0;
fFileHandler = 0;
fStdExceptionHandler = 0;
fTimers = 0;
fCompiled = 0;
fHelpers = 0;
fInsideNotify = kFALSE;
fBeepDuration = 0;
fBeepFreq = 0;
gLibraryVersion = new Int_t [gLibraryVersionMax];
memset(gLibraryVersion, 0, gLibraryVersionMax*sizeof(Int_t));
}
TSystem::~TSystem()
{
if (fOnExitList) {
fOnExitList->Delete();
SafeDelete(fOnExitList);
}
if (fSignalHandler) {
fSignalHandler->Delete();
SafeDelete(fSignalHandler);
}
if (fFileHandler) {
fFileHandler->Delete();
SafeDelete(fFileHandler);
}
if (fStdExceptionHandler) {
fStdExceptionHandler->Delete();
SafeDelete(fStdExceptionHandler);
}
if (fTimers) {
fTimers->Delete();
SafeDelete(fTimers);
}
if (fCompiled) {
fCompiled->Delete();
SafeDelete(fCompiled);
}
if (fHelpers) {
fHelpers->Delete();
SafeDelete(fHelpers);
}
if (gSystem == this)
gSystem = 0;
}
Bool_t TSystem::Init()
{
fNfd = 0;
fMaxrfd = -1;
fMaxwfd = -1;
fSigcnt = 0;
fLevel = 0;
fSignalHandler = new TOrdCollection;
fFileHandler = new TOrdCollection;
fStdExceptionHandler = new TOrdCollection;
fTimers = new TOrdCollection;
fBuildArch = BUILD_ARCH;
fBuildCompiler = COMPILER;
fBuildCompilerVersion = COMPILERVERS;
fBuildNode = BUILD_NODE;
fFlagsDebug = CXXDEBUG;
fFlagsOpt = CXXOPT;
fIncludePath = INCLUDEPATH;
fLinkedLibs = LINKEDLIBS;
fSoExt = SOEXT;
fObjExt = OBJEXT;
fAclicMode = kDefault;
fMakeSharedLib = MAKESHAREDLIB;
fMakeExe = MAKEEXE;
fCompiled = new TOrdCollection;
if (gEnv && fBeepDuration == 0 && fBeepFreq == 0) {
fBeepDuration = gEnv->GetValue("Root.System.BeepDuration", 100);
fBeepFreq = gEnv->GetValue("Root.System.BeepFreq", 440);
}
if (!fName.CompareTo("Generic")) return kTRUE;
return kFALSE;
}
void TSystem::SetProgname(const char *name)
{
gProgName = StrDup(name);
}
void TSystem::SetDisplay()
{
}
void TSystem::SetErrorStr(const char *errstr)
{
ResetErrno();
fLastErrorString = errstr;
}
const char *TSystem::GetError()
{
if (GetErrno() == 0 && fLastErrorString != "")
return fLastErrorString;
return Form("errno: %d", GetErrno());
}
Int_t TSystem::GetErrno()
{
#ifdef _REENTRANT
return errno;
#else
#ifdef R__SOLARIS_CC50
return ::errno;
#else
return errno;
#endif
#endif
}
void TSystem::ResetErrno()
{
#ifdef _REENTRANT
errno = 0;
#else
#ifdef R__SOLARIS_CC50
::errno = 0;
#else
errno = 0;
#endif
#endif
}
void TSystem::RemoveOnExit(TObject *obj)
{
if (fOnExitList == 0)
fOnExitList = new TOrdCollection;
if (fOnExitList->FindObject(obj) == 0)
fOnExitList->Add(obj);
}
const char *TSystem::HostName()
{
return "Local host";
}
void TSystem::NotifyApplicationCreated()
{
}
void TSystem::Beep(Int_t freq , Int_t duration ,
Bool_t setDefault )
{
if (setDefault) {
fBeepFreq = freq;
fBeepDuration = duration;
return;
}
if (fBeepDuration < 0 || fBeepFreq < 0) return;
if (freq < 0) freq = fBeepFreq;
if (duration < 0) duration = fBeepDuration;
DoBeep(freq, duration);
}
void TSystem::Run()
{
fInControl = kTRUE;
fDone = kFALSE;
loop_entry:
try {
RETRY {
while (!fDone) {
gApplication->StartIdleing();
InnerLoop();
gApplication->StopIdleing();
}
} ENDTRY;
}
catch (std::exception& exc) {
TIter next(fStdExceptionHandler);
TStdExceptionHandler* eh = 0;
while ((eh = (TStdExceptionHandler*) next())) {
switch (eh->Handle(exc))
{
case TStdExceptionHandler::kSEProceed:
break;
case TStdExceptionHandler::kSEHandled:
goto loop_entry;
break;
case TStdExceptionHandler::kSEAbort:
Warning("Run", "instructed to abort");
goto loop_end;
break;
}
}
throw;
}
catch (const char *str) {
printf("%s\n", str);
}
catch (...) {
Warning("Run", "handle uncaugth exception, terminating");
}
loop_end:
fInControl = kFALSE;
}
void TSystem::ExitLoop()
{
fDone = kTRUE;
}
void TSystem::InnerLoop()
{
fLevel++;
DispatchOneEvent();
fLevel--;
}
Bool_t TSystem::ProcessEvents()
{
gROOT->SetInterrupt(kFALSE);
DispatchOneEvent(kTRUE);
return gROOT->IsInterrupted();
}
void TSystem::DispatchOneEvent(Bool_t)
{
AbstractMethod("DispatchOneEvent");
}
void TSystem::Sleep(UInt_t)
{
AbstractMethod("Sleep");
}
Int_t TSystem::Select(TList *, Long_t)
{
AbstractMethod("Select");
return -1;
}
Int_t TSystem::Select(TFileHandler *, Long_t)
{
AbstractMethod("Select");
return -1;
}
TTime TSystem::Now()
{
return TTime(0);
}
void TSystem::AddTimer(TTimer *ti)
{
if (ti && fTimers && (fTimers->FindObject(ti) == 0))
fTimers->Add(ti);
}
TTimer *TSystem::RemoveTimer(TTimer *ti)
{
if (fTimers) {
TTimer *tr = (TTimer*) fTimers->Remove(ti);
return tr;
}
return 0;
}
Long_t TSystem::NextTimeOut(Bool_t mode)
{
if (!fTimers) return -1;
TOrdCollectionIter it((TOrdCollection*)fTimers);
TTimer *t, *to = 0;
Long_t tt, timeout = -1, tnow = Now();
while ((t = (TTimer *) it.Next())) {
if (t->IsSync() == mode) {
tt = (long)t->GetAbsTime() - tnow;
if (tt < 0) tt = 0;
if (timeout == -1) {
timeout = tt;
to = t;
}
if (tt < timeout) {
timeout = tt;
to = t;
}
}
}
if (to && to->IsAsync() && timeout > 0) {
if (to->IsInterruptingSyscalls())
SigAlarmInterruptsSyscalls(kTRUE);
else
SigAlarmInterruptsSyscalls(kFALSE);
}
return timeout;
}
void TSystem::AddSignalHandler(TSignalHandler *h)
{
if (h && fSignalHandler && (fSignalHandler->FindObject(h) == 0))
fSignalHandler->Add(h);
}
TSignalHandler *TSystem::RemoveSignalHandler(TSignalHandler *h)
{
if (fSignalHandler)
return (TSignalHandler *)fSignalHandler->Remove(h);
return 0;
}
void TSystem::AddFileHandler(TFileHandler *h)
{
if (h && fFileHandler && (fFileHandler->FindObject(h) == 0))
fFileHandler->Add(h);
}
TFileHandler *TSystem::RemoveFileHandler(TFileHandler *h)
{
if (fFileHandler)
return (TFileHandler *)fFileHandler->Remove(h);
return 0;
}
void TSystem::ResetSignal(ESignals , Bool_t )
{
AbstractMethod("ResetSignal");
}
void TSystem::IgnoreSignal(ESignals , Bool_t )
{
AbstractMethod("IgnoreSignal");
}
void TSystem::IgnoreInterrupt(Bool_t ignore)
{
IgnoreSignal(kSigInterrupt, ignore);
}
void TSystem::AddStdExceptionHandler(TStdExceptionHandler *eh)
{
if (eh && fStdExceptionHandler && (fStdExceptionHandler->FindObject(eh) == 0))
fStdExceptionHandler->Add(eh);
}
TStdExceptionHandler *TSystem::RemoveStdExceptionHandler(TStdExceptionHandler *eh)
{
if (fStdExceptionHandler)
return (TStdExceptionHandler *)fStdExceptionHandler->Remove(eh);
return 0;
}
Int_t TSystem::GetFPEMask()
{
AbstractMethod("GetFPEMask");
return 0;
}
Int_t TSystem::SetFPEMask(Int_t)
{
AbstractMethod("SetFPEMask");
return 0;
}
int TSystem::Exec(const char*)
{
AbstractMethod("Exec");
return -1;
}
FILE *TSystem::OpenPipe(const char*, const char*)
{
AbstractMethod("OpenPipe");
return 0;
}
int TSystem::ClosePipe(FILE*)
{
AbstractMethod("ClosePipe");
return -1;
}
TString TSystem::GetFromPipe(const char *command)
{
TString out;
FILE *pipe = OpenPipe(command, "r");
if (!pipe) {
SysError("GetFromPipe", "cannot run command \"%s\"", command);
return out;
}
TString line;
while (line.Gets(pipe)) {
if (out != "")
out += "\n";
out += line;
}
Int_t r = ClosePipe(pipe);
if (r) {
Error("GetFromPipe", "command \"%s\" returned %d", command, r);
}
return out;
}
int TSystem::GetPid()
{
AbstractMethod("GetPid");
return -1;
}
void TSystem::Exit(int, Bool_t)
{
AbstractMethod("Exit");
}
void TSystem::Abort(int)
{
AbstractMethod("Abort");
}
void TSystem::StackTrace()
{
AbstractMethod("StackTrace");
}
TSystem *TSystem::FindHelper(const char *path, void *dirptr)
{
if (!fHelpers)
fHelpers = new TOrdCollection;
TPluginHandler *h;
TSystem *helper = 0;
TUrl url(path, kTRUE);
TIter next(fHelpers);
while ((helper = (TSystem*) next()))
if (helper->ConsistentWith(path, dirptr))
return helper;
if (!path)
return 0;
TRegexp re("^root.*:");
TString pname = path;
if (pname.Index(re) != kNPOS) {
if ((h = gROOT->GetPluginManager()->FindHandler("TSystem", path))) {
if (h->LoadPlugin() == -1)
return 0;
helper = (TSystem*) h->ExecPlugin(2, path, kFALSE);
}
} else if ((h = gROOT->GetPluginManager()->FindHandler("TSystem", path))) {
if (h->LoadPlugin() == -1)
return 0;
helper = (TSystem*) h->ExecPlugin(0);
}
if (helper)
fHelpers->Add(helper);
return helper;
}
Bool_t TSystem::ConsistentWith(const char *path, void *dirptr)
{
Bool_t checkproto = kFALSE;
if (path) {
if (!GetDirPtr()) {
TUrl url(path, kTRUE);
if (!strncmp(url.GetProtocol(), GetName(), strlen(GetName())))
checkproto = kTRUE;
}
}
Bool_t checkdir = kFALSE;
if (GetDirPtr() && GetDirPtr() == dirptr)
checkdir = kTRUE;
return (checkproto || checkdir);
}
int TSystem::MakeDirectory(const char*)
{
AbstractMethod("MakeDirectory");
return 0;
}
void *TSystem::OpenDirectory(const char*)
{
AbstractMethod("OpenDirectory");
return 0;
}
void TSystem::FreeDirectory(void*)
{
AbstractMethod("FreeDirectory");
}
const char *TSystem::GetDirEntry(void*)
{
AbstractMethod("GetDirEntry");
return 0;
}
Bool_t TSystem::ChangeDirectory(const char*)
{
AbstractMethod("ChangeDirectory");
return kFALSE;
}
const char *TSystem::WorkingDirectory()
{
return 0;
}
const char *TSystem::HomeDirectory(const char*)
{
return 0;
}
int TSystem::mkdir(const char *name, Bool_t recursive)
{
if (recursive) {
TString safeName = name;
TString dirname = DirName(safeName);
if (!dirname.Length()) {
return -1;
}
if (AccessPathName(dirname, kFileExists)) {
int res = mkdir(dirname, kTRUE);
if (res) return res;
}
if (!AccessPathName(safeName, kFileExists)) {
return -1;
}
}
return MakeDirectory(name);
}
const char *TSystem::BaseName(const char *name)
{
if (name) {
if (name[0] == '/' && name[1] == '\0')
return name;
char *cp;
if ((cp = (char*)strrchr(name, '/')))
return ++cp;
return name;
}
Error("BaseName", "name = 0");
return 0;
}
Bool_t TSystem::IsAbsoluteFileName(const char *dir)
{
if (dir)
return dir[0] == '/';
return kFALSE;
}
Bool_t TSystem::IsFileInIncludePath(const char *name, char **fullpath)
{
if (!name || !strlen(name)) return kFALSE;
TString aclicMode;
TString arguments;
TString io;
TString realname = SplitAclicMode(name, aclicMode, arguments, io);
TString fileLocation = DirName(realname);
TString incPath = gSystem->GetIncludePath();
incPath.Append(":").Prepend(" ");
incPath.ReplaceAll(" -I",":");
while ( incPath.Index(" :") != -1 ) {
incPath.ReplaceAll(" :",":");
}
incPath.Prepend(fileLocation+":.:");
char *actual = Which(incPath,realname);
if (!actual) {
return kFALSE;
} else {
if (fullpath)
*fullpath = actual;
else
delete [] actual;
return kTRUE;
}
}
const char *TSystem::DirName(const char *pathname)
{
if (pathname && strchr(pathname, '/')) {
R__LOCKGUARD2(gSystemMutex);
static int len = 0;
static char *buf = 0;
int pathlen = strlen(pathname);
if (pathlen > len) {
delete [] buf;
len = pathlen;
buf = new char [len+1];
}
strcpy(buf, pathname);
char *r = buf+pathlen-1;
while ( r>buf && *(r)=='/') { --r; }
while ( r>buf && *(r)!='/') { --r; }
while ( r>buf && *(r)=='/') { --r; }
*(r+1) = '\0';
return buf;
}
return ".";
}
const char *TSystem::UnixPathName(const char *name)
{
return name;
}
char *TSystem::ConcatFileName(const char *dir, const char *name)
{
TString nameString(name);
PrependPathName(dir, nameString);
return StrDup(nameString.Data());
}
const char *TSystem::PrependPathName(const char *, TString&)
{
AbstractMethod("PrependPathName");
return 0;
}
const char *TSystem::ExpandFileName(const char *fname)
{
const int kBufSize = kMAXPATHLEN;
int n, ier, iter, lx, ncopy;
char *inp, *out, *c, *b, *e, *x, *t, buff[kBufSize*4];
const char *p;
static char xname[kBufSize];
R__LOCKGUARD2(gSystemMutex);
iter = 0; xname[0] = 0; inp = buff + kBufSize; out = inp + kBufSize;
inp[-1] = ' '; inp[0] = 0; out[-1] = ' ';
c = (char *)fname + strspn(fname, " \t\f\r");
strcat(inp, c);
again:
iter++; c = inp; ier = 0;
x = out; x[0] = 0;
for ( ; c[0]; c++) {
p = 0; e = 0;
if (c[0] == '~' && c[1] == '/') {
p = HomeDirectory(); e = c + 1; if (!p) ier++;
}
if (p) {
strcpy(x, p); x += strlen(p); c = e-1; continue;
}
p = 0;
if (c[0] == '~' && c[1] != '/') {
n = strcspn(c+1, "/ "); buff[0] = 0; strncat(buff, c+1, n);
p = HomeDirectory(buff); e = c+1+n;
}
if (p) {
strcpy(x,p); x += strlen(p); c = e-1; continue;
}
p = 0;
if (c[0] == '.' && c[1] == '/' && c[-1] == ' ') {
p = strcpy(buff, WorkingDirectory()); e = c + 1; if (!p) ier++;
}
if (p) {
strcpy(x,p); x += strlen(p); c = e-1; continue;
}
if (c[0] != '$') {
x++[0] = c[0];
} else {
b = c+1;
if (c[1] == '(') b++;
if (c[1] == '{') b++;
if (b[0] == '$')
e = b+1;
else
for (e = b; isalnum(e[0]) || e[0] == '_'; e++) ;
buff[0] = 0; strncat(buff, b, e-b);
p = Getenv(buff);
if (!p) {
for (t = buff; (t[0] = toupper(t[0])); t++) ;
p = Getenv(buff);
}
if (!p) {
for (t = buff; (t[0] = tolower(t[0])); t++) ;
p = Getenv(buff);
}
if (!p && !strcmp(buff, "cwd")) {
p = strcpy(buff, WorkingDirectory());
}
if (!p && !strcmp(buff, "$")) {
sprintf(buff, "%d", GetPid());
p = buff;
}
if (!p) {
#ifdef WIN32
if (c[1] && c[1]!='\\' && c[1]!=';' && c[1]!='/')
ier++;
#else
ier++;
#endif
x++[0] = c[0];
} else {
int lp = strlen(p);
if (lp >= kBufSize) {
strncpy(x, p, kBufSize);
x += kBufSize;
break;
} else
strcpy(x,p); x += lp; c = (b==c+1) ? e-1 : e;
}
}
}
x[0] = 0; lx = x - out;
if (ier && iter < 3) { strcpy(inp, out); goto again; }
ncopy = (lx >= kBufSize) ? kBufSize-1 : lx;
xname[0] = 0; strncat(xname, out, ncopy);
if (ier || ncopy != lx)
::Error("TSystem::ExpandFileName", "input: %s, output: %s", fname, xname);
return xname;
}
Bool_t TSystem::ExpandPathName(TString&)
{
return kFALSE;
}
char *TSystem::ExpandPathName(const char *)
{
return 0;
}
Bool_t TSystem::AccessPathName(const char *, EAccessMode)
{
return kFALSE;
}
Bool_t TSystem::IsPathLocal(const char *path)
{
Bool_t localPath = kTRUE;
TUrl url(path);
if (strlen(url.GetHost()) > 0) {
localPath = kFALSE;
TInetAddress a(gSystem->GetHostByName(url.GetHost()));
TInetAddress b(gSystem->GetHostByName(gSystem->HostName()));
if (!strcmp(a.GetHostName(), b.GetHostName()) ||
!strcmp(a.GetHostAddress(), b.GetHostAddress())) {
localPath = kTRUE;
if (strlen(url.GetUser()) > 0) {
UserGroup_t *u = gSystem->GetUserInfo();
if (u) {
if (strcmp(u->fUser, url.GetUser()))
localPath = kFALSE;
delete u;
}
}
}
}
return localPath;
}
int TSystem::CopyFile(const char *, const char *, Bool_t)
{
AbstractMethod("CopyFile");
return -1;
}
int TSystem::Rename(const char *, const char *)
{
AbstractMethod("Rename");
return -1;
}
int TSystem::Link(const char *, const char *)
{
AbstractMethod("Link");
return -1;
}
int TSystem::Symlink(const char *, const char *)
{
AbstractMethod("Symlink");
return -1;
}
int TSystem::Unlink(const char *)
{
AbstractMethod("Unlink");
return -1;
}
int TSystem::GetPathInfo(const char *path, Long_t *id, Long_t *size,
Long_t *flags, Long_t *modtime)
{
Long64_t lsize;
int res = GetPathInfo(path, id, &lsize, flags, modtime);
if (res == 0 && size) {
if (sizeof(Long_t) == 4 && lsize > kMaxInt) {
Error("GetPathInfo", "file %s > 2 GB, use GetPathInfo() with Long64_t size", path);
*size = kMaxInt;
} else {
*size = (Long_t)lsize;
}
}
return res;
}
int TSystem::GetPathInfo(const char *path, Long_t *id, Long64_t *size,
Long_t *flags, Long_t *modtime)
{
FileStat_t buf;
int res = GetPathInfo(path, buf);
if (res == 0) {
if (id)
*id = (buf.fDev << 24) + buf.fIno;
if (size)
*size = buf.fSize;
if (modtime)
*modtime = buf.fMtime;
if (flags) {
*flags = 0;
if (buf.fMode & (kS_IXUSR|kS_IXGRP|kS_IXOTH))
*flags |= 1;
if (R_ISDIR(buf.fMode))
*flags |= 2;
if (!R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode))
*flags |= 4;
}
}
return res;
}
int TSystem::GetPathInfo(const char *, FileStat_t &)
{
AbstractMethod("GetPathInfo(const char*, FileStat_t&)");
return 1;
}
int TSystem::GetFsInfo(const char *, Long_t *, Long_t *, Long_t *, Long_t *)
{
AbstractMethod("GetFsInfo");
return 1;
}
const char *TSystem::TempDirectory() const
{
AbstractMethod("TempDirectory");
return 0;
}
FILE *TSystem::TempFileName(TString &, const char *)
{
AbstractMethod("TempFileName");
return 0;
}
int TSystem::Chmod(const char *, UInt_t)
{
AbstractMethod("Chmod");
return -1;
}
int TSystem::Umask(Int_t)
{
AbstractMethod("Umask");
return -1;
}
int TSystem::Utime(const char *, Long_t, Long_t)
{
AbstractMethod("Utime");
return -1;
}
const char *TSystem::FindFile(const char *, TString&, EAccessMode)
{
AbstractMethod("FindFile");
return 0;
}
char *TSystem::Which(const char *search, const char *wfil, EAccessMode mode)
{
TString wfilString(wfil);
FindFile(search, wfilString, mode);
if (wfilString.IsNull()) return 0;
return StrDup(wfilString.Data());
}
Int_t TSystem::GetUid(const char * )
{
AbstractMethod("GetUid");
return 0;
}
Int_t TSystem::GetEffectiveUid()
{
AbstractMethod("GetEffectiveUid");
return 0;
}
Int_t TSystem::GetGid(const char * )
{
AbstractMethod("GetGid");
return 0;
}
Int_t TSystem::GetEffectiveGid()
{
AbstractMethod("GetEffectiveGid");
return 0;
}
UserGroup_t *TSystem::GetUserInfo(Int_t )
{
AbstractMethod("GetUserInfo");
return 0;
}
UserGroup_t *TSystem::GetUserInfo(const char * )
{
AbstractMethod("GetUserInfo");
return 0;
}
UserGroup_t *TSystem::GetGroupInfo(Int_t )
{
AbstractMethod("GetGroupInfo");
return 0;
}
UserGroup_t *TSystem::GetGroupInfo(const char * )
{
AbstractMethod("GetGroupInfo");
return 0;
}
void TSystem::Setenv(const char*, const char*)
{
AbstractMethod("Setenv");
}
void TSystem::Unsetenv(const char *name)
{
Setenv(name, "");
}
const char *TSystem::Getenv(const char*)
{
AbstractMethod("Getenv");
return 0;
}
void TSystem::Openlog(const char *, Int_t, ELogFacility)
{
AbstractMethod("Openlog");
}
void TSystem::Syslog(ELogLevel, const char *)
{
AbstractMethod("Syslog");
}
void TSystem::Closelog()
{
AbstractMethod("Closelog");
}
Int_t TSystem::RedirectOutput(const char *, const char *, RedirectHandle_t *)
{
AbstractMethod("RedirectOutput");
return -1;
}
void TSystem::ShowOutput(RedirectHandle_t *h)
{
if (!h) {
Error("ShowOutput", "handle not specified");
return;
}
if (gSystem->AccessPathName(h->fFile, kReadPermission)) {
Error("ShowOutput", "file '%s' cannot be read", h->fFile.Data());
return;
}
FILE *f = 0;
if (!(f = fopen(h->fFile.Data(), "r"))) {
Error("ShowOutput", "file '%s' cannot be open", h->fFile.Data());
return;
}
off_t ltot = lseek(fileno(f), (off_t) 0, SEEK_END);
Int_t begin = (h->fReadOffSet > 0 && h->fReadOffSet < ltot) ? h->fReadOffSet : 0;
lseek(fileno(f), (off_t) begin, SEEK_SET);
Int_t left = ltot - begin;
const Int_t kMAXBUF = 16384;
char buf[kMAXBUF];
Int_t wanted = (left > kMAXBUF-1) ? kMAXBUF-1 : left;
Int_t len;
do {
while ((len = read(fileno(f), buf, wanted)) < 0 &&
TSystem::GetErrno() == EINTR)
TSystem::ResetErrno();
if (len < 0) {
SysError("ShowOutput", "error reading log file");
break;
}
buf[len] = 0;
fprintf(stderr,"%s", buf);
left -= len;
wanted = (left > kMAXBUF) ? kMAXBUF : left;
} while (len > 0 && left > 0);
h->fReadOffSet = ltot;
}
const char* TSystem::GetDynamicPath()
{
AbstractMethod("GetDynamicPath");
return 0;
}
void TSystem::SetDynamicPath(const char *)
{
AbstractMethod("SetDynamicPath");
}
int TSystem::Load(const char *module, const char *entry, Bool_t system)
{
#ifdef NOCINT
AbstractMethod("Load");
return 0;
#else
static int recCall = 0;
TString libs = GetLibraries();
TString moduleBasename = BaseName(module);
TString l(moduleBasename);
Ssiz_t idx = l.Last('.');
if (idx != kNPOS) {
l.Remove(idx+1);
}
idx = libs.Index(l);
if (idx != kNPOS) {
if (idx == 0 || libs[idx-1] == '/' || libs[idx-1] == '\\') {
Ssiz_t len = libs.Length();
idx += l.Length();
if (!l.EndsWith("."))
idx++;
while (idx < len && libs[idx] != '.') {
if (libs[idx] == ' ' || idx+1 == len) {
return 1;
}
++idx;
}
}
}
if (l[l.Length()-1] == '.') {
l.Remove(l.Length()-1);
}
if (l.BeginsWith("lib")) {
l.Replace(0, 3, "-l");
idx = libs.Index(l);
if (idx != kNPOS &&
(idx == 0 || libs[idx-1] == ' ') &&
(libs[idx+l.Length()] == ' ' || libs[idx+l.Length()] == 0)) {
return 1;
}
}
recCall++;
char *path = DynamicPathName(module);
int ret;
TString deplibs = gInterpreter->GetSharedLibDeps(moduleBasename);
if (deplibs.IsNull()) {
TString libmapfilename;
if (path) {
libmapfilename = path;
idx = libmapfilename.Last('.');
if (idx != kNPOS) {
libmapfilename.Remove(idx);
}
libmapfilename += ".rootmap";
}
if (gSystem->GetPathInfo(libmapfilename, 0, (Long_t*)0, 0, 0) == 0) {
if (gDebug > 0) Info("Load", "loading %s", libmapfilename.Data());
gInterpreter->LoadLibraryMap(libmapfilename);
deplibs = gInterpreter->GetSharedLibDeps(moduleBasename);
}
}
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 (gDebug > 0)
Info("Load", "loading dependent library %s for library %s",
deplib, ((TObjString*)tokens->At(0))->GetName());
if ((ret = Load(deplib, "", system)) < 0) {
delete tokens;
recCall--;
return ret;
}
}
delete tokens;
}
ret = -1;
if (path) {
const char *dirname = DirName(path);
#ifdef ROOTLIBDIR
TString rootlibdir = ROOTLIBDIR;
#else
const char *libdirname = ConcatFileName(gRootDir,"lib");
TString rootlibdir = libdirname;
delete [] libdirname;
#endif
if (rootlibdir == dirname) {
system = kTRUE;
}
gLibraryVersionIdx++;
if (gLibraryVersionIdx == gLibraryVersionMax) {
gLibraryVersionMax *= 2;
TStorage::ReAllocInt(gLibraryVersion, gLibraryVersionMax, gLibraryVersionIdx);
}
ret = gInterpreter->Load(path, system);
if (ret < 0) ret = -1;
if (gDebug > 0)
Info("Load", "loaded library %s, status %d", path, ret);
if (ret == 0 && gLibraryVersion[gLibraryVersionIdx]) {
int v = TROOT::ConvertVersionCode2Int(gLibraryVersion[gLibraryVersionIdx]);
Error("Load", "version mismatch, %s = %d, ROOT = %d",
path, v, gROOT->GetVersionInt());
ret = -2;
gLibraryVersion[gLibraryVersionIdx] = 0;
}
gLibraryVersionIdx--;
delete [] path;
}
recCall--;
if (recCall == 0 && gApplication)
gApplication->InitializeGraphics();
if (!entry || !entry[0] || ret < 0) return ret;
Func_t f = DynFindSymbol(module, entry);
if (f) return 0;
return -1;
#endif
}
char *TSystem::DynamicPathName(const char *, Bool_t)
{
AbstractMethod("DynamicPathName");
return 0;
}
Func_t TSystem::DynFindSymbol(const char * , const char *entry)
{
#ifdef NOCINT
AbstractMethod("DynFindSymbol");
return 0;
#else
return (Func_t) gInterpreter->FindSym(entry);
#endif
}
void TSystem::Unload(const char *module)
{
#ifdef NOCINT
AbstractMethod("UnLoad");
#else
char *path;
if ((path = DynamicPathName(module))) {
gInterpreter->UnloadFile(path);
delete [] path;
}
#endif
}
void TSystem::ListSymbols(const char *, const char *)
{
AbstractMethod("ListSymbols");
}
void TSystem::ListLibraries(const char *regexp)
{
TString libs = GetLibraries(regexp);
TRegexp separator("[^ \\t\\s]+");
TString s;
Ssiz_t start = 0, index = 0, end = 0;
int i = 0;
Printf("");
Printf("Loaded shared libraries");
Printf("=======================");
while ((start < libs.Length()) && (index != kNPOS)) {
index = libs.Index(separator, &end, start);
if (index >= 0) {
s = libs(index, end);
if (s.BeginsWith("-")) {
if (s.BeginsWith("-l")) {
Printf("%s", s.Data());
i++;
}
} else {
Printf("%s", s.Data());
i++;
}
}
start += end+1;
}
Printf("-----------------------");
Printf("%d libraries loaded", i);
Printf("=======================");
}
const char *TSystem::GetLinkedLibraries()
{
return 0;
}
const char *TSystem::GetLibraries(const char *regexp, const char *options,
Bool_t isRegexp)
{
fListLibs = "";
TString libs = "";
TString opt = options;
Bool_t so2dylib = (opt.First('L') != kNPOS);
if (so2dylib)
opt.ReplaceAll("L", "");
if (opt.IsNull() || opt.First('D') != kNPOS)
libs += gInterpreter->GetSharedLibs();
if (opt.IsNull() || opt.First('S') != kNPOS) {
if (!libs.IsNull()) libs.Append(" ");
const char *linked;
if ((linked = GetLinkedLibraries())) {
if (fLinkedLibs != LINKEDLIBS) {
TString custom = fLinkedLibs;
custom.ReplaceAll(LINKEDLIBS,linked);
if (custom == fLinkedLibs) {
libs.Append(linked);
libs.Append(" ");
}
libs.Append(custom);
} else {
libs.Append(linked);
}
} else
libs.Append(fLinkedLibs);
}
if (regexp && *regexp) {
TRegexp separator("[^ \\t\\s]+");
TRegexp user_re(regexp, kTRUE);
TString s;
Ssiz_t start, index, end;
start = index = end = 0;
while ((start < libs.Length()) && (index != kNPOS)) {
index = libs.Index(separator,&end,start);
if (index >= 0) {
s = libs(index,end);
if ((isRegexp && s.Index(user_re) != kNPOS) ||
(!isRegexp && s.Index(regexp) != kNPOS)) {
if (!fListLibs.IsNull())
fListLibs.Append(" ");
fListLibs.Append(s);
}
}
start += end+1;
}
} else
fListLibs = libs;
#if defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5)
if (so2dylib) {
TString libs2 = fListLibs;
TString maclibs;
TRegexp separator("[^ \\t\\s]+");
TRegexp user_so("\\.so$");
Ssiz_t start, index, end;
start = index = end = 0;
while ((start < libs2.Length()) && (index != kNPOS)) {
index = libs2.Index(separator, &end, start);
if (index >= 0) {
TString s = libs2(index, end);
if (s.Index(user_so) != kNPOS) {
s.ReplaceAll(".so",".dylib");
if ( GetPathInfo( s, 0, (Long_t*)0, 0, 0 ) != 0 ) {
s.Replace( 0, s.Last('/')+1, 0, 0);
s.Replace( 0, s.Last('\\')+1, 0, 0);
}
}
if (!maclibs.IsNull()) maclibs.Append(" ");
maclibs.Append(s);
}
start += end+1;
}
fListLibs = maclibs;
}
#endif
return fListLibs;
}
TInetAddress TSystem::GetHostByName(const char *)
{
AbstractMethod("GetHostByName");
return TInetAddress();
}
TInetAddress TSystem::GetPeerName(int)
{
AbstractMethod("GetPeerName");
return TInetAddress();
}
TInetAddress TSystem::GetSockName(int)
{
AbstractMethod("GetSockName");
return TInetAddress();
}
int TSystem::GetServiceByName(const char *)
{
AbstractMethod("GetServiceByName");
return -1;
}
char *TSystem::GetServiceByPort(int)
{
AbstractMethod("GetServiceByPort");
return 0;
}
int TSystem::OpenConnection(const char*, int, int)
{
AbstractMethod("OpenConnection");
return -1;
}
int TSystem::AnnounceTcpService(int, Bool_t, int, int)
{
AbstractMethod("AnnounceTcpService");
return -1;
}
int TSystem::AnnounceUnixService(int, int)
{
AbstractMethod("AnnounceUnixService");
return -1;
}
int TSystem::AnnounceUnixService(const char *, int)
{
AbstractMethod("AnnounceUnixService");
return -1;
}
int TSystem::AcceptConnection(int)
{
AbstractMethod("AcceptConnection");
return -1;
}
void TSystem::CloseConnection(int, Bool_t)
{
AbstractMethod("CloseConnection");
}
int TSystem::RecvRaw(int, void *, int, int)
{
AbstractMethod("RecvRaw");
return -1;
}
int TSystem::SendRaw(int, const void *, int, int)
{
AbstractMethod("SendRaw");
return -1;
}
int TSystem::RecvBuf(int, void *, int)
{
AbstractMethod("RecvBuf");
return -1;
}
int TSystem::SendBuf(int, const void *, int)
{
AbstractMethod("SendBuf");
return -1;
}
int TSystem::SetSockOpt(int, int, int)
{
AbstractMethod("SetSockOpt");
return -1;
}
int TSystem::GetSockOpt(int, int, int*)
{
AbstractMethod("GetSockOpt");
return -1;
}
int TSystem::GetSysInfo(SysInfo_t *) const
{
AbstractMethod("GetSysInfo");
return -1;
}
int TSystem::GetCpuInfo(CpuInfo_t *, Int_t) const
{
AbstractMethod("GetCpuInfo");
return -1;
}
int TSystem::GetMemInfo(MemInfo_t *) const
{
AbstractMethod("GetMemInfo");
return -1;
}
int TSystem::GetProcInfo(ProcInfo_t *) const
{
AbstractMethod("GetProcInfo");
return -1;
}
void AssignAndDelete(TString& target, char *tobedeleted) {
target = tobedeleted;
delete [] tobedeleted;
}
#ifdef WIN32
static TString R__Exec(const char *cmd)
{
FILE * f = gSystem->OpenPipe(cmd,"r");
if (!f) {
return "";
}
TString result;
char x;
while ((x = fgetc(f))!=EOF ) {
if (x=='\n' || x=='\r') break;
result += x;
}
fclose(f);
return result;
}
static void R__FixLink(TString &cmd)
{
TString res = R__Exec("link 2>&1");
if (res.Length()) {
if (res.Contains("Microsoft (R) Incremental Linker"))
return;
}
res = R__Exec("cygpath . 2>&1");
if (res.Length()) {
if (res != ".")
return;
}
res = R__Exec("which cl.exe 2>&1|grep cl|sed 's,cl\\.exe$,link\\.exe,' 2>&1");
if (res.Length()) {
res = R__Exec(Form("cygpath -w '%s' 2>&1",res.Data()));
if (res.Length()) {
cmd.ReplaceAll(" link ",Form(" \"%s\" ",res.Data()));
}
}
}
#endif
int TSystem::CompileMacro(const char *filename, Option_t *opt,
const char *library_specified,
const char *build_dir,
UInt_t dirmode)
{
Bool_t keep = kFALSE;
Bool_t recompile = kFALSE;
EAclicMode mode = fAclicMode;
Bool_t loadLib = kTRUE;
if (opt) {
keep = (strchr(opt,'k')!=0);
recompile = (strchr(opt,'f')!=0);
if (strchr(opt,'O')!=0) {
mode = kOpt;
}
if (strchr(opt,'g')!=0) {
mode = kDebug;
}
if (strchr(opt,'c')!=0) {
loadLib = kFALSE;
}
}
if (mode==kDefault) {
TString rootbuild = ROOTBUILD;
if (rootbuild.Index("debug",0,TString::kIgnoreCase)==kNPOS) {
mode=kOpt;
} else {
mode=kDebug;
}
}
TString build_loc = ExpandFileName(GetBuildDir());
if (build_dir && strlen(build_dir)) build_loc = build_dir;
if (build_loc.Length() && (!IsAbsoluteFileName(build_loc)) ) {
AssignAndDelete( build_loc , ConcatFileName( WorkingDirectory(), build_loc ) );
}
TString library = filename;
ExpandPathName( library );
if (! IsAbsoluteFileName(library) ) {
AssignAndDelete( library , ConcatFileName( WorkingDirectory(), library ) );
}
{
Ssiz_t pos = 0;
while ((pos = library.Index("//", 2, pos, TString::kExact)) != kNPOS) {
library.Remove(pos, 1);
}
}
TString filename_fullpath = library;
TString file_dirname = DirName( filename_fullpath );
if (library.Length()>1 && isalpha(library[0]) && library[1]==':') {
file_dirname.Prepend(library(0,2));
}
TString file_location( file_dirname );
Ssiz_t dot_pos = library.Last('.');
TString extension = library;
extension.Replace( 0, dot_pos+1, 0 , 0);
TString libname_noext = library;
if (dot_pos>=0) libname_noext.Remove( dot_pos );
library.Replace( dot_pos, library.Length()-dot_pos,
TString("_") + extension + "." + fSoExt );
TString libname ( BaseName( libname_noext ) );
libname.Append("_").Append(extension);
TString libname_ext ( libname );
libname_ext += "." + fSoExt;
if (library_specified && strlen(library_specified) ) {
libname = BaseName( library_specified );
library = library_specified;
ExpandPathName( library );
if (! IsAbsoluteFileName(library) ) {
AssignAndDelete( library , ConcatFileName( WorkingDirectory(), library ) );
}
library = TString(library) + "." + fSoExt;
}
TString lib_dirname = DirName( library );
if (library.Length()>1 && isalpha(library[0]) && library[1]==':') {
lib_dirname.Prepend(library(0,2));
}
TString lib_location( lib_dirname );
Bool_t mkdirFailed = kFALSE;
if (build_loc.Length()==0) {
build_loc = lib_location;
} else {
TRegexp disk_finder ("[A-z]:");
Int_t pos = library.Index( disk_finder );
if (pos==0) library.Remove(pos,3);
pos = lib_location.Index( disk_finder );
if (pos==0) lib_location.Remove(pos,3);
AssignAndDelete( library, ConcatFileName( build_loc, library) );
Bool_t canWriteBuild_loc = !gSystem->AccessPathName(build_loc,kWritePermission);
TString build_loc_store( build_loc );
AssignAndDelete( build_loc, ConcatFileName( build_loc, lib_location) );
if (gSystem->AccessPathName(build_loc,kFileExists)) {
mkdirFailed = (0 != mkdir(build_loc, true));
if (mkdirFailed && !canWriteBuild_loc) {
build_loc = build_loc_store;
mkdirFailed = kFALSE;
} else if (!mkdirFailed && dirmode!=0) {
Chmod(build_loc,dirmode);
}
}
}
if ( gInterpreter->IsLoaded(filename) ) {
::Info("ACLiC","script has already been loaded in interpreted mode");
::Info("ACLiC","unloading %s and compiling it", filename);
if ( gInterpreter->UnloadFile( (char*) filename ) != 0 ) {
return kFALSE;
}
}
TString includes = GetIncludePath();
{
TRegexp rel_inc("-I[^\"/\\$%-][^:-]+");
Int_t len,pos;
pos = rel_inc.Index(includes,&len);
while( len != 0 ) {
TString sub = includes(pos,len);
sub.Remove(0,2);
AssignAndDelete( sub, ConcatFileName( WorkingDirectory(), sub ) );
sub.Prepend(" -I");
includes.Replace(pos,len,sub);
pos = rel_inc.Index(includes,&len);
}
}
{
TRegexp rel_inc("-I\"[^/\\$%-][^:-]+");
Int_t len,pos;
pos = rel_inc.Index(includes,&len);
while( len != 0 ) {
TString sub = includes(pos,len);
sub.Remove(0,3);
AssignAndDelete( sub, ConcatFileName( WorkingDirectory(), sub ) );
sub.Prepend(" -I\"");
includes.Replace(pos,len,sub);
pos = rel_inc.Index(includes,&len);
}
}
includes += " -I\"" + build_loc;
includes += "\" -I\"";
includes += WorkingDirectory();
includes += "\"";
if (gEnv) {
TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
includes.Append(" ").Append(fromConfig).Append(" ");
}
TString incPath = GetIncludePath();
incPath.Append(":").Prepend(" ");
if (gEnv) {
TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
incPath.Append(fromConfig);
}
incPath.ReplaceAll(" -I",":");
while ( incPath.Index(" :") != -1 ) {
incPath.ReplaceAll(" :",":");
}
incPath.Prepend(file_location+":.:");
TString defines = " ";
{
TString cmd = GetMakeSharedLib();
TRegexp rel_def("-D[^\\s\\t\\n\\r]*");
Int_t len,pos;
pos = rel_def.Index(cmd,&len);
while( len != 0 ) {
defines += cmd(pos,len);
defines += " ";
pos = rel_def.Index(cmd,&len,pos+1);
}
}
TString emergency_loc;
UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid());
if (ug) {
AssignAndDelete( emergency_loc, ConcatFileName( TempDirectory(), ug->fUser ) );
} else {
emergency_loc = TempDirectory();
}
Bool_t canWrite = !gSystem->AccessPathName(build_loc,kWritePermission);
Bool_t modified = kFALSE;
if ( !recompile ) {
TString depdir = build_loc;
TString depfilename;
AssignAndDelete( depfilename, ConcatFileName(depdir, BaseName(libname_noext)) );
depfilename += "_" + extension + ".d";
TString bakdepfilename = depfilename + ".bak";
Long_t lib_time, file_time;
#ifndef WIN32
const char * stderrfile = "/dev/null";
#else
TString stderrfile;
AssignAndDelete( stderrfile, ConcatFileName(build_loc,"stderr.tmp") );
#endif
if ((gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time ) != 0) ||
(gSystem->GetPathInfo( filename, 0, (Long_t*)0, 0, &file_time ) == 0 &&
(lib_time < file_time))) {
recompile = kTRUE;
modified = kTRUE;
} else {
Bool_t needDependencies;
if ( gSystem->GetPathInfo( depfilename, 0,(Long_t*) 0, 0, &file_time ) == 0 ) {
needDependencies = ( file_time < lib_time );
} else {
needDependencies = true;
}
if (needDependencies) {
if (!canWrite) {
depdir = emergency_loc;
AssignAndDelete( depfilename, ConcatFileName(depdir, BaseName(libname_noext)) );
depfilename += "_" + extension + ".d";
bakdepfilename = depfilename + ".bak";
}
gSystem->Unlink(depfilename);
#ifdef WIN32
TString touch = "echo # > "; touch += "\"" + depfilename + "\"";
#else
TString touch = "echo > "; touch += "\"" + depfilename + "\"";
#endif
TString builddep = "rmkdepend \"-f";
builddep += depfilename;
builddep += "\" -Y -- ";
#ifndef ROOTINCDIR
TString rootsys = gSystem->Getenv("ROOTSYS");
#else
TString rootsys = ROOTINCDIR;
#endif
builddep += " \"-I"+rootsys+"/include\" ";
builddep += includes;
builddep += defines;
builddep += " -- \"";
builddep += filename;
builddep += "\" > ";
builddep += stderrfile;
builddep += " 2>&1 ";
TString adddictdep = "echo ";
adddictdep += filename;
adddictdep += ": ";
{
char *cintdictversion = Which(incPath,"cintdictversion.h");
if (cintdictversion) {
adddictdep += cintdictversion;
delete [] cintdictversion;
} else {
adddictdep += rootsys+"/include/cintdictversion.h ";
}
}
adddictdep += " >> \""+depfilename+"\"";
if (gDebug > 4) {
::Info("ACLiC",touch.Data());
::Info("ACLiC",builddep.Data());
::Info("ACLiC",adddictdep.Data());
}
Int_t depbuilt = !gSystem->Exec(touch);
if (depbuilt) depbuilt = !gSystem->Exec(builddep);
if (depbuilt) depbuilt = !gSystem->Exec(adddictdep);
if (!depbuilt) {
::Warning("ACLiC","Failed to generate the dependency file for %s",
library.Data());
} else {
#ifdef WIN32
gSystem->Unlink(stderrfile);
#endif
gSystem->Unlink(bakdepfilename);
}
}
FILE * depfile = fopen(depfilename.Data(),"r");
if (depfile==0) {
modified = kTRUE;
recompile = kTRUE;
} else {
Int_t sz = 256;
char *line = new char[sz];
line[0] = 0;
char c;
Int_t current = 0;
Int_t nested = 0;
while ((c = fgetc(depfile)) != EOF) {
if (c=='#') {
while ((c = fgetc(depfile)) != EOF) {
if (c=='\n') {
break;
}
}
continue;
}
if (isspace(c) && !nested) {
if (current) {
if (line[current-1]!=':') {
line[current] = 0;
Long_t filetime;
if ( gSystem->GetPathInfo( line, 0, (Long_t*)0, 0, &filetime ) == 0 ) {
modified |= ( lib_time <= filetime );
}
}
}
current = 0;
line[0] = 0;
} else {
if (current==sz-1) {
sz = 2*sz;
char *newline = new char[sz];
strcpy(newline,line);
delete [] line;
line = newline;
}
if (c=='"') nested = !nested;
else {
line[current] = c;
current++;
}
}
}
delete [] line;
fclose(depfile);
recompile = modified;
}
}
}
if ( gInterpreter->IsLoaded(library)
|| strlen(GetLibraries(library,"D",kFALSE)) != 0 ) {
Bool_t reload = kFALSE;
TNamed *libinfo = (TNamed*)fCompiled->FindObject(library);
if (libinfo) {
Long_t load_time = libinfo->GetUniqueID();
Long_t lib_time;
if ( gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time ) == 0
&& (lib_time>load_time)) {
reload = kTRUE;
}
}
if ( !recompile && reload ) {
::Info("ACLiC","%s has been modified and will be reloaded",
libname.Data());
if ( gInterpreter->UnloadFile( (char*) library.Data() ) != 0 ) {
return kFALSE;
}
TNamed *k = new TNamed(library,library);
Long_t lib_time;
gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
k->SetUniqueID(lib_time);
if (!keep) k->SetBit(kMustCleanup);
fCompiled->Add(k);
return !gSystem->Load(library);
}
::Info("ACLiC","%s script has already been compiled and loaded",
modified ? "modified" : "unmodified");
if ( !recompile ) {
return kTRUE;
} else {
#ifdef R__KCC
::Error("ACLiC","shared library can not be updated (when using the KCC compiler)!");
return kFALSE;
#else
::Info("ACLiC","it will be regenerated and reloaded!");
if ( gInterpreter->UnloadFile( (char*) library.Data() ) != 0 ) {
return kFALSE;
}
Unlink(library);
#endif
}
}
TString libmapfilename;
AssignAndDelete( libmapfilename, ConcatFileName( build_loc, libname ) );
libmapfilename += ".rootmap";
#if (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5)) || defined(R__WIN32)
Bool_t produceRootmap = kTRUE;
#else
Bool_t produceRootmap = kFALSE;
#endif
Bool_t linkDepLibraries = !produceRootmap;
if (gEnv) {
#if (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5))
Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",2);
#elif defined(R__WIN32)
Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",3);
#else
Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",1);
#endif
produceRootmap = linkLibs & 0x2;
linkDepLibraries = linkLibs & 0x1;
}
if (!recompile) {
if (loadLib) {
TNamed *k = new TNamed(library,library);
Long_t lib_time;
gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
k->SetUniqueID(lib_time);
if (!keep) k->SetBit(kMustCleanup);
fCompiled->Add(k);
if (gInterpreter->GetSharedLibDeps(libname) == 0) {
gInterpreter->LoadLibraryMap(libmapfilename);
}
return !gSystem->Load(library);
}
else return kTRUE;
}
if (!canWrite && recompile) {
if (mkdirFailed) {
::Warning("ACLiC","Could not create the directory: %s",
build_loc.Data());
} else {
::Warning("ACLiC","%s is not writeable!",
build_loc.Data());
}
if (emergency_loc == build_dir ) {
::Error("ACLiC","%s is the last resort location (i.e. temp location)",build_loc.Data());
return kFALSE;
}
::Warning("ACLiC","Output will be written to %s",
emergency_loc.Data());
return CompileMacro(filename, opt, library_specified, emergency_loc, dirmode);
}
Info("ACLiC","creating shared library %s",library.Data());
TString dict = libname + "_ACLiC_dict";
static const int maxforbidden = 27;
static const char *forbidden_chars[maxforbidden] =
{ "+","-","*","/","&","%","|","^",">","<",
"=","~",".","(",")","[","]","!",",","$",
" ",":","'","#","@","\\","\"" };
for( int ic = 0; ic < maxforbidden; ic++ ) {
dict.ReplaceAll( forbidden_chars[ic],"_" );
}
if ( dict.Last('.')!=dict.Length()-1 ) dict.Append(".");
AssignAndDelete( dict, ConcatFileName( build_loc, dict ) );
TString dicth = dict;
TString dictObj = dict;
dict += "cxx";
dicth += "h";
dictObj += fObjExt;
TString linkdef;
AssignAndDelete( linkdef, ConcatFileName( build_loc, libname ) );
linkdef += "_ACLiC_linkdef.h";
ofstream linkdefFile( linkdef, ios::out );
linkdefFile << "// File Automatically generated by the ROOT Script Compiler "
<< endl;
linkdefFile << endl;
linkdefFile << "#ifdef __CINT__" << endl;
linkdefFile << endl;
linkdefFile << "#pragma link C++ nestedclasses;" << endl;
linkdefFile << "#pragma link C++ nestedtypedefs;" << endl;
linkdefFile << endl;
const char * extensions[] = { ".h", ".hh", ".hpp", ".hxx", ".hPP", ".hXX" };
int i;
for (i = 0; i < 6; i++ ) {
char * name;
TString extra_linkdef = BaseName( libname_noext );
extra_linkdef.Append(GetLinkdefSuffix());
extra_linkdef.Append(extensions[i]);
name = Which(incPath,extra_linkdef);
if (name) {
if (gDebug>4) Info("ACLiC","including extra linkdef file: %s",name);
linkdefFile << "#include \"" << name << "\"" << endl;
delete [] name;
}
}
if (gDebug>5) Info("ACLiC","looking for header in: %s",incPath.Data());
for (i = 0; i < 6; i++ ) {
char * name;
TString lookup = BaseName( libname_noext );
lookup.Append(extensions[i]);
name = Which(incPath,lookup);
if (name) {
linkdefFile << "#pragma link C++ defined_in "<<name<<";"<< endl;
delete [] name;
}
}
linkdefFile << "#pragma link C++ defined_in \""<<filename_fullpath << "\";" << endl;
linkdefFile << endl;
linkdefFile << "#endif" << endl;
linkdefFile.close();
TString mapfile;
AssignAndDelete( mapfile, ConcatFileName( build_loc, libname ) );
mapfile += "_ACLiC_map";
TString mapfilein = mapfile + ".in";
TString mapfileout = mapfile + ".out";
Bool_t needLoadMap = kFALSE;
if (gInterpreter->GetSharedLibDeps(libname) !=0 ) {
gInterpreter->UnloadLibraryMap(libname);
needLoadMap = kTRUE;
}
ofstream mapfileStream( mapfilein, ios::out );
{
TString name = ".rootmap";
TString sname = "system.rootmap";
TString file;
#ifdef ROOTETCDIR
AssignAndDelete(file, ConcatFileName(ROOTETCDIR, sname) );
#else
TString etc = gRootDir;
#ifdef WIN32
etc += "\\etc";
#else
etc += "/etc";
#endif
AssignAndDelete(file, ConcatFileName(etc, sname));
if (gSystem->AccessPathName(file)) {
AssignAndDelete(file, ConcatFileName(gRootDir, sname));
if (gSystem->AccessPathName(file)) {
AssignAndDelete(file, ConcatFileName(gRootDir, name));
}
}
#endif
mapfileStream << file << endl;
AssignAndDelete(file, ConcatFileName(gSystem->HomeDirectory(), name) );
mapfileStream << file << endl;
mapfileStream << name << endl;
for (i = 0; i < gInterpreter->GetRootMapFiles()->GetEntriesFast(); i++) {
mapfileStream << ((TObjString*)gInterpreter->GetRootMapFiles()->At(i))->GetString() << endl;
}
}
mapfileStream.close();
TString rcint;
#ifndef ROOTBINDIR
rcint = gSystem->Getenv("ROOTSYS");
#ifndef R__WIN32
rcint += "/bin/";
#else
rcint += "\\bin\\";
#endif
#else
rcint = ROOTBINDIR;
#ifndef R__WIN32
rcint += "/";
#else
rcint += "\\";
#endif
#endif
#ifdef G__NOSTUBS
rcint += "rootcint_nostubs.sh --lib-list-prefix=";
#else
rcint += "rootcint \"--lib-list-prefix=";
#endif
rcint += mapfile;
rcint += "\" -f \"";
rcint.Append(dict).Append("\" -c -p ").Append(GetIncludePath()).Append(" ");
if (produceRootmap) {
rcint.Append("-DR__ACLIC_ROOTMAP ");
}
if (gEnv) {
TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
rcint.Append(fromConfig).Append(" \"");
}
rcint.Append(filename_fullpath).Append("\" \"").Append(linkdef).Append("\"");;
if (gDebug>3) {
::Info("ACLiC","creating the dictionary files");
if (gDebug>4) ::Info("ACLiC",rcint.Data());
}
Int_t dictResult = gSystem->Exec(rcint);
if (dictResult) {
if (dictResult==139) ::Error("ACLiC","Dictionary generation failed with a core dump!");
else ::Error("ACLiC","Dictionary generation failed!");
}
Bool_t result = !dictResult;
TString depLibraries;
if (result) {
TString linkedlibs = GetLibraries("", "S");
TString libtoload;
TString all_libtoload;
ifstream liblist(mapfileout);
ofstream libmapfile;
if (produceRootmap) {
libmapfile.open(libmapfilename);
libmapfile << "Library." << libname << ": " << libname;
}
while ( liblist >> libtoload ) {
if (libtoload != library && libtoload != libname && libtoload != libname_ext) {
if (produceRootmap) {
if (loadLib || linkDepLibraries ) gROOT->LoadClass("", libtoload);
if (!linkedlibs.Contains(libtoload)) {
libmapfile << " " << libtoload;
all_libtoload.Append(" ").Append(libtoload);
depLibraries.Append(" ");
depLibraries.Append(GetLibraries(libtoload,"DSL",kFALSE));
}
} else {
gROOT->LoadClass("", libtoload);
}
}
unsigned char c = liblist.peek();
if (c=='\n' || c=='\r') {
liblist.get();
break;
}
}
if (produceRootmap) {
std::string clname;
while ( std::getline(liblist,clname) ) {
std::replace(clname.begin(), clname.end(), ':', '@');
std::replace(clname.begin(), clname.end(), ' ', '_');
libmapfile << endl;
libmapfile << "Library." << clname << ": " << libname << " " << all_libtoload;
}
libmapfile << endl;
libmapfile.close();
}
}
TString linkLibraries;
linkLibraries.Prepend(GetLibraries("","SDL"));
TString cmd = fMakeSharedLib;
cmd.ReplaceAll("$SourceFiles","\"$SourceFiles\"");
cmd.ReplaceAll("$SourceFiles",dict);
cmd.ReplaceAll("$ObjectFiles","\"$ObjectFiles\"");
cmd.ReplaceAll("$ObjectFiles",dictObj);
cmd.ReplaceAll("$IncludePath",includes);
cmd.ReplaceAll("$SharedLib","\"$SharedLib\"");
cmd.ReplaceAll("$SharedLib",library);
if (linkDepLibraries) {
if (produceRootmap) {
cmd.ReplaceAll("$DepLibs",depLibraries);
} else {
cmd.ReplaceAll("$DepLibs",linkLibraries);
}
}
cmd.ReplaceAll("$LinkedLibs",linkLibraries);
cmd.ReplaceAll("$LibName",libname);
cmd.ReplaceAll("$BuildDir","\"$BuildDir\"");
cmd.ReplaceAll("$BuildDir",build_loc);
if (mode==kDebug) {
cmd.ReplaceAll("$Opt",fFlagsDebug);
} else {
cmd.ReplaceAll("$Opt",fFlagsOpt);
}
#ifdef WIN32
R__FixLink(cmd);
#endif
TString testcmd = fMakeExe;
TString fakeMain;
AssignAndDelete( fakeMain, ConcatFileName( build_loc, libname ) );
fakeMain += "_ACLiC_main";
fakeMain += extension;
ofstream fakeMainFile( fakeMain, ios::out );
fakeMainFile << "// File Automatically generated by the ROOT Script Compiler "
<< endl;
fakeMainFile << "int main(char*argc,char**argvv) {};" << endl;
fakeMainFile.close();
TString exec;
AssignAndDelete( exec, ConcatFileName( build_loc, libname ) );
exec += "_ACLiC_exec";
testcmd.ReplaceAll("$SourceFiles",dict);
testcmd.ReplaceAll("$ObjectFiles",dictObj);
testcmd.ReplaceAll("$IncludePath",includes);
testcmd.ReplaceAll("$ExeName",exec);
testcmd.ReplaceAll("$LinkedLibs",linkLibraries);
testcmd.ReplaceAll("$BuildDir",build_loc);
if (mode==kDebug)
testcmd.ReplaceAll("$Opt",fFlagsDebug);
else
testcmd.ReplaceAll("$Opt",fFlagsOpt);
#ifdef WIN32
R__FixLink(testcmd);
#endif
if (result) {
if (gDebug>3) {
::Info("ACLiC","compiling the dictionary and script files");
if (gDebug>4) ::Info("ACLiC",cmd.Data());
}
Int_t compilationResult = gSystem->Exec( cmd );
if (compilationResult) {
if (compilationResult==139) ::Error("ACLiC","Compilation failed with a core dump!");
else ::Error("ACLiC","Compilation failed!");
if (produceRootmap) {
gSystem->Unlink(libmapfilename);
}
}
result = !compilationResult;
} else {
::Info("ACLiC","Invoking compiler to check macro's validity");
TString line(fMakeSharedLib);
TString comp;
Ssiz_t posEOL=kNPOS;
while ((kNPOS!=(posEOL=line.Index(";"))
|| kNPOS!=(posEOL=line.Index("&&")))
&& kNPOS!=line.Index("$ObjectFiles")) {
Ssiz_t posSource=line.Index("$SourceFiles");
Ssiz_t posInclude=line.Index("$IncludePath");
if (posSource!=kNPOS && posSource<posEOL
&& posInclude!=kNPOS && posInclude<posEOL)
comp=line(0, posEOL);
line.Remove(0, posEOL+(line(posEOL)==';'?1:2));
}
if (!comp.Length())
::Info("ACLiC","Cannot extract compiler call from MakeSharedLibs().");
else {
Bool_t compileHeader=kFALSE;
size_t lenFilename=strlen(filename);
const char* endOfFilename=filename+lenFilename;
for (Int_t iExt=0; !compileHeader && iExt<6; iExt++) {
size_t lenExt=strlen(extensions[iExt]);
compileHeader |=lenFilename>lenExt
&& !strcmp(extensions[iExt], endOfFilename-lenExt);
}
TString filenameForCompiler(filename);
if (compileHeader) {
filenameForCompiler= libname + "_ACLiC";
filenameForCompiler+=".check.cxx";
gSystem->Link(filename, filenameForCompiler);
}
comp.ReplaceAll("$SourceFiles",filenameForCompiler);
comp.ReplaceAll("$ObjectFiles",dictObj);
comp.ReplaceAll("$IncludePath",includes);
comp.ReplaceAll("$SharedLib",library);
comp.ReplaceAll("$LinkedLibs",linkLibraries);
comp.ReplaceAll("$LibName",libname);
comp.ReplaceAll("$BuildDir",build_loc);
if (mode==kDebug) comp.ReplaceAll("$Opt",fFlagsDebug);
else comp.ReplaceAll("$Opt",fFlagsOpt);
if (gDebug>4) ::Info("ACLiC",comp.Data());
Int_t compilationResult = gSystem->Exec( comp );
if (filenameForCompiler.CompareTo(filename))
gSystem->Unlink(filenameForCompiler);
if (!compilationResult) {
::Info("ACLiC","The compiler has not found any problem with your macro.\n"
"\tProbably your macro uses something rootcint can't parse.\n"
"\tCheck http://root.cern.ch/root/Cint.phtml?limitations for Cint's limitations.");
TString objfile=filename;
Ssiz_t len=objfile.Length();
objfile.Replace(len-extension.Length(), len, GetObjExt());
gSystem->Unlink(objfile);
}
}
}
if ( result ) {
TNamed *k = new TNamed(library,library);
Long_t lib_time;
gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
k->SetUniqueID(lib_time);
if (!keep) k->SetBit(kMustCleanup);
fCompiled->Add(k);
#ifndef NOCINT
gInterpreter->SetRTLD_NOW();
#endif
if (needLoadMap) {
gInterpreter->LoadLibraryMap(libmapfilename);
}
if (gDebug>3) ::Info("ACLiC","loading the shared library");
if (loadLib) result = !gSystem->Load(library);
else result = kTRUE;
#ifndef NOCINT
gInterpreter->SetRTLD_LAZY();
#endif
if ( !result ) {
if (gDebug>3) {
::Info("ACLiC","testing for missing symbols:");
if (gDebug>4) ::Info("ACLiC",testcmd.Data());
}
gSystem->Exec(testcmd);
gSystem->Unlink( exec );
}
};
if (gDebug<=5) {
gSystem->Unlink( dict );
gSystem->Unlink( dicth );
gSystem->Unlink( dictObj );
gSystem->Unlink( linkdef );
gSystem->Unlink( mapfilein );
gSystem->Unlink( mapfileout );
gSystem->Unlink( fakeMain );
gSystem->Unlink( exec );
}
if (gDebug>6) {
rcint.Prepend("echo ");
cmd.Prepend("echo \" ").Append(" \" ");
testcmd.Prepend("echo \" ").Append(" \" ");
gSystem->Exec(rcint);
gSystem->Exec( cmd );
gSystem->Exec(testcmd);
}
return result;
}
const char *TSystem::GetBuildArch() const
{
return fBuildArch;
}
const char *TSystem::GetBuildCompiler() const
{
return fBuildCompiler;
}
const char *TSystem::GetBuildCompilerVersion() const
{
return fBuildCompilerVersion;
}
const char *TSystem::GetBuildNode() const
{
return fBuildNode;
}
const char *TSystem::GetBuildDir() const
{
if (fBuildDir.Length()==0) {
if (!gEnv) return "";
const_cast<TSystem*>(this)->fBuildDir = gEnv->GetValue("ACLiC.BuildDir","");
}
return fBuildDir;
}
const char *TSystem::GetFlagsDebug() const
{
return fFlagsDebug;
}
const char *TSystem::GetFlagsOpt() const
{
return fFlagsOpt;
}
TSystem::EAclicMode TSystem::GetAclicMode() const
{
return fAclicMode;
}
const char *TSystem::GetMakeSharedLib() const
{
return fMakeSharedLib;
}
const char *TSystem::GetMakeExe() const
{
return fMakeExe;
}
const char *TSystem::GetIncludePath()
{
fListPaths = fIncludePath;
fListPaths.Append(" ").Append(gInterpreter->GetIncludePath());
return fListPaths;
}
const char *TSystem::GetLinkedLibs() const
{
return fLinkedLibs;
}
const char *TSystem::GetLinkdefSuffix() const
{
if (fLinkdefSuffix.Length()==0) {
if (!gEnv) return "_linkdef";
const_cast<TSystem*>(this)->fLinkdefSuffix = gEnv->GetValue("ACLiC.Linkdef","_linkdef");
}
return fLinkdefSuffix;
}
const char *TSystem::GetSoExt() const
{
return fSoExt;
}
const char *TSystem::GetObjExt() const
{
return fObjExt;
}
void TSystem::SetBuildDir(const char* build_dir)
{
fBuildDir = build_dir;
}
void TSystem::SetFlagsDebug(const char *flags)
{
fFlagsDebug = flags;
}
void TSystem::SetFlagsOpt(const char *flags)
{
fFlagsOpt = flags;
}
void TSystem::SetAclicMode(EAclicMode mode)
{
fAclicMode = mode;
}
void TSystem::SetMakeExe(const char *directives)
{
fMakeExe = directives;
}
void TSystem::SetMakeSharedLib(const char *directives)
{
fMakeSharedLib = directives;
}
void TSystem::AddIncludePath(const char *includePath)
{
if (includePath) {
fIncludePath += " ";
fIncludePath += includePath;
}
}
void TSystem::AddLinkedLibs(const char *linkedLib)
{
if (linkedLib) {
fLinkedLibs += " ";
fLinkedLibs += linkedLib;
}
}
void TSystem::SetIncludePath(const char *includePath)
{
fIncludePath = includePath;
}
void TSystem::SetLinkedLibs(const char *linkedLibs)
{
fLinkedLibs = linkedLibs;
}
void TSystem::SetLinkdefSuffix(const char *suffix)
{
fLinkdefSuffix = suffix;
}
void TSystem::SetSoExt(const char *SoExt)
{
fSoExt = SoExt;
}
void TSystem::SetObjExt(const char *ObjExt)
{
fObjExt = ObjExt;
}
TString TSystem::SplitAclicMode(const char* filename, TString &aclicMode,
TString &arguments, TString &io) const
{
char *fname = Strip(filename);
char *arg = strchr(fname, '(');
while (arg && *arg && (arg > fname && *(arg-1) == '$') && *(arg+1))
arg = strchr(arg+1, '(');
if (arg && arg > fname) {
*arg = 0;
char *t = arg-1;
while (*t == ' ') {
*t = 0; t--;
}
arg++;
}
{
char *s2 = 0;
char *s3;
s2 = strstr(fname, ">>");
if (!s2) s2 = strstr(fname, "2>");
if (!s2) s2 = strchr(fname, '>');
s3 = strchr(fname, '<');
if (s2 && s3) s2 = s2<s3 ? s2 : s3;
if (s3 && !s2) s2 = s3;
if (s2==fname) {
io = fname;
aclicMode = "";
arguments = "";
delete []fname;
return "";
} else if (s2) {
s2--;
while (s2 && *s2 == ' ') s2--;
s2++;
io = s2;
*s2 = 0;
} else
io = "";
}
char postfix[4];
postfix[0] = 0;
int len = strlen(fname);
const char *mode = 0;
if (len > 1) {
if (strcmp(fname+len-1, "g") == 0)
mode = "g";
else if (strcmp(fname+len-1, "O") == 0)
mode = "O";
if (mode)
len--;
}
Bool_t compile = len && fname[len - 1] == '+';
Bool_t remove = compile && len > 1 && fname[len - 2] == '+';
if (compile) {
if (mode) {
fname[len] = 0;
}
if (remove) {
fname[strlen(fname)-2] = 0;
strcpy(postfix, "++");
} else {
fname[strlen(fname)-1] = 0;
strcpy(postfix, "+");
}
if (mode)
strcat(postfix, mode);
}
TString resFilename = fname;
aclicMode = postfix;
arguments = "(";
if (arg) arguments += arg;
else arguments = "";
delete []fname;
return resFilename;
}
void TSystem::CleanCompiledMacros()
{
TIter next(fCompiled);
TNamed *lib;
while ((lib = (TNamed*)next())) {
if (lib->TestBit(kMustCleanup)) Unlink(lib->GetTitle());
}
}
TVersionCheck::TVersionCheck(int versionCode)
{
if (versionCode != TROOT::RootVersionCode() && gLibraryVersion)
gLibraryVersion[gLibraryVersionIdx] = versionCode;
}