Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

posix.cpp

00001 //FILE:         posix.cpp
00002 //AUTHOR:       Nathan Cournia <nathan@cournia.com>
00003 //DESCRIPTION:  POSIX compatable utility functions.
00004 
00005 #include <unistd.h>
00006 #include <sys/stat.h>
00007 #include <vector>
00008 #include <cerrno>
00009 #include <cstring>
00010 #include "utils.h"
00011 
00013 bool
00014 utils::mkdir( const std::string& filename )
00015 {
00016         if( !(::mkdir( filename.c_str( ), 0755 ) == 0) ) {
00017                 set_error( ::strerror( errno ) );
00018                 return false;
00019         }
00020         clear_error( );
00021         return true;
00022 }
00023 
00025 bool
00026 utils::exists( const std::string& filename )
00027 {
00028         struct stat tmp;
00029         if( !(stat (filename.c_str( ), &tmp) >= 0)) {
00030                 set_error( ::strerror( errno ) );
00031                 return false;
00032         }
00033         clear_error( );
00034         return true;
00035 }
00036 
00038 bool
00039 utils::can_read( const std::string& filename )
00040 {
00041         if( !(access( filename.c_str( ), R_OK ) == 0) ) {
00042                 set_error( ::strerror( errno ) );
00043                 return false;
00044         }
00045         clear_error( );
00046         return true;
00047 }
00048 
00050 bool
00051 utils::is_dir( const std::string& filename )
00052 {
00053         struct stat tmp;
00054         if( lstat( filename.c_str( ), &tmp ) == 0 ) {
00055                 if( S_ISDIR( tmp.st_mode ) ) {
00056                         clear_error( );
00057                         return true;
00058                 }
00059         }
00060         set_error( ::strerror( errno ) );
00061         return false;
00062 }
00063 
00065 bool
00066 utils::is_link( const std::string& filename )
00067 {
00068         struct stat tmp;
00069         if( lstat( filename.c_str( ), &tmp ) == 0 ) {
00070                 if( S_ISLNK( tmp.st_mode ) ) {
00071                         clear_error( );
00072                         return true;
00073                 }
00074         }
00075         set_error( ::strerror( errno ) );
00076         return false;
00077 }
00078 
00080 bool
00081 utils::chdir( const std::string& filename )
00082 {
00083         if( !(::chdir( filename.c_str( ) ) == 0) ) {
00084                 set_error( ::strerror( errno ) );
00085                 return false;
00086         }
00087         clear_error( );
00088         return true;
00089 }
00090 
00092 std::string
00093 utils::get_valid_absolute_dir( const std::string& file )
00094 {
00095         //trim whitespace
00096         std::string filename = file;
00097         filename = utils::trim( utils::rtrim( filename ) );
00098 
00099         //make sure the string is not empty
00100         if( filename.length( ) < 1 ) return "";
00101         
00102         //is this file path absolute
00103         if( filename[ 0 ] != '/' ) {
00104                 //relative path, get cwd
00105                 char cwd[ 1024 ]; //hope this is enough
00106                 getcwd( cwd, 1024 );
00107 
00108                 //add relative path to full path
00109                 filename = std::string( cwd ) + "/" + filename;
00110         }
00111 
00112         //create a stack
00113         std::vector<std::string> stack;
00114 
00115         //place dirs on stack
00116         std::string::size_type start = 0;
00117         std::string::size_type pos = 0;
00118         std::string token;
00119 
00120         //delimit by "/"
00121         while( (pos = filename.find_first_of( "/", start )) != std::string::npos ) {
00122                 token = filename.substr( start, pos - start );
00123                 if( token == ".." ) {
00124                         //go back a dir, pop the stack
00125                         if( stack.size( ) > 0 ) {
00126                                 stack.pop_back( );
00127                         }
00128                 } else if( (token.length( ) > 0) && (token != ".") ) {
00129                         //place token on stack
00130                         stack.push_back( token );
00131                 }
00132 
00133                 //move current string position
00134                 start = pos + 1;
00135         }
00136 
00137         //there still may be a dir at the end
00138         if( start < filename.length( ) ) {
00139                 token = filename.substr( start, filename.length( ) - start );
00140                 if( token == ".." ) {
00141                         //go back a dir, pop the stack
00142                         if( stack.size( ) > 0 ) {
00143                                 stack.pop_back( );
00144                         }
00145                 } else if( (token.length( ) > 0) && (token != ".") ) {
00146                         //place token on stack
00147                         stack.push_back( token );
00148                 }
00149         }
00150 
00151         //if the stack size is greater than one, see if the dir
00152         filename = "";
00153         if( stack.size( ) > 1 ) {
00154                 std::string old;
00155                 for( unsigned int i = 0; i < stack.size( ); ++i ) {
00156                         old = filename;
00157                         filename += "/" + stack[ i ];
00158                         if( !(utils::is_dir( filename.c_str( ) )) ) {
00159                                 //not a dir, go back to old as the last valid dir
00160                                 if( old.length( ) < 1 ) {
00161                                         return "/";
00162                                 } else {
00163                                         return old;
00164                                 }
00165                         }
00166                 }
00167                 
00168                 //the whole string was a dir
00169                 return filename;
00170         } else if( stack.size( ) == 1 ) {
00171                 //looks like the file looks like /filename
00172                 filename += "/" + stack[ 0 ];
00173                 if( utils::is_dir( filename.c_str( ) ) ) {
00174                         return filename;
00175                 } else {
00176                         return "/";
00177                 }
00178         } else {
00179                 //fuck, this shouldn't happen
00180                 return "";
00181         }
00182 }
00183 
00185 std::string
00186 utils::get_absolute_dir( const std::string& file )
00187 {
00188         //trim whitespace
00189         std::string filename = file;
00190         filename = utils::trim( utils::rtrim( filename ) );
00191 
00192         //make sure the string is not empty
00193         if( filename.length( ) < 1 ) return "";
00194         
00195         //is this file path absolute
00196         if( filename[ 0 ] != '/' ) {
00197                 //relative path, get cwd
00198                 char cwd[ 1024 ]; //hope this is enough
00199                 getcwd( cwd, 1024 );
00200 
00201                 //add relative path to full path
00202                 filename = std::string( cwd ) + "/" +  filename;
00203         }
00204 
00205         //create a stack
00206         std::vector<std::string> stack;
00207 
00208         //place dirs on stack
00209         std::string::size_type start = 0;
00210         std::string::size_type pos = 0;
00211         std::string token;
00212 
00213         //delimit by "/"
00214         while( (pos = filename.find_first_of( "/", start )) != std::string::npos ) {
00215                 token = filename.substr( start, pos - start );
00216                 if( token == ".." ) {
00217                         //go back a dir, pop the stack
00218                         if( stack.size( ) > 0 ) {
00219                                 stack.pop_back( );
00220                         }
00221                 } else if( (token.length( ) > 0) && (token != ".") ) {
00222                         //place token on stack
00223                         stack.push_back( token );
00224                 }
00225 
00226                 //move current string position
00227                 start = pos + 1;
00228         }
00229 
00230         //there still may be a dir at the end
00231         if( start < filename.length( ) ) {
00232                 token = filename.substr( start, filename.length( ) - start );
00233                 if( token == ".." ) {
00234                         //go back a dir, pop the stack
00235                         if( stack.size( ) > 0 ) {
00236                                 stack.pop_back( );
00237                         }
00238                 } else if( (token.length( ) > 0) && (token != ".") ) {
00239                         //place token on stack
00240                         stack.push_back( token );
00241                 }
00242         }
00243 
00244         filename = "";
00245         if( stack.size( ) > 1 ) {
00246                 for( unsigned int i = 0; i < stack.size( ) - 1; ++i ) {
00247                         filename += "/" + stack[ i ];
00248                 }
00249                 return filename;
00250         } else {
00251                 return "/";
00252         }
00253 }
00254 
00256 std::string
00257 utils::get_filename( const std::string& file )
00258 {
00259         std::string::size_type pos = file.find_last_of( "/", file.length( ) );
00260         if( pos == std::string::npos ) {
00261                 //no slashes
00262                 return file;
00263         } else {
00264                 return file.substr( pos + 1, file.length( ) - (pos + 1) );
00265         }
00266 }

Generated on Tue Feb 11 18:49:41 2003 for uber by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002