]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkUtilities.cxx
#2536 BBTK Feature New Normal wt-version Package
[bbtk.git] / kernel / src / bbtkUtilities.cxx
index 9a6b0283e3ca0fc0ea3f36ee5d04f7967aeb78dc..7e85dc76787497b9e350fc332188b4283f88304b 100644 (file)
+/*
+ # ---------------------------------------------------------------------
+ #
+ # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
+ #                        pour la SantÈ)
+ # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
+ # Previous Authors : Laurent Guigues, Jean-Pierre Roux
+ # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
+ #
+ #  This software is governed by the CeCILL-B license under French law and
+ #  abiding by the rules of distribution of free software. You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL-B
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ #  or in the file LICENSE.txt.
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL-B license and that you accept its terms.
+ # ------------------------------------------------------------------------ */
+
+
+/*=========================================================================
+  Program:   bbtk
+  Module:    $RCSfile: bbtkUtilities.cxx,v $
+  Language:  C++
+  Date:      $Date: 2012/11/16 08:49:01 $
+  Version:   $Revision: 1.15 $
+=========================================================================*/
+
+
+
+
 #include "bbtkUtilities.h"
+#include "bbtkMessageManager.h"
+
+#if defined(MACOSX) // assume this is OSX 
+# include <sys/param.h>
+# include <mach-o/dyld.h> // _NSGetExecutablePath : must add -framework CoreFoundation to link line 
+# include <string.h>
+# ifndef PATH_MAX
+#  define PATH_MAX MAXPATHLEN
+# endif
+#endif // MACOSX
+
+#ifndef PATH_MAX // If not defined yet : do it 
+#  define PATH_MAX 2048
+#endif 
 
 namespace bbtk
 {
 
 
-bool Utilities::loosematch(std::string stdLine,std::string stdOptions) 
-{
-       bool result=false;
-       char charTmp;
-         std::vector<std::string> tokens;
-         SplitString ( stdOptions,"|", tokens);
-                         int j,sizeStdLineTmp;
-         int i,size=tokens.size();  
-         for (i=0; i<size; i++)
-         {               
-                 if ( strcasecmp(stdLine.c_str(),tokens[i].c_str())==0) 
-                 { 
-                         result=true; 
-                 }               
+
+           // ======================================================================
+    // See : http://www.techbytes.ca/techbyte103.html for more O.S.
+    bool Utilities::FileExists(std::string strFilename) 
+    {
+      struct stat stFileInfo;
+     bool blnReturn;
+     int intStat;
+     
+     // Attempt to get the file attributes
+     intStat = stat(strFilename.c_str(),&stFileInfo);
+     if(intStat == 0) 
+       {
+        // We were able to get the file attributes
+        // so the file obviously exists.
+        blnReturn = true;
+       } 
+     else 
+       {
+        // We were not able to get the file attributes.
+        // This may mean that we don't have permission to
+        // access the folder which contains this file. If you
+        // need to do that level of checking, lookup the
+        // return values of stat which will give you
+        // more details on why stat failed.
+        blnReturn = false;
+       }
+     
+     return(blnReturn);
+    }
+    
+    
+    // =====================================================================
+    
+    std::string Utilities::ExtractPackageName(const std::string  &name, 
+                                         std::string& path)
+    {
+      std::string pkgname;
+      path = "";
+      
+      std::string::size_type slash_position = name.find_last_of("/\\");
+      if (slash_position != std::string::npos) 
+       {
+         pkgname = name.substr(slash_position+1,std::string::npos);
+         path = name.substr(0,slash_position);
+         //    std::cout << "F:P='"<<path<<"'"<<std::endl;//+1,std::string::npos);
+       }
+      else 
+       {
+         pkgname = name;
+       }
+      
+      // remove {.so | dll} if any
+      std::string::size_type dot_position = pkgname.find_last_of('.');      
+      if (dot_position != std::string::npos){
+       pkgname = pkgname.substr(0,dot_position);
+      }      
+#if defined(__GNUC__)
+      
+      // GCC mechanism
+      // shared lib name = libbb<name>.so
+      
+      // remove {libbb} if any
+      if (memcmp ( pkgname.c_str(), "libbb", 5) == 0) {
+       pkgname =  pkgname.substr(5, pkgname.length());
+      }
+      /*
+     /// \ \todo     what would happen if (stupid) user names his package 'libbb' ?!?
+      /// \ --> Should be forbidden!
+      */
+#elif defined(_WIN32)
+      
+      // WIN 32 mechanism
+      // shared lib name = <name>.dll
+      
+      // EED Problem loading package call bbtkTools
+      //     // remove {bb} if any
+      if (memcmp (pkgname.c_str(), "bb", 2) == 0) {
+       pkgname =  pkgname.substr(2, pkgname.length());  
+      }
+      
+      /*
+     /// \ \todo     what would happen if (stupid) user names his package 'bb' ?!?
+     /// \ --> Should be forbidden!
+     */
+#else
+      bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
+#endif      
+      return pkgname;
+    }
+    
+    //=====================================================================
+    std::string Utilities::ExtractScriptName(const std::string &name,
+                                        std::string& path)
+    {
+      std::string pkgname;
+      
+      std::string::size_type slash_position = name.find_last_of("/\\");
+      if (slash_position != std::string::npos) {
+       pkgname =name.substr(slash_position+1,std::string::npos);
+       path = name.substr(0,slash_position);      
+      } else {
+       pkgname = name;
+      }
+      // remove {.bbs } if any
+      std::string::size_type dot_position = pkgname.find_last_of('.');
+      if (dot_position != std::string::npos){
+       pkgname = pkgname.substr(0,dot_position);
+      }
+      return pkgname;
+    }
+    
+    // ========================================================================
+
+    std::string Utilities::ExpandLibName(const std::string &name, bool verbose)
+    {
+      // -----   Think of expanding path name ( ./ ../ ../../ )
+      
+      char buf[2048]; // for getcwd
+      char * currentDir = getcwd(buf, 2048);
+      std::string cwd(currentDir);
+      std::string libname(name);
+      std::string fileSeparator;
+      fileSeparator = ConfigurationFile::GetInstance().Get_file_separator();
+      // tooHigh : true is user supplies a library pathname with too many "../"
+      bool tooHigh = false;
+      
+      //std::cout << "------------------cwd ["  << cwd << "] name [" << name << "]" << std::endl;
+      
+      if ( name[0] == '/' ||  name[1] == ':' ) // Linux or Windows absolute name
+       {
+         return(libname);
+       }
+      else if  ( name =="." )
+       {
+         libname = cwd  + fileSeparator;
+         return(libname);
+       }
+      else if  (name[0] == '.' && (name[1] == '/' || name[1] == '\\') )
+       {
+         libname = cwd  + fileSeparator + name.substr(2, name.length());
+         return(libname);
+       }
+      else if ( name[0] == '.' &&  name[1] == '.' /*  && (name[2] == '/' || name[2] == '\\') */ ) 
+       {
+         if ( IsAtRoot(cwd) )  // hope it gets / (for Linux),  C: D: (for Windows)
+      {  
+     // if we are already at / or c: --> hopeless  
+         if (verbose)
+           std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
+         tooHigh = true;
+      }
+      else
+      {
+         // iterate on ../ and go up from the current working dir!
+         std::string a(name); 
+         bool alreadyProcessRoot = false;
+
+          //if (a[a.size()-1] != fileSeparator[0])
+          //   a.append(fileSeparator);
+//std::cout << "------------------a ["  << a << "]" << std::endl;
+
+         for(;;)  // wild loop !
+         {
+            std::string::size_type slash_position = cwd.find_last_of(fileSeparator);
+            if (slash_position != std::string::npos) {
+             if (slash_position == 0)
+                slash_position = 1;
+              cwd = cwd.substr(0,slash_position/*+1*/);
+//std::cout << "------------------cwd ["  << cwd << "]" << std::endl;
+            //  if (a == "..") {
+            //    a = "";
+            //    break;
+            //   }
+            //   else
+                 a = a.substr(3, /*name.length()*/ a.length());  // remove ../
+//std::cout << "------------------a ["  << a << "]" << std::endl;  
+              if (a == "" || alreadyProcessRoot)
+              {
+                if (verbose)
+                  std::cout << "   File path : [" <<  name << "] doesn't exist" << std::endl;
+                tooHigh = true;
+                break;
+              }
+             // std::string b = cwd + a;
+              libname =  cwd;
+              char c = cwd[cwd.size()-1];
+              if (c != '/' && c != '\\' )
+                libname += fileSeparator;
+              libname += a;
+
+              if ( a[0] != '.' ) // if . (probabely ../), loop again
+                break;
+
+              if (IsAtRoot(cwd))
+                alreadyProcessRoot = true;
+            }
+         } // end iterating on ../
+      }
+//std::cout << "------------------out of loop]" << std::endl;        
+      if (tooHigh)
+         libname="";
+      return (libname);
+
+    }  // -----   End of expanding path name   ( ./ ../ ../../ )
+
+    std::cout <<"* ERROR in ExpandLibName : should never get here!" << std::endl;
+    // To avoid warning
+    return(""); // Will never get here!
+  }
+
+// ===================================================================================
+
+  std::string Utilities::MakeLibnameFromPath(std::string path, std::string pkgname)
+  {
+    std::string libname = path;
+       if(path.size()>0){
+               char c = path[path.size()-1];    
+#if defined(__GNUC__)
+       if (c != '/')
+          libname += "/libbb";
+       else
+          libname += "libbb";
+       libname += pkgname;
+#if defined(MACOSX)
+         libname += ".dylib";
+#else
+         libname += ".so";
+#endif 
+         
+#elif defined(_WIN32)
+       if (c != '\\') 
+          libname += "\\bb";
+       else
+          libname += "bb";
+       libname += pkgname;
+       libname += ".dll";
+#endif
+       }
+    
+    return libname;    
+  }
+
+// ===================================================================================
+
+  std::string Utilities::MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt)
+  {
+    std::string libname = path;
+       if(path.size()>0){
+               char c = path[path.size()-1];
+               if (c != '/' && c != '\\')
+               {
+                  libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
+               }
+               libname += pkgname;
+               if (addExt)
+               {
+                  int l = libname.size();
+                  if (l>4)
+                  {
+                         if (libname.substr(l-4, 4) != ".bbs")
+                         {
+                                  libname = libname + ".bbs";
+                         }
+                  }
+               }
+       }
+    
+    return libname;
+  }
+  // =======================================================================
+
+  // =======================================================================
+  /// Returns the user settings dir, e.g. /home/username/.bbtk
+  std::string Utilities::GetUserSettingsDir()
+  {
+    std::string str_Home=Utilities::GetEnvHome();
+    std::string fullname = str_Home + "/.bbtk";
+    MakeValidFileName(fullname);
+    return fullname;
+  }
+  
+
+  // =======================================================================
+  /// Builds the complete path to the file 'name' located 
+  /// in user settings dir, e.g. /home/username/.bbtk/
+  std::string Utilities::MakeUserSettingsFullFileName(const std::string& name)
+  {
+    std::string str_home=Utilities::GetEnvHome();
+    std::string fullname = str_home + "/.bbtk/" + name;
+    MakeValidFileName(fullname);
+    return fullname;
+  }
+  // =======================================================================
+  
+
+  // =======================================================================
+  void Utilities::CreateDirectoryIfNeeded( std::string const &dirName)
+  {
+    if (FileExists(dirName)) return;
+    std::string cmd("mkdir \"");
+    cmd += dirName;
+    cmd += "\"";
+    system(cmd.c_str());
+  }  
+  // =======================================================================
+  
+  
+  //========================================================================
+  bool Utilities::IsAtRoot(std::string cwd)
+  {
+    if ( cwd == "/"              // hope it gets /     (for Linux)
+        || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
+      return (true);
+    else
+      return(false);
+  }
+  // ======================================================================
+
+  // ======================================================================
+  bool Utilities::IsDirectory(std::string const &dirName)
+  {
+    struct stat fs;
+    
+    if ( stat(dirName.c_str(), &fs) == 0 )
+      {
+#if _WIN32
+       return ((fs.st_mode & _S_IFDIR) != 0);
+#else
+       return S_ISDIR(fs.st_mode);
+#endif
+      }
+    else
+      {
+       return false;
+      }
+  }
+  // =======================================================================
+    
+  // =======================================================================
+  void Utilities::SplitAroundFirstDot( const std::string& in,
+                                      std::string& left,
+                                      std::string& right)
+  {
+    std::string delimiter = ".";
+    std::string::size_type pos = in.find_first_of(delimiter);
+    if (std::string::npos != pos) 
+      {
+       left = in.substr(0,pos);
+       right = in.substr(pos+1,in.size());
+       
+      }
+    else
+      {
+       left ="";
+       right = "";
+       bbtkGlobalError("Token '"<<in<<"' : expected 'a.b' format but no dot found");
+      }
+  }
+  //=======================================================================
+
+  //=======================================================================
+  void Utilities::SplitString ( const std::string& str, 
+                               const std::string& delimiters, 
+                               std::vector<std::string>& tokens)
+  {
+    // Skip delimiters at beginning.
+    std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+    // Find first delimiter.
+    std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
+    
+    while (std::string::npos != pos || std::string::npos != lastPos)
+      {
+       // Found a token, add it to the vector.
+       tokens.push_back(str.substr(lastPos, pos - lastPos));
+       // Skip delimiters.  Note the "not_of"
+       lastPos = str.find_first_not_of(delimiters, pos);
+       // Find next delimiter
+       pos = str.find_first_of(delimiters, lastPos);
+      }
+    
+  }
+  //=======================================================================
+  
+  
+  // ======================================================================
+  std::string Utilities::get_file_name(const std::string& s) 
+  { 
+    std::string::size_type slash_position = s.find_last_of("/\\");
+    if (slash_position != std::string::npos) 
+      {
+       return  s.substr(slash_position+1,std::string::npos);   
+      }
+    else 
+      {
+       return s;
+      }
+  }
+  //=======================================================================
+
+  // ========================================================================
+  /**
+   * \brief   Explore a directory with possibility of recursion
+   *          return number of files read
+   * @param  dirpath   directory to explore
+   * @param  recursive whether we want recursion or not
+   */
+  int Utilities::Explore(std::string const &dirpath, bool recursive, std::vector<std::string> &Filenames)
+  {
+    int numberOfFiles = 0;
+    std::string fileName;
+      
+      std::string dirName = dirpath;
+      
+#ifdef _MSC_VER
+      WIN32_FIND_DATA fileData;
+   HANDLE hFile = FindFirstFile((dirName+"\\*").c_str(), &fileData);
+
+   for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
+       b = FindNextFile(hFile, &fileData))
+   {
+      fileName = fileData.cFileName;
+      if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+      {
+         // Need to check for . and .. to avoid infinite loop
+         if ( fileName != "." && fileName != ".." && recursive )
+         {
+            numberOfFiles += Explore(dirName+ "\\"+fileName,recursive,Filenames);
+         }
+      }
+      else
+      {
+         Filenames.push_back(dirName+"\\"+fileName);
+         numberOfFiles++;
+      }
+   }
+   DWORD dwError = GetLastError();
+   if (hFile != INVALID_HANDLE_VALUE) 
+      FindClose(hFile);
+   if (dwError != ERROR_NO_MORE_FILES) 
+   {
+      LPVOID lpMsgBuf;
+      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
+                    FORMAT_MESSAGE_FROM_SYSTEM|
+                    FORMAT_MESSAGE_IGNORE_INSERTS,
+                    NULL,GetLastError(),
+                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                    (LPTSTR) &lpMsgBuf,0,NULL);
+
+     // ErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
+     //             <<" for the directory : "<<dirName);
+      
+      return 0;
+   }
+
+#else
+  // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
+  // work on debian for example
+//std::cout <<"in Explor dirname[" << dirName << "]" << std::endl; 
+   DIR* dir = opendir(dirName.c_str());
+   if (!dir)
+   {
+      return 0;
+   }
+//std::cout <<"Open OK" << std::endl; 
+   // According to POSIX, the dirent structure contains a field char d_name[]
+   // of unspecified size, with at most NAME_MAX characters preceeding the
+   // terminating null character. Use of other fields will harm the  porta-
+   // bility of your programs.
+
+   struct stat buf;
+   dirent *d;
+   for (d = readdir(dir); d; d = readdir(dir))
+   {
+      fileName = dirName + "/" + d->d_name;
+//std::cout <<"in Explor filename[" << fileName << "]" << std::endl;      
+      if( stat(fileName.c_str(), &buf) != 0 )
+      {
+         //ErrorMacro( strerror(errno) );
+      }
+      if ( S_ISREG(buf.st_mode) )    //is it a regular file?
+      {
+         Filenames.push_back( fileName );
+         numberOfFiles++;
+      }
+      else if ( S_ISDIR(buf.st_mode) ) //directory?
+      {
+         if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
+         {
+            numberOfFiles += Explore( fileName, recursive, Filenames);
+         }
+      }
+      else
+      {
+         //ErrorMacro( "Unexpected error" );
+         return -1;
+      }
+   }
+   if( closedir(dir) != 0 )
+   {
+     // ErrorMacro( strerror(errno) );
+   }
+#endif
+
+  return numberOfFiles;
+
+}
+  //=======================================================================
+
+    //=======================================================================
+    // Replaces substrings "\\n" by a real carriage return "\n"
+    void Utilities::SubsBackslashN ( std::string& s )
+    {
+      std::string ss("\\n");
+      std::string::size_type pos = 0;
+      pos = s.find(ss,0);
+      const char* cr = "\n";
+      while ( pos != std::string::npos )
+       {
+         s.replace(pos,2,cr,1);
+         pos = s.find(ss, pos-1);
+       }
+    }
+    //=======================================================================
+
+
+   //=======================================================================
+
+  bool Utilities::loosematch(std::string stdLine,std::string stdOptions) 
+  {
+    bool result=false;
+    std::vector<std::string> tokens;
+    SplitString ( stdOptions,"|", tokens);
+    int i,size=tokens.size();  
+    for (i=0; i<size; i++)
+      {                  
+#ifdef WIN32
+       if ( strcmpi(stdLine.c_str(),tokens[i].c_str())==0) 
+         { 
+           result=true; 
+         }               
+#else
+       if ( strcasecmp(stdLine.c_str(),tokens[i].c_str())==0) 
+         { 
+           result=true; 
+         }               
+#endif
+       
+      }
+    return result;
+  }
+  //=========================================================================  
+  
+  //=========================================================================  
+  // From http://www.fltk.org/newsgroups.php?gfltk.general+v:22083
+  //
+  int get_app_path (char *pname, size_t pathsize)
+  {
+#ifdef LINUX
+    /* Oddly, the readlink(2) man page says no NULL is appended. */
+    /* So you have to do it yourself, based on the return value: */
+    pathsize --; /* Preserve a space to add the trailing NULL */
+    long result = readlink("/proc/self/exe", pname, pathsize);
+    if (result > 0)
+      {
+       pname[result] = 0; /* add the #@!%ing NULL */
+       
+       if ((access(pname, 0) == 0))
+         return 0; /* file exists, return OK */
+       /*else name doesn't seem to exist, return FAIL (falls
+         through) */
+      }
+#endif /* LINUX */
+    
+#ifdef WIN32
+    long result = GetModuleFileName(NULL, pname, pathsize);
+    if (result > 0)
+      {
+       /* fix up the dir slashes... */
+       int len = strlen(pname);
+       int idx;
+       for (idx = 0; idx < len; idx++)
+         {
+           if (pname[idx] == '\\') pname[idx] = '/';
+         }
+       
+       for (idx = len-1; idx >=0 ; idx--)
+         {
+           if (pname[idx] == '/')
+             { 
+               pname[idx+1] = '\0';
+               idx = -1;
+             }
+         }
+       
+       if ((access(pname, 0) == 0))
+         return 0; /* file exists, return OK */
+       /*else name doesn't seem to exist, return FAIL (falls
+         through) */
+      }
+#endif /* WIN32 */
+    
+#ifdef SOLARIS
+    char *p = getexecname();
+    if (p)
+      {
+       /* According to the Sun manpages, getexecname will
+          "normally" return an */
+       /* absolute path - BUT might not... AND that IF it is not,
+          pre-pending */
+       /* getcwd() will "usually" be the correct thing... Urgh!
+        */
+       
+       /* check pathname is absolute (begins with a / ???) */
+       if (p[0] == '/') /* assume this means we have an
+                           absolute path */
+         {
+           strncpy(pname, p, pathsize);
+           if ((access(pname, 0) == 0))
+             return 0; /* file exists, return OK */
+         }
+       else /* if not, prepend getcwd() then check if file
+               exists */
+         {
+           getcwd(pname, pathsize);
+           long result = strlen(pname);
+           strncat(pname, "/", (pathsize - result));
+           result ++;
+           strncat(pname, p, (pathsize - result));
+           
+           if ((access(pname, 0) == 0))
+             return 0; /* file exists, return OK */
+           /*else name doesn't seem to exist, return FAIL
+             (falls through) */
+         }
+      }
+#endif /* SOLARIS */
+    
+#ifdef MACOSX /* assume this is OSX */
+    /*
+      from http://www.hmug.org/man/3/NSModule.html
+      
+      extern int _NSGetExecutablePath(char *buf, unsigned long
+      *bufsize);
+      
+      _NSGetExecutablePath  copies  the  path  of the executable
+      into the buffer and returns 0 if the path was successfully
+      copied  in the provided buffer. If the buffer is not large
+      enough, -1 is returned and the  expected  buffer  size  is
+      copied  in  *bufsize.  Note that _NSGetExecutablePath will
+      return "a path" to the executable not a "real path" to the
+      executable.  That  is  the path may be a symbolic link and
+      not the real file. And with  deep  directories  the  total
+      bufsize needed could be more than MAXPATHLEN.
+    */
+    int status = -1;
+    char *given_path = (char*)malloc(MAXPATHLEN * 2);
+    if (!given_path) return status;
+    
+    uint32_t npathsize = MAXPATHLEN * 2;
+    long result = _NSGetExecutablePath(given_path, &npathsize);
+    if (result == 0)
+      { /* OK, we got something - now try and resolve the real path...
+        */
+       if (realpath(given_path, pname) != NULL)
+         {
+           if ((access(pname, 0) == 0))
+             status = 0; /* file exists, return OK */
          }
-         return result;
+      }
+    free (given_path);
+    return status;
+#endif /* MACOSX */
+    
+    return -1; /* Path Lookup Failed */
+  } 
+  //=========================================================================
+       
+
+       
+  //=========================================================================
+  std::string Utilities::GetExecutablePath()
+  {
+    char name[PATH_MAX];
+    int err = get_app_path(name, PATH_MAX);
+    if (err) 
+      {
+       bbtkGlobalError("Could not determine current executable path ?");  
+      }
+    
+    // remove the exe name
+    char *slash;               
+    slash = strrchr(name, VALID_FILE_SEPARATOR_CHAR);
+    if (slash)
+      {
+       *slash = 0;
+      }
+    return name;
+  }
+  //=========================================================================
+
+
+std::string Utilities::GetEnvHome()
+{
+#if defined(__GNUC__)
+       std::string strHome;
+    char *envHome=getenv("HOME");
+    if (envHome!=NULL)  
+       { 
+               strHome=envHome; 
+       } else {
+               strHome = "/var/www/testwtdbg/docroot";
+       } // if
+#elif defined(_WIN32)
+       std::string strHome( getenv("USERPROFILE") );
+#endif
+       return strHome;
+}   
+
+
+
+//TAD Arbol CFT
+
+
+//---------NodeTree---------------
+
+NodeTreeC::NodeTreeC() 
+{
+       
+}
+
+NodeTreeC::NodeTreeC(std::string _data)
+{
+       data = _data;
+}
+
+NodeTreeC::~NodeTreeC()
+{
+
+}
+void NodeTreeC::deleteTree()
+{
+       data = "";
+       std::cout<<"NodeTreeC::deleteTree 1"<<std::endl;
+       childs.erase(childs.begin(),childs.begin()+childs.size());
+       std::cout<<"NodeTreeC::deleteTree 2"<<std::endl;
 }
 
+void NodeTreeC::insertChild(std::string _data)
+{
+       NodeTreeC temp = NodeTreeC(_data);
+       childs.push_back(temp);
+       //std::cout<<"NodeTreeC::insertChild"<<std::endl;
+}
 
+void NodeTreeC::treeTour(int lvl)
+{
+       std::string space = "";
+       for (int j=0; j<lvl ; j++){
+                               space += "   ";
+       }
+       lvl++;
+       std::cout <<space<<"data: "<< data << "  size: "<< childs.size() << std::endl;
+       for(int i = 0 ; i < childs.size(); i++)
+       {
+               childs[i].treeTour(lvl);                
+       }
+}
+
+void NodeTreeC::setData(std::string _data)
+{
+       data = _data;
+       //std::cout<<"NodeTreeC::setData"<<std::endl;
+}
 
 }