From d3e9f54c0057f498ecc6a641237720fa93be2981 Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Tue, 4 Jul 2006 17:36:38 +0000
Subject: [PATCH] From Axel: Implementing ConcatFileName and Which to not
 return a new char[] to be deleted by the user, but operate on an existing
 TString. because of backward compatibility issues I had to introduce new
 function names.

   Which(...const char*,...) -> FindFile(...TString&,...)
   ConcatFileName(...const char*,...) -> PrependPath(...TString&,...)

The existing Which and ConcatFilename are now wrappers for the new
TString versions. The wrapping is done in TSystem, so all derived
classes need to implement FindFile and PrependPath now.
I've also fixed a few obvious problems and incompatibilities between the
windows and the unix versions; the VMS version is IMHO still broken. One
of the problems fixed: ConcatFileName(0,"name") returned "name" on unix,
but "\\name" on windows. It now returns "name" for all.


git-svn-id: http://root.cern.ch/svn/root/trunk@15688 27541ba8-7e3a-0410-8455-c3a389f83636
---
 alien/inc/TAlienSystem.h   |   4 +-
 alien/src/TAlienSystem.cxx |   6 +-
 base/inc/TSystem.h         |   4 +-
 base/src/TSystem.cxx       |  33 +++++++++--
 unix/inc/TUnixSystem.h     |   6 +-
 unix/src/TUnixSystem.cxx   | 118 +++++++++++++++++--------------------
 vms/inc/TVmsSystem.h       |   6 +-
 vms/src/TVmsSystem.cxx     |  86 +++++++++++++--------------
 winnt/inc/TWinNTSystem.h   |   6 +-
 winnt/src/TWinNTSystem.cxx | 103 ++++++++++++++------------------
 10 files changed, 188 insertions(+), 184 deletions(-)

diff --git a/alien/inc/TAlienSystem.h b/alien/inc/TAlienSystem.h
index d3c56e66149..c664de1e5b9 100644
--- a/alien/inc/TAlienSystem.h
+++ b/alien/inc/TAlienSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TSystem.h,v 1.55 2006/03/29 09:21:01 rdm Exp $
+// @(#)root/base:$Name:  $:$Id: TAlienSystem.h,v 1.1 2006/05/26 16:55:04 rdm Exp $
 // Author: Andreas Peters  15/05/2006
 
 /*************************************************************************
@@ -71,7 +71,7 @@ public:
    virtual int             Chmod(const char *file, UInt_t mode);
    virtual int             Umask(Int_t mask);
    virtual int             Utime(const char *file, Long_t modtime, Long_t actime);
-   virtual char           *Which(const char *search, const char *file, EAccessMode mode = kFileExists);
+   virtual const char     *FindFile(const char *search, TString& file, EAccessMode mode = kFileExists);
 
    //---- Users & Groups
    virtual Int_t           GetUid(const char *user = 0);
diff --git a/alien/src/TAlienSystem.cxx b/alien/src/TAlienSystem.cxx
index 2aa42abc6f1..db2462edf53 100644
--- a/alien/src/TAlienSystem.cxx
+++ b/alien/src/TAlienSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TAlienSystem.cxx,v 1.2 2006/05/30 15:34:17 rdm Exp $
+// @(#)root/base:$Name:  $:$Id: TAlienSystem.cxx,v 1.3 2006/06/01 14:46:49 rdm Exp $
 // Author: Andreas Peters   15/05/2006
 
 /*************************************************************************
@@ -376,9 +376,9 @@ int TAlienSystem::Utime(const char *, Long_t, Long_t)
 }
 
 //______________________________________________________________________________
-char *TAlienSystem::Which(const char *, const char *, EAccessMode)
+const char *TAlienSystem::FindFile(const char *, TString&, EAccessMode)
 {
-   // Find location of file in a search path. User must delete returned string.
+   // Find location of file in a search path.
    // Returns 0 in case file is not found.
 
    AbstractMethod("Which");
diff --git a/base/inc/TSystem.h b/base/inc/TSystem.h
index 57181bec3fc..cb644aea71d 100644
--- a/base/inc/TSystem.h
+++ b/base/inc/TSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name: v5-11-02 $:$Id: TSystem.h,v 1.55 2006/03/29 09:21:01 rdm Exp $
+// @(#)root/base:$Name:  $:$Id: TSystem.h,v 1.56 2006/05/23 04:47:35 brun Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -326,6 +326,7 @@ public:
    virtual char           *ConcatFileName(const char *dir, const char *name);
    virtual Bool_t          IsAbsoluteFileName(const char *dir);
    virtual Bool_t          IsFileInIncludePath(const char *name, char **fullpath = 0);
+   virtual const char     *PrependPathName(const char *dir, TString& name);
    virtual Bool_t          ExpandPathName(TString &path);
    virtual char           *ExpandPathName(const char *path);
    virtual Bool_t          AccessPathName(const char *path, EAccessMode mode = kFileExists);
@@ -342,6 +343,7 @@ public:
    virtual int             Umask(Int_t mask);
    virtual int             Utime(const char *file, Long_t modtime, Long_t actime);
    virtual const char     *UnixPathName(const char *unixpathname);
+   virtual const char     *FindFile(const char *search, TString& file, EAccessMode mode = kFileExists);
    virtual char           *Which(const char *search, const char *file, EAccessMode mode = kFileExists);
 
    //---- Users & Groups
diff --git a/base/src/TSystem.cxx b/base/src/TSystem.cxx
index d0bc056acaf..3eec1979650 100644
--- a/base/src/TSystem.cxx
+++ b/base/src/TSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TSystem.cxx,v 1.140 2006/05/23 04:47:35 brun Exp $
+// @(#)root/base:$Name:  $:$Id: TSystem.cxx,v 1.141 2006/05/26 09:01:58 brun Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -952,7 +952,17 @@ const char *TSystem::UnixPathName(const char *name)
 }
 
 //______________________________________________________________________________
-char *TSystem::ConcatFileName(const char *, const char *)
+char *TSystem::ConcatFileName(const char *dir, const char *name)
+{
+   // Concatenate a directory and a file name. User must delete returned string.
+
+   TString nameString(name);
+   PrependPathName(dir, nameString);
+   return StrDup(nameString.Data());
+}
+
+//______________________________________________________________________________
+const char *TSystem::PrependPathName(const char *, TString&)
 {
    // Concatenate a directory and a file name.
 
@@ -1299,15 +1309,28 @@ int TSystem::Utime(const char *, Long_t, Long_t)
 }
 
 //______________________________________________________________________________
-char *TSystem::Which(const char *, const char *, EAccessMode)
+const char *TSystem::FindFile(const char *, TString&, EAccessMode)
 {
-   // Find location of file in a search path. User must delete returned string.
+   // Find location of file in a search path. Return value points to TString for
+   // compatibility with Which(const char *, const char *, EAccessMode). 
    // Returns 0 in case file is not found.
 
-   AbstractMethod("Which");
+   AbstractMethod("FindFile");
    return 0;
 }
 
+//______________________________________________________________________________
+char *TSystem::Which(const char *search, const char *wfil, EAccessMode mode)
+{
+   // Find location of file in a search path. User must delete returned string.
+   // Returns 0 in case file is not found.
+
+   TString wfilString(wfil);
+   FindFile(search, wfilString, mode);
+   if (wfilString.IsNull()) return 0;
+   return StrDup(wfilString.Data());
+}
+
 //---- Users & Groups ----------------------------------------------------------
 
 //______________________________________________________________________________
diff --git a/unix/inc/TUnixSystem.h b/unix/inc/TUnixSystem.h
index 69cc037892d..8058898fc44 100644
--- a/unix/inc/TUnixSystem.h
+++ b/unix/inc/TUnixSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/unix:$Name:  $:$Id: TUnixSystem.h,v 1.24 2005/09/13 10:20:30 rdm Exp $
+// @(#)root/unix:$Name:  $:$Id: TUnixSystem.h,v 1.25 2005/09/24 11:57:36 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -139,7 +139,7 @@ public:
    FILE             *TempFileName(TString &base, const char *dir = 0);
 
    //---- Paths & Files ----------------------------------------
-   char             *ConcatFileName(const char *dir, const char *name);
+   const char       *PrependPathName(const char *dir, TString& name);
    Bool_t            ExpandPathName(TString &patbuf);
    char             *ExpandPathName(const char *path);
    Bool_t            AccessPathName(const char *path, EAccessMode mode = kFileExists);
@@ -154,7 +154,7 @@ public:
    int               Chmod(const char *file, UInt_t mode);
    int               Umask(Int_t mask);
    int               Utime(const char *file, Long_t modtime, Long_t actime);
-   char             *Which(const char *search, const char *file, EAccessMode mode = kFileExists);
+   const char       *FindFile(const char *search, TString& file, EAccessMode mode = kFileExists);
 
    //---- Users & Groups ---------------------------------------
    Int_t             GetUid(const char *user = 0);
diff --git a/unix/src/TUnixSystem.cxx b/unix/src/TUnixSystem.cxx
index 7f70e9c3879..29d1307ddb2 100644
--- a/unix/src/TUnixSystem.cxx
+++ b/unix/src/TUnixSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/unix:$Name:  $:$Id: TUnixSystem.cxx,v 1.152 2006/05/19 07:03:36 brun Exp $
+// @(#)root/unix:$Name:  $:$Id: TUnixSystem.cxx,v 1.153 2006/05/26 17:11:28 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -1189,29 +1189,25 @@ FILE *TUnixSystem::TempFileName(TString &base, const char *dir)
 }
 
 //______________________________________________________________________________
-char *TUnixSystem::ConcatFileName(const char *dir, const char *name)
+const char *TUnixSystem::PrependPathName(const char *dir, TString& name)
 {
-   // Concatenate a directory and a file name. Returned string must be
-   // deleted by user.
+   // Concatenate a directory and a file name.
 
-   if (name == 0 || strlen(name) <= 0 || strcmp(name, ".") == 0)
-      return StrDup(dir);
-
-   TString buf;
-   if (dir && (strcmp(dir, "/") != 0)) {
-      buf = dir;
-      if (dir[strlen(dir)-1] == '/')
-         buf += name;
-      else {
-         buf += "/";
-         buf += name;
-      };
-   } else {
-      buf = "/";
-      buf +=name; // sprintf(buf, "/%s", name);
+   if (name.IsNull() || name == ".") {
+      if (dir) {
+         name = dir;
+         if (dir[strlen(dir) - 1] != '/')
+            name += '/';
+      } else name = "";
+      return name.Data();
    }
 
-   return StrDup(buf.Data());
+   if (!dir || !dir[0]) dir = "/";
+   else if (dir[strlen(dir) - 1] != '/')
+      name.Prepend('/');
+   name.Prepend(dir);
+
+   return name.Data();
 }
 
 //---- Paths & Files -----------------------------------------------------------
@@ -1524,72 +1520,68 @@ int TUnixSystem::Utime(const char *file, Long_t modtime, Long_t actime)
 }
 
 //______________________________________________________________________________
-char *TUnixSystem::Which(const char *search, const char *wfil, EAccessMode mode)
+const char *TUnixSystem::FindFile(const char *search, TString& wfil, EAccessMode mode)
 {
    // Find location of file "wfil" in a search path.
    // The search path is specified as a : separated list of directories.
-   // User must delete returned string. Returns 0 in case file is not found.
+   // Return value is pointing to wfile for compatibility with 
+   // Which(const char*,const char*,EAccessMode) version
 
-   char name[kMAXPATHLEN], file[kMAXPATHLEN];
-   const char *ptr;
-   char *next, *exname;
-   struct stat finfo;
+   if (gEnv->GetValue("Root.ShowPath", 0))
+      printf("Which: %s = ", wfil.Data());
 
-   exname = gSystem->ExpandPathName(wfil);
-   if (exname)
-      strcpy(file, exname);
-   else
-      file[0] = 0;
-   delete [] exname;
+   gSystem->ExpandPathName(wfil);
 
-   if (file[0] == '/') {
-      exname = StrDup(file);
-      if (exname && access(exname, mode) == 0 &&
-          stat(exname, &finfo) == 0 && S_ISREG(finfo.st_mode)) {
+   if (wfil[0] == '/') {
+      struct stat finfo;
+      if (access(wfil.Data(), mode) == 0 &&
+          stat(wfil.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
          if (gEnv->GetValue("Root.ShowPath", 0))
-            Printf("Which: %s = %s", wfil, exname);
-         return exname;
+            printf("%s", wfil.Data());
+         return wfil.Data();
       }
-      delete [] exname;
       if (gEnv->GetValue("Root.ShowPath", 0))
-         Printf("Which: %s = <not found>", wfil);
+         printf("<not found>");
+      wfil = "";
       return 0;
    }
 
    if (search == 0)
       search = ".";
 
-   for (ptr = search; *ptr;) {
-      for (next = name; *ptr && *ptr != ':'; )
-         *next++ = *ptr++;
-      *next = '\0';
-
-      if (name[0] != '/' && name[0] != '$' && name[0] != '~') {
-         char tmp[kMAXPATHLEN];
-         strcpy(tmp, name);
-         strcpy(name, gSystem->WorkingDirectory());
-         strcat(name, "/");
-         strcat(name, tmp);
+   TString pwd(gSystem->WorkingDirectory());
+   pwd += "/";
+   for (const char* ptr = search; *ptr;) {
+      TString name;
+      if (*ptr != '/' && *ptr !='$' && *ptr != '~')
+         name = pwd;
+      const char* posEndOfPart = strchr(ptr, ':');
+      if (posEndOfPart) {
+         name.Append(ptr, posEndOfPart - ptr);
+         ptr = posEndOfPart + 1; // skip ':'
+      } else { 
+         name.Append(ptr);
+         ptr += strlen(ptr);
       }
 
-      if (*(name + strlen(name) - 1) != '/')
-         strcat(name, "/");
-      strcat(name, file);
+      if (!name.EndsWith("/"))
+         name += '/';
+      name += wfil;
 
-      exname = gSystem->ExpandPathName(name);
-      if (exname && access(exname, mode) == 0 &&
-          stat(exname, &finfo) == 0 && S_ISREG(finfo.st_mode)) {
+      gSystem->ExpandPathName(name);
+      struct stat finfo;
+      if (access(name.Data(), mode) == 0 &&
+          stat(name.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
          if (gEnv->GetValue("Root.ShowPath", 0))
-            Printf("Which: %s = %s", wfil, exname);
-         return exname;
+            printf("%s", name.Data());
+         wfil = name;
+         return wfil.Data();
       }
-      delete [] exname;
-      if (*ptr)
-         ptr++;
    }
 
    if (gEnv->GetValue("Root.ShowPath", 0))
-      Printf("Which: %s = <not found>", wfil);
+      printf("<not found>");
+   wfil = "";
    return 0;
 }
 
diff --git a/vms/inc/TVmsSystem.h b/vms/inc/TVmsSystem.h
index a6caba4f622..db4a1a2ae9c 100644
--- a/vms/inc/TVmsSystem.h
+++ b/vms/inc/TVmsSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/vms:$Name:  $:$Id: TVmsSystem.h,v 1.4 2001/01/23 19:01:55 rdm Exp $
+// @(#)root/vms:$Name:  $:$Id: TVmsSystem.h,v 1.5 2001/02/03 14:46:42 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -126,7 +126,7 @@ public:
    const char       *HomeDirectory();
 
    //---- Paths & Files ----------------------------------------
-   char             *ConcatFileName(const char *dir, const char *name);
+   const char       *PrependPathName(const char *dir, TString& name);
    Bool_t            ExpandPathName(TString &patbuf);
    char             *ExpandPathName(const char *path);
    Bool_t            AccessPathName(const char *path, EAccessMode mode = kFileExists);
@@ -137,7 +137,7 @@ public:
    int               GetPathInfo(const char *path, unsigned short *id,Long_t *size,
                                  Long_t *flags, Long_t *modtime);
    int               Umask(Int_t mask);
-   char             *Which(const char *search, const char *file, EAccessMode mode = kFileExists);
+   const char       *FindFile(const char *search, TString& file, EAccessMode mode = kFileExists);
 
    //---- System Logging ---------------------------------------
    void              Openlog(const char *name, Int_t options, ELogFacility facility);
diff --git a/vms/src/TVmsSystem.cxx b/vms/src/TVmsSystem.cxx
index 0b22eecfb52..3e2d0f0a246 100644
--- a/vms/src/TVmsSystem.cxx
+++ b/vms/src/TVmsSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/vms:$Name:  $:$Id: TVmsSystem.cxx,v 1.10 2001/11/26 15:37:46 rdm Exp $
+// @(#)root/vms:$Name:  $:$Id: TVmsSystem.cxx,v 1.11 2002/11/18 23:02:19 rdm Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -534,24 +534,20 @@ const char *TVmsSystem::HomeDirectory()
 }
 
 //______________________________________________________________________________
-char *TVmsSystem::ConcatFileName(const char *dir, const char *name)
+const char *TVmsSystem::PrependPathName(const char *dir, TString& name)
 {
-   // Concatenate a directory and a file name. Returned string must be
-   // deleted by user.
+   // Concatenate a directory and a file name.
 
-   if (name == 0 || strlen(name) <= 0 || strcmp(name, ".") == 0)
-      return StrDup(dir);
+   if (name.IsNull() || name == ".") {
+      if (dir) name = dir;
+      else name = "";
+      return name.Data();
 
-   char buf[kMAXPATHLEN];
-   if (dir && (strcmp(dir, "/") != 0)) {
-      if (dir[strlen(dir)-1] == '/')
-         sprintf(buf, "%s%s", dir, name);
-      else
-         sprintf(buf, "%s/%s", dir, name);
-   } else
-      sprintf(buf, "/%s", name);
+   if (dir && dir[0] && dir[strlen(dir) - 1] != '/')
+      name.Prepend("/");
+   name.Prepend(dir);
 
-   return StrDup(buf);
+   return name.Data();
 }
 
 //---- Paths & Files -----------------------------------------------------------
@@ -750,7 +746,7 @@ int TVmsSystem::Umask(Int_t mask)
 }
 
 //______________________________________________________________________________
-char *TVmsSystem::Which(const char *search, const char *file, EAccessMode mode)
+const char *TVmsSystem::FindFile(const char *search, TString& file, EAccessMode mode)
 {
    // Find location of file in a search path.
    // User must delete returned string.
@@ -759,35 +755,39 @@ char *TVmsSystem::Which(const char *search, const char *file, EAccessMode mode)
    const char *ptr;
    char *next, *exname, *ffile;
    char s2[]=":";
+   Ssiz_t posCol = 0;
+
+   if (gEnv->GetValue("Root.ShowPath",0))
+      printf("Which: %s = ", file.Data());
+
+   if (search != 0){
+      if (strchr(file(),']')) {
+         if (gEnv->GetValue("Root.ShowPath",0))
+            printf("%s\n", file.Data());
+         return file.Data();
+      } else if ((posCol = file.First(':')) != kNPOS) {
+         file.Remove(0, posCol + 1);
+         if (gEnv->GetValue("Root.ShowPath",0))
+            printf("%s\n", file.Data());
+         return file.Data();
+      } else {
+         if (file.IsNull()) {
+            file = search;
+            if (gEnv->GetValue("Root.ShowPath",0))
+               printf("%s\n", file.Data());
+            return file.Data();
+         }
+         file.Prepend(search);
+         if (access(file(),mode) == 0) {
+            if (gEnv->GetValue("Root.ShowPath",0))
+               printf("%s\n", file.Data());
+            return file.Data();
+          }
+      }
+   }
 
-ffile = StrDup(file);
-
-if (search != 0){
-  if (strchr(file,']')){
-    exname = StrDup(file);
-    return exname;
-    }
-  else if(strrchr(file,':')){
-    exname = StrDup(strtok(ffile,s2));
-    return exname;
-    }
-  else {
-   if (file == 0){
-     exname = StrDup(search);
-     return exname;
-     }
-     strcpy(temp,search);
-     strcat(temp,file);
-     exname = StrDup(temp);
-     if (exname && access(exname,mode) == 0) {
-       if (gEnv->GetValue("Root.ShowPath",0))
-          Printf("Which: %s = %s", file,exname);
-       return exname;
-       }
-   delete [] exname;
+   file = "";
    return 0;
-   }
-}
 
 #if 0
    if (strchr(file, '/')) {
diff --git a/winnt/inc/TWinNTSystem.h b/winnt/inc/TWinNTSystem.h
index e88d7302d46..3cbfb2afb8e 100644
--- a/winnt/inc/TWinNTSystem.h
+++ b/winnt/inc/TWinNTSystem.h
@@ -1,4 +1,4 @@
-// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.h,v 1.39 2006/03/28 16:35:00 brun Exp $
+// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.h,v 1.40 2006/05/15 16:30:10 brun Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -165,7 +165,6 @@ public:
    const char       *WorkingDirectory(char driveletter);
    const char       *WorkingDirectory();
    const char       *HomeDirectory(const char *userName=0);
-   char             *ConcatFileName(const char *dir, const char *name);
    const char       *TempDirectory() const;
    FILE             *TempFileName(TString &base, const char *dir = 0);
 
@@ -181,6 +180,7 @@ public:
 
    //---- Paths & Files ----------------------------------------
    const char        DriveName(const char *pathname="/");
+   const char       *PrependPathName(const char *dir, TString& name);
    Bool_t            ExpandPathName(TString &patbuf);
    char             *ExpandPathName(const char *path);
    Bool_t            AccessPathName(const char *path, EAccessMode mode = kFileExists);
@@ -197,7 +197,7 @@ public:
    int               Umask(Int_t mask);
    int               Utime(const char *file, Long_t modtime, Long_t actime);
    const char       *UnixPathName(const char *unixpathname);
-   char             *Which(const char *search, const char *file, EAccessMode mode = kFileExists);
+   const char       *FindFile(const char *search, TString& file, EAccessMode mode = kFileExists);
 
    //---- Standard Output redirection --------------------------
    Int_t             RedirectOutput(const char *name, const char *mode = "a");
diff --git a/winnt/src/TWinNTSystem.cxx b/winnt/src/TWinNTSystem.cxx
index 7dbb5a231fa..93e90f26af1 100644
--- a/winnt/src/TWinNTSystem.cxx
+++ b/winnt/src/TWinNTSystem.cxx
@@ -1,4 +1,4 @@
-// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.cxx,v 1.141 2006/05/18 10:46:26 brun Exp $
+// @(#)root/winnt:$Name:  $:$Id: TWinNTSystem.cxx,v 1.142 2006/05/21 18:17:24 brun Exp $
 // Author: Fons Rademakers   15/09/95
 
 /*************************************************************************
@@ -2078,30 +2078,20 @@ Bool_t TWinNTSystem::AccessPathName(const char *path, EAccessMode mode)
 }
 
 //______________________________________________________________________________
-char *TWinNTSystem::ConcatFileName(const char *dir, const char *name)
+const char *TWinNTSystem::PrependPathName(const char *dir, TString& name)
 {
-   // Concatenate a directory and a file name. Returned string must be
-   // deleted by user.
+   // Concatenate a directory and a file name.
 
-   Int_t ldir  = dir  ? strlen(dir) : 0;
-   Int_t lname = name ? strlen(name) : 0;
-
-   if (!lname) return StrDup(dir);
-
-   char *buf = new char[ldir+lname+2];
-
-   if (ldir) {
+   if (name == ".") name = "";
+   if (dir && dir[0]) {
       // Test whether the last symbol of the directory is a separator
-      char last = dir[ldir-1];
-      if (last == '/' || last == '\\' || last == ':') {
-         sprintf(buf, "%s%s", dir, name);
-      } else {
-         sprintf(buf, "%s\\%s", dir, name);
+      char last = dir[strlen(dir) - 1];
+      if (last != '/' && last == '\\') {
+         name.Prepend('\\');
       }
-   } else {
-      sprintf(buf, "\\%s", name);
+      name.Prepend(dir);
    }
-   return buf;
+   return name.Data();
 }
 
 //______________________________________________________________________________
@@ -2422,59 +2412,56 @@ int TWinNTSystem::Utime(const char *file, Long_t modtime, Long_t actime)
 }
 
 //______________________________________________________________________________
-char *TWinNTSystem::Which(const char *search, const char *infile, EAccessMode mode)
+const char *TWinNTSystem::FindFile(const char *search, TString& infile, EAccessMode mode)
 {
    // Find location of file in a search path.
    // User must delete returned string. Returns 0 in case file is not found.
 
-   static char name[kMAXPATHLEN];
-   char *lpFilePart = 0;
-   char *found = 0;
-
    // Windows cannot check on execution mode - all we can do is kReadPermission
    if (mode==kExecutePermission)
       mode=kReadPermission;
 
    // Expand parameters
 
-   char *exinfile = gSystem->ExpandPathName(infile);
+   gSystem->ExpandPathName(infile);
    // Check whether this infile has the absolute path first
-   if (IsAbsoluteFileName(exinfile) ) {
-      found = exinfile;
-   } else {
-      char *tmp = gSystem->ExpandPathName(search);
-      TString exsearch(tmp);
-      delete [] tmp;
-
-      // Need to use Windows delimiters
-      Int_t lastDelim = -1;
-      for(int i=0; i<exsearch.Length(); ++i) {
-         switch( exsearch[i] ) {
-            case ':': if (i-lastDelim!=2) exsearch[i] = ';'; // Replace the ':' unless there are after a disk suffix (aka ;c:\mydirec...)
-               lastDelim = i;
-               break;
-            case ';': lastDelim = i; break;
-         }
-      }
-
-      // Check access
-      struct stat finfo;
-      if (::SearchPath(exsearch, exinfile, NULL, kMAXPATHLEN, name, &lpFilePart) &&
-          ::access(name, mode) == 0 && stat(name, &finfo) == 0 &&
-          finfo.st_mode & S_IFREG) {
-         if (gEnv->GetValue("Root.ShowPath", 0)) {
-            Printf("Which: %s = %s", infile, name);
-         }
-         found = StrDup(name);
+   if (IsAbsoluteFileName(infile.Data()) ) {
+      if (!AccessPathName(infile.Data(), mode))
+      return infile.Data();
+      infile = "";
+      return 0;
+   }
+   TString exsearch(search);
+   gSystem->ExpandPathName(exsearch);
+
+   // Need to use Windows delimiters
+   Int_t lastDelim = -1;
+   for(int i=0; exsearch[i]; ++i) {
+      switch( exsearch[i] ) {
+         case ':': 
+            // Replace the ':' unless there are after a disk suffix (aka ;c:\mydirec...)
+            if (i-lastDelim!=2) exsearch[i] = ';';
+            lastDelim = i;
+            break;
+         case ';': lastDelim = i; break;
       }
-      delete [] exinfile;
    }
 
-   if (found  && AccessPathName(found, mode)) {
-      delete [] found;
-      found = 0;
+   // Check access
+   struct stat finfo;
+   char name[kMAXPATHLEN];
+   char *lpFilePart = 0;
+   if (::SearchPath(exsearch.Data(), infile.Data(), NULL, kMAXPATHLEN, name, &lpFilePart) &&
+       ::access(name, mode) == 0 && stat(name, &finfo) == 0 &&
+       finfo.st_mode & S_IFREG) {
+      if (gEnv->GetValue("Root.ShowPath", 0)) {
+         Printf("Which: %s = %s", infile, name);
+      }
+      infile = name;
+      return infile.Data();
    }
-   return found;
+   infile = "";
+   return 0;
 }
 
 //---- Users & Groups ----------------------------------------------------------
-- 
GitLab