bbtkUtilities.cxx

Go to the documentation of this file.
00001 /*=========================================================================                                                                               
00002   Program:   bbtk
00003   Module:    $RCSfile: bbtkUtilities.cxx,v $
00004   Language:  C++
00005   Date:      $Date: 2008/10/17 08:18:14 $
00006   Version:   $Revision: 1.7 $
00007 =========================================================================*/
00008 
00009 /* ---------------------------------------------------------------------
00010 
00011 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
00012 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
00013 *
00014 *  This software is governed by the CeCILL-B license under French law and 
00015 *  abiding by the rules of distribution of free software. You can  use, 
00016 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
00017 *  license as circulated by CEA, CNRS and INRIA at the following URL 
00018 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
00019 *  or in the file LICENSE.txt.
00020 *
00021 *  As a counterpart to the access to the source code and  rights to copy,
00022 *  modify and redistribute granted by the license, users are provided only
00023 *  with a limited warranty  and the software's author,  the holder of the
00024 *  economic rights,  and the successive licensors  have only  limited
00025 *  liability. 
00026 *
00027 *  The fact that you are presently reading this means that you have had
00028 *  knowledge of the CeCILL-B license and that you accept its terms.
00029 * ------------------------------------------------------------------------ */                                                                         
00030 
00031 
00032 #include "bbtkUtilities.h"
00033 
00034  
00035 
00036 namespace bbtk
00037 {
00038 
00039 
00040 
00041             // ======================================================================
00042     // See : http://www.techbytes.ca/techbyte103.html for more O.S.
00043     bool Utilities::FileExists(std::string strFilename) 
00044     {
00045       struct stat stFileInfo;
00046      bool blnReturn;
00047      int intStat;
00048      
00049      // Attempt to get the file attributes
00050      intStat = stat(strFilename.c_str(),&stFileInfo);
00051      if(intStat == 0) 
00052        {
00053          // We were able to get the file attributes
00054          // so the file obviously exists.
00055          blnReturn = true;
00056        } 
00057      else 
00058        {
00059          // We were not able to get the file attributes.
00060          // This may mean that we don't have permission to
00061          // access the folder which contains this file. If you
00062          // need to do that level of checking, lookup the
00063          // return values of stat which will give you
00064          // more details on why stat failed.
00065          blnReturn = false;
00066        }
00067      
00068      return(blnReturn);
00069     }
00070     
00071     
00072     // =====================================================================
00073     
00074     std::string Utilities::ExtractPackageName(const std::string  &name, 
00075                                           std::string& path)
00076     {
00077       std::string pkgname;
00078       path = "";
00079       
00080       std::string::size_type slash_position = name.find_last_of("/\\");
00081       if (slash_position != std::string::npos) 
00082         {
00083           pkgname = name.substr(slash_position+1,std::string::npos);
00084           path = name.substr(0,slash_position);
00085           //    std::cout << "F:P='"<<path<<"'"<<std::endl;//+1,std::string::npos);
00086         }
00087       else 
00088         {
00089           pkgname = name;
00090         }
00091       
00092       // remove {.so | dll} if any
00093       std::string::size_type dot_position = pkgname.find_last_of('.');      
00094       if (dot_position != std::string::npos){
00095         pkgname = pkgname.substr(0,dot_position);
00096       }      
00097 #if defined(__GNUC__)
00098       
00099       // GCC mechanism
00100       // shared lib name = libbb<name>.so
00101       
00102       // remove {libbb} if any
00103       if (memcmp ( pkgname.c_str(), "libbb", 5) == 0) {
00104         pkgname =  pkgname.substr(5, pkgname.length());
00105       }
00106       /*
00109       */
00110 #elif defined(_WIN32)
00111       
00112       // WIN 32 mechanism
00113       // shared lib name = <name>.dll
00114       
00115       // EED Problem loading package call bbtkTools
00116       //     // remove {bb} if any
00117       if (memcmp (pkgname.c_str(), "bb", 2) == 0) {
00118         pkgname =  pkgname.substr(2, pkgname.length());  
00119       }
00120       
00121       /*
00124      */
00125 #else
00126       bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
00127 #endif      
00128       return pkgname;
00129     }
00130     
00131     //=====================================================================
00132     std::string Utilities::ExtractScriptName(const std::string &name,
00133                                          std::string& path)
00134     {
00135       std::string pkgname;
00136       
00137       std::string::size_type slash_position = name.find_last_of("/\\");
00138       if (slash_position != std::string::npos) {
00139         pkgname =name.substr(slash_position+1,std::string::npos);
00140         path = name.substr(0,slash_position);      
00141       } else {
00142         pkgname = name;
00143       }
00144       // remove {.bbs } if any
00145       std::string::size_type dot_position = pkgname.find_last_of('.');
00146       if (dot_position != std::string::npos){
00147         pkgname = pkgname.substr(0,dot_position);
00148       }
00149       return pkgname;
00150     }
00151     
00152     // ========================================================================
00153 
00154     std::string Utilities::ExpandLibName(const std::string &name, bool verbose)
00155     {
00156       // -----   Think of expanding path name ( ./ ../ ../../ )
00157       
00158       char buf[2048]; // for getcwd
00159       char * currentDir = getcwd(buf, 2048);
00160       std::string cwd(currentDir);
00161       std::string libname(name);
00162       std::string fileSeparator;
00163       fileSeparator = ConfigurationFile::GetInstance().Get_file_separator();
00164       // tooHigh : true is user supplies a library pathname with too many "../"
00165       bool tooHigh = false;
00166       
00167       //std::cout << "------------------cwd ["  << cwd << "] name [" << name << "]" << std::endl;
00168       
00169       if ( name[0] == '/' ||  name[1] == ':' ) // Linux or Windows absolute name
00170         {
00171           return(libname);
00172         }
00173       else if  ( name =="." )
00174         {
00175           libname = cwd  + fileSeparator;
00176           return(libname);
00177         }
00178       else if  (name[0] == '.' && (name[1] == '/' || name[1] == '\\') )
00179         {
00180           libname = cwd  + fileSeparator + name.substr(2, name.length());
00181           return(libname);
00182         }
00183       else if ( name[0] == '.' &&  name[1] == '.' /*  && (name[2] == '/' || name[2] == '\\') */ ) 
00184         {
00185           if ( IsAtRoot(cwd) )  // hope it gets / (for Linux),  C: D: (for Windows)
00186       {  
00187      // if we are already at / or c: --> hopeless  
00188          if (verbose)
00189            std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
00190          tooHigh = true;
00191       }
00192       else
00193       {
00194          // iterate on ../ and go up from the current working dir!
00195          std::string a(name); 
00196          bool alreadyProcessRoot = false;
00197 
00198           //if (a[a.size()-1] != fileSeparator[0])
00199           //   a.append(fileSeparator);
00200 //std::cout << "------------------a ["  << a << "]" << std::endl;
00201 
00202          for(;;)  // wild loop !
00203          {
00204             std::string::size_type slash_position = cwd.find_last_of(fileSeparator);
00205             if (slash_position != std::string::npos) {
00206              if (slash_position == 0)
00207                 slash_position = 1;
00208               cwd = cwd.substr(0,slash_position/*+1*/);
00209 //std::cout << "------------------cwd ["  << cwd << "]" << std::endl;
00210             //  if (a == "..") {
00211             //    a = "";
00212             //    break;
00213             //   }
00214             //   else
00215                  a = a.substr(3, /*name.length()*/ a.length());  // remove ../
00216 //std::cout << "------------------a ["  << a << "]" << std::endl;  
00217               if (a == "" || alreadyProcessRoot)
00218               {
00219                 if (verbose)
00220                   std::cout << "   File path : [" <<  name << "] doesn't exist" << std::endl;
00221                 tooHigh = true;
00222                 break;
00223               }
00224              // std::string b = cwd + a;
00225               libname =  cwd;
00226               char c = cwd[cwd.size()-1];
00227               if (c != '/' && c != '\\' )
00228                 libname += fileSeparator;
00229               libname += a;
00230 
00231               if ( a[0] != '.' ) // if . (probabely ../), loop again
00232                 break;
00233 
00234               if (IsAtRoot(cwd))
00235                 alreadyProcessRoot = true;
00236             }
00237          } // end iterating on ../
00238       }
00239 //std::cout << "------------------out of loop]" << std::endl;        
00240       if (tooHigh)
00241          libname="";
00242       return (libname);
00243 
00244     }  // -----   End of expanding path name   ( ./ ../ ../../ )
00245 
00246     std::cout <<"* ERROR in ExpandLibName : should never get here!" << std::endl;
00247     // To avoid warning
00248     return(""); // Will never get here!
00249   }
00250 
00251 // ===================================================================================
00252 
00253   std::string Utilities::MakeLibnameFromPath(std::string path, std::string pkgname)
00254   {
00255     std::string libname = path;
00256     char c = path[path.size()-1];    
00257 #if defined(__GNUC__)
00258        if (c != '/')
00259           libname += "/libbb";
00260        else
00261           libname += "libbb";
00262        libname += pkgname;
00263        libname += ".so";
00264          
00265 #elif defined(_WIN32)
00266        if (c != '\\')
00267           libname = path+"\\bb";
00268        libname += pkgname;
00269        libname += ".dll";
00270 #endif
00271     return libname;    
00272   }
00273 
00274 // ===================================================================================
00275 
00276   std::string Utilities::MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt)
00277   {
00278     std::string libname = path;
00279     char c = path[path.size()-1];
00280     if (c != '/' && c != '\\')
00281     {
00282        libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
00283     }
00284     libname += pkgname;
00285     if (addExt)
00286     {
00287        int l = libname.size();
00288        if (l>4)
00289        {
00290           if (libname.substr(l-4, 4) != ".bbs")
00291           {
00292                libname = libname + ".bbs";
00293           }
00294        }
00295     }
00296     return libname;
00297   }
00298 
00299   // =======================================================================
00302   std::string Utilities::MakeUserSettingsFullFileName(const std::string& name)
00303   {
00304 #if defined(__GNUC__)
00305     std::string str_home(getenv("HOME"));
00306 #elif defined(_WIN32)
00307     std::string str_home(getenv("USERPROFILE"));
00308 #endif
00309     std::string fullname = str_home + "/.bbtk/" + name;
00310     Utilities::replace( fullname, 
00311                         INVALID_FILE_SEPARATOR , 
00312                         VALID_FILE_SEPARATOR);
00313     return fullname;
00314   }
00315   
00316 
00317 
00318     //========================================================================
00319     
00320     bool Utilities::IsAtRoot(std::string cwd)
00321     {
00322       if ( cwd == "/"              // hope it gets /     (for Linux)
00323            || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
00324         return (true);
00325       else
00326         return(false);
00327     }
00328     
00329     // ======================================================================
00330     
00331     bool Utilities::IsDirectory(std::string const &dirName)
00332     {
00333       struct stat fs;
00334       
00335       if ( stat(dirName.c_str(), &fs) == 0 )
00336         {
00337 #if _WIN32
00338           return ((fs.st_mode & _S_IFDIR) != 0);
00339 #else
00340           return S_ISDIR(fs.st_mode);
00341 #endif
00342         }
00343       else
00344         {
00345           return false;
00346         }
00347     }
00348     
00349     // ===================================================================================
00350     
00351     void Utilities::SplitAroundFirstDot( const std::string& in,
00352                                             std::string& left,
00353                                             std::string& right)
00354     {
00355       std::string delimiter = ".";
00356       std::string::size_type pos = in.find_first_of(delimiter);
00357       if (std::string::npos != pos) 
00358         {
00359           left = in.substr(0,pos);
00360           right = in.substr(pos+1,in.size());
00361           
00362         }
00363       else
00364         {
00365           // bbtkError(in<<" : expected 'a.b' format but no dot found");
00366           left ="";
00367           right = "";
00368         }
00369     }
00370     //=======================================================================
00371     void Utilities::SplitString ( const std::string& str, 
00372                                      const std::string& delimiters, 
00373                                      std::vector<std::string>& tokens)
00374     {
00375       // Skip delimiters at beginning.
00376       std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
00377       // Find first delimiter.
00378       std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
00379       
00380       while (std::string::npos != pos || std::string::npos != lastPos)
00381         {
00382           // Found a token, add it to the vector.
00383           tokens.push_back(str.substr(lastPos, pos - lastPos));
00384           // Skip delimiters.  Note the "not_of"
00385           lastPos = str.find_first_not_of(delimiters, pos);
00386           // Find next delimiter
00387           pos = str.find_first_of(delimiters, lastPos);
00388         }
00389       
00390     }
00391     //=======================================================================
00392     
00393     
00394     // ===================================================================================
00395     
00396     std::string Utilities::get_file_name(const std::string& s) 
00397     { 
00398       std::string::size_type slash_position = s.find_last_of("/\\");
00399       if (slash_position != std::string::npos) 
00400         {
00401           return  s.substr(slash_position+1,std::string::npos);   
00402         }
00403       else 
00404         {
00405           return s;
00406         }
00407     }
00408     
00409     // ===================================================================================
00416     int Utilities::Explore(std::string const &dirpath, bool recursive, std::vector<std::string> &Filenames)
00417     {
00418       int numberOfFiles = 0;
00419       std::string fileName;
00420       
00421       std::string dirName = dirpath;
00422       
00423 #ifdef _MSC_VER
00424       WIN32_FIND_DATA fileData;
00425    HANDLE hFile = FindFirstFile((dirName+"\\*").c_str(), &fileData);
00426 
00427    for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
00428        b = FindNextFile(hFile, &fileData))
00429    {
00430       fileName = fileData.cFileName;
00431       if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00432       {
00433          // Need to check for . and .. to avoid infinite loop
00434          if ( fileName != "." && fileName != ".." && recursive )
00435          {
00436             numberOfFiles += Explore(dirName+ "\\"+fileName,recursive,Filenames);
00437          }
00438       }
00439       else
00440       {
00441          Filenames.push_back(dirName+"\\"+fileName);
00442          numberOfFiles++;
00443       }
00444    }
00445    DWORD dwError = GetLastError();
00446    if (hFile != INVALID_HANDLE_VALUE) 
00447       FindClose(hFile);
00448    if (dwError != ERROR_NO_MORE_FILES) 
00449    {
00450       LPVOID lpMsgBuf;
00451       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
00452                     FORMAT_MESSAGE_FROM_SYSTEM|
00453                     FORMAT_MESSAGE_IGNORE_INSERTS,
00454                     NULL,GetLastError(),
00455                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00456                     (LPTSTR) &lpMsgBuf,0,NULL);
00457 
00458      // ErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
00459      //             <<" for the directory : "<<dirName);
00460       
00461       return 0;
00462    }
00463 
00464 #else
00465   // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
00466   // work on debian for example
00467 //std::cout <<"in Explor dirname[" << dirName << "]" << std::endl; 
00468    DIR* dir = opendir(dirName.c_str());
00469    if (!dir)
00470    {
00471       return 0;
00472    }
00473 //std::cout <<"Open OK" << std::endl; 
00474    // According to POSIX, the dirent structure contains a field char d_name[]
00475    // of unspecified size, with at most NAME_MAX characters preceeding the
00476    // terminating null character. Use of other fields will harm the  porta-
00477    // bility of your programs.
00478 
00479    struct stat buf;
00480    dirent *d;
00481    for (d = readdir(dir); d; d = readdir(dir))
00482    {
00483       fileName = dirName + "/" + d->d_name;
00484 //std::cout <<"in Explor filename[" << fileName << "]" << std::endl;      
00485       if( stat(fileName.c_str(), &buf) != 0 )
00486       {
00487          //ErrorMacro( strerror(errno) );
00488       }
00489       if ( S_ISREG(buf.st_mode) )    //is it a regular file?
00490       {
00491          Filenames.push_back( fileName );
00492          numberOfFiles++;
00493       }
00494       else if ( S_ISDIR(buf.st_mode) ) //directory?
00495       {
00496          if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
00497          {
00498             numberOfFiles += Explore( fileName, recursive, Filenames);
00499          }
00500       }
00501       else
00502       {
00503          //ErrorMacro( "Unexpected error" );
00504          return -1;
00505       }
00506    }
00507    if( closedir(dir) != 0 )
00508    {
00509      // ErrorMacro( strerror(errno) );
00510    }
00511 #endif
00512 
00513   return numberOfFiles;
00514 
00515 }
00516 
00517 
00518     //=======================================================================
00519     // Replaces substrings "\\n" by a real carriage return "\n"
00520     void Utilities::SubsBackslashN ( std::string& s )
00521     {
00522       std::string ss("\\n");
00523       std::string::size_type pos = 0;
00524       pos = s.find(ss,0);
00525       char* cr = "\n";
00526       while ( pos != std::string::npos )
00527         {
00528           s.replace(pos,2,cr,1);
00529           pos = s.find(ss, pos-1);
00530         }
00531     }
00532     //=======================================================================
00533 
00534 
00535 
00536 bool Utilities::loosematch(std::string stdLine,std::string stdOptions) 
00537 {
00538         bool result=false;
00539           std::vector<std::string> tokens;
00540           SplitString ( stdOptions,"|", tokens);
00541           int i,size=tokens.size();  
00542           for (i=0; i<size; i++)
00543           {               
00544 #ifdef WIN32
00545                   if ( strcmpi(stdLine.c_str(),tokens[i].c_str())==0) 
00546                   { 
00547                           result=true; 
00548                   }               
00549 #else
00550                   if ( strcasecmp(stdLine.c_str(),tokens[i].c_str())==0) 
00551                   { 
00552                           result=true; 
00553                   }               
00554 #endif
00555 
00556           }
00557           return result;
00558 }
00559 
00560 
00561 
00562 }

Generated on Wed Nov 12 11:37:08 2008 for BBTK by  doxygen 1.5.6