00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <simgear/compiler.h>
00026
00027 #include <simgear_config.h>
00028 #include <simgear/debug/logstream.hxx>
00029 #include <stdio.h>
00030 #include <sys/stat.h>
00031 #include <sys/stat.h>
00032 #if defined( _MSC_VER) || defined(__MINGW32__)
00033 # include <direct.h>
00034 #endif
00035 #include "sg_path.hxx"
00036
00037
00042 #if defined( macintosh )
00043 static const char sgDirPathSep = ':';
00044 static const char sgDirPathSepBad = '/';
00045 #else
00046 static const char sgDirPathSep = '/';
00047 static const char sgDirPathSepBad = '\\';
00048 #endif
00049
00050 #if defined( WIN32 ) && !defined(__CYGWIN__)
00051 static const char sgSearchPathSep = ';';
00052 #else
00053 static const char sgSearchPathSep = ':';
00054 #endif
00055
00056
00057
00058
00059
00060
00061
00062 void
00063 SGPath::fix()
00064 {
00065 for ( string::size_type i = 0; i < path.size(); ++i ) {
00066 #if defined( WIN32 )
00067
00068 if ( i == 1 ) {
00069 continue;
00070 }
00071 #endif
00072 if ( path[i] == sgDirPathSepBad ) {
00073 path[i] = sgDirPathSep;
00074 }
00075 }
00076 }
00077
00078
00079
00080 SGPath::SGPath()
00081 : path("")
00082 {
00083 }
00084
00085
00086
00087 SGPath::SGPath( const std::string& p )
00088 : path(p)
00089 {
00090 fix();
00091 }
00092
00093
00094
00095 SGPath::~SGPath() {
00096 }
00097
00098
00099
00100 void SGPath::set( const string& p ) {
00101 path = p;
00102 fix();
00103 }
00104
00105
00106
00107 void SGPath::append( const string& p ) {
00108 if ( path.size() == 0 ) {
00109 path = p;
00110 } else {
00111 if ( p[0] != sgDirPathSep ) {
00112 path += sgDirPathSep;
00113 }
00114 path += p;
00115 }
00116 fix();
00117 }
00118
00119
00120 void SGPath::add( const string& p ) {
00121 append( sgSearchPathSep+p );
00122 }
00123
00124
00125
00126
00127 void SGPath::concat( const string& p ) {
00128 if ( path.size() == 0 ) {
00129 path = p;
00130 } else {
00131 path += p;
00132 }
00133 fix();
00134 }
00135
00136
00137
00138 string SGPath::file() const {
00139 int index = path.rfind(sgDirPathSep);
00140 if (index >= 0) {
00141 return path.substr(index + 1);
00142 } else {
00143 return "";
00144 }
00145 }
00146
00147
00148
00149 string SGPath::dir() const {
00150 int index = path.rfind(sgDirPathSep);
00151 if (index >= 0) {
00152 return path.substr(0, index);
00153 } else {
00154 return "";
00155 }
00156 }
00157
00158
00159 string SGPath::base() const {
00160 int index = path.rfind(".");
00161 if ((index >= 0) && (path.find("/", index) == string::npos)) {
00162 return path.substr(0, index);
00163 } else {
00164 return "";
00165 }
00166 }
00167
00168
00169
00170
00171 string SGPath::extension() const {
00172 int index = path.rfind(".");
00173 if ((index >= 0) && (path.find("/", index) == string::npos)) {
00174 return path.substr(index + 1);
00175 } else {
00176 return "";
00177 }
00178 }
00179
00180 bool SGPath::exists() const {
00181 FILE* fp = fopen( path.c_str(), "r");
00182 if (fp == 0) {
00183 return false;
00184 }
00185 fclose(fp);
00186 return true;
00187 }
00188
00189 #if defined( _MSC_VER) || defined(__MINGW32__)
00190 # define sgMkDir(d,m) _mkdir(d)
00191 #else
00192 # define sgMkDir(d,m) mkdir(d,m)
00193 #endif
00194
00195
00196 void SGPath::create_dir( mode_t mode ) {
00197 string_list dirlist = sgPathSplit(dir());
00198 if ( dirlist.empty() )
00199 return;
00200 string path = dirlist[0];
00201 string_list path_elements = sgPathBranchSplit(path);
00202 bool absolute = !path.empty() && path[0] == sgDirPathSep;
00203
00204 unsigned int i = 1;
00205 SGPath dir = absolute ? string( 1, sgDirPathSep ) : "";
00206 dir.concat( path_elements[0] );
00207 #if defined( _MSC_VER) || defined(__MINGW32__)
00208 if ( dir.str().find(':') != string::npos && path_elements.size() >= 2 ) {
00209 dir.append( path_elements[1] );
00210 i = 2;
00211 }
00212 #endif
00213 struct stat info;
00214 int r;
00215 for(; ( r = stat( dir.c_str(), &info ) ) == 0 && i < path_elements.size(); i++) {
00216 dir.append(path_elements[i]);
00217 }
00218 if ( r == 0 ) {
00219 return;
00220 }
00221 if ( sgMkDir( dir.c_str(), mode) ) {
00222 SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
00223 return;
00224 }
00225 for(;i < path_elements.size(); i++) {
00226 dir.append(path_elements[i]);
00227 if ( sgMkDir( dir.c_str(), mode) ) {
00228 SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
00229 break;
00230 }
00231 }
00232 }
00233
00234 string_list sgPathBranchSplit( const string &dirpath ) {
00235 string_list path_elements;
00236 string element, path = dirpath;
00237 while ( path.size() ) {
00238 size_t p = path.find( sgDirPathSep );
00239 if ( p != string::npos ) {
00240 element = path.substr( 0, p );
00241 path.erase( 0, p + 1 );
00242 } else {
00243 element = path;
00244 path = "";
00245 }
00246 if ( element.size() )
00247 path_elements.push_back( element );
00248 }
00249 return path_elements;
00250 }
00251
00252
00253 string_list sgPathSplit( const string &search_path ) {
00254 string tmp = search_path;
00255 string_list result;
00256 result.clear();
00257
00258 bool done = false;
00259
00260 while ( !done ) {
00261 int index = tmp.find(sgSearchPathSep);
00262 if (index >= 0) {
00263 result.push_back( tmp.substr(0, index) );
00264 tmp = tmp.substr( index + 1 );
00265 } else {
00266 if ( !tmp.empty() )
00267 result.push_back( tmp );
00268 done = true;
00269 }
00270 }
00271
00272 return result;
00273 }