]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkUtilities.cxx
Compil sous Windows
[bbtk.git] / kernel / src / bbtkUtilities.cxx
index 968853ff91b111f59a100382974cf1cb42f9eacb..ff96d767462d502ffe7aee9d2e9acc1f3700546a 100644 (file)
@@ -5,6 +5,483 @@ namespace bbtk
 {
 
 
+
+           // ======================================================================
+    // 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;
+    char c = path[path.size()-1];    
+#if defined(__GNUC__)
+       if (c != '/')
+          libname += "/libbb";
+       else
+          libname += "libbb";
+       libname += pkgname;
+       libname += ".so";
+         
+#elif defined(_WIN32)
+       if (c != '\\')
+          libname = path+"\\bb";
+       libname += pkgname;
+       libname += ".dll";
+#endif
+    return libname;    
+  }
+
+// ===================================================================================
+
+  std::string Utilities::MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt)
+  {
+    std::string libname = path;
+    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;
+  }
+
+    //========================================================================
+    
+    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
+       {
+         // bbtkError(in<<" : expected 'a.b' format but no dot found");
+         left ="";
+         right = "";
+       }
+    }
+    //=======================================================================
+    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);
+      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;