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