]> git.mxchange.org Git - simgear.git/commitdiff
Quick hack to remote trailing / on Windows. Feel free to replace by something more...
authorFrederic Bouvier <fredfgfs01@free.fr>
Fri, 29 Oct 2010 07:30:59 +0000 (09:30 +0200)
committerFrederic Bouvier <fredfgfs01@free.fr>
Fri, 29 Oct 2010 07:30:59 +0000 (09:30 +0200)
simgear/misc/sg_path.cxx

index 73475b0c6d73654f6732e477bede035db156a30d..fde4903a6e1716d85a15a745a9cd51e1ffdca070 100644 (file)
-// sg_path.cxx -- routines to abstract out path separator differences
-//               between MacOS and the rest of the world
-//
-// Written by Curtis L. Olson, started April 1999.
-//
-// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
-
-
-#include <simgear/compiler.h>
-
-#include <simgear_config.h>
-#include <simgear/debug/logstream.hxx>
-#include <stdio.h>
-#include <sys/stat.h>
-#ifdef _WIN32
-#  include <direct.h>
-#endif
-#include "sg_path.hxx"
-
-using std::string;
-
-
-/**
- * define directory path separators
- */
-
-static const char sgDirPathSep = '/';
-static const char sgDirPathSepBad = '\\';
-
-#ifdef _WIN32
-static const char sgSearchPathSep = ';';
-#else
-static const char sgSearchPathSep = ':';
-#endif
-
-
-// If Unix, replace all ":" with "/".  In windoze, allow the
-// second character to be a ":" for things like c:\foo\bar
-
-void
-SGPath::fix()
-{
-    for ( string::size_type i = 0; i < path.size(); ++i ) {
-#if defined( WIN32 )
-       // for windoze, don't replace the ":" for the second character
-       if ( i == 1 ) {
-           continue;
-       }
-#endif
-       if ( path[i] == sgDirPathSepBad ) {
-           path[i] = sgDirPathSep;
-       }
-    }
-}
-
-
-// default constructor
-SGPath::SGPath()
-    : path(""),
-    _cached(false)
-{
-}
-
-
-// create a path based on "path"
-SGPath::SGPath( const std::string& p )
-    : path(p),
-    _cached(false)
-{
-    fix();
-}
-
-// create a path based on "path" and a "subpath"
-SGPath::SGPath( const SGPath& p, const std::string& r )
-    : path(p.path),
-    _cached(false)
-{
-    append(r);
-    fix();
-}
-
-SGPath::SGPath(const SGPath& p) :
-  path(p.path),
-  _cached(p._cached),
-  _exists(p._exists),
-  _isDir(p._isDir),
-  _isFile(p._isFile)
-{
-}
-    
-SGPath& SGPath::operator=(const SGPath& p)
-{
-  path = p.path;
-  _cached = p._cached;
-  _exists = p._exists;
-  _isDir = p._isDir;
-  _isFile = p._isFile;
-  return *this;
-}
-
-// destructor
-SGPath::~SGPath() {
-}
-
-
-// set path
-void SGPath::set( const string& p ) {
-    path = p;
-    fix();
-    _cached = false;
-}
-
-
-// append another piece to the existing path
-void SGPath::append( const string& p ) {
-    if ( path.size() == 0 ) {
-       path = p;
-    } else {
-       if ( p[0] != sgDirPathSep ) {
-           path += sgDirPathSep;
-       }
-       path += p;
-    }
-    fix();
-    _cached = false;
-}
-
-//add a new path component to the existing path string
-void SGPath::add( const string& p ) {
-    append( sgSearchPathSep+p );
-}
-
-
-// concatenate a string to the end of the path without inserting a
-// path separator
-void SGPath::concat( const string& p ) {
-    if ( path.size() == 0 ) {
-       path = p;
-    } else {
-       path += p;
-    }
-    fix();
-    _cached = false;
-}
-
-
-// Get the file part of the path (everything after the last path sep)
-string SGPath::file() const {
-    int index = path.rfind(sgDirPathSep);
-    if (index >= 0) {
-       return path.substr(index + 1);
-    } else {
-       return "";
-    }
-}
-  
-
-// get the directory part of the path.
-string SGPath::dir() const {
-    int index = path.rfind(sgDirPathSep);
-    if (index >= 0) {
-       return path.substr(0, index);
-    } else {
-       return "";
-    }
-}
-
-// get the base part of the path (everything but the extension.)
-string SGPath::base() const {
-    int index = path.rfind(".");
-    if ((index >= 0) && (path.find("/", index) == string::npos)) {
-       return path.substr(0, index);
-    } else {
-       return "";
-    }
-}
-
-// get the extension (everything after the final ".")
-// but make sure no "/" follows the "." character (otherwise it
-// is has to be a directory name containing a ".").
-string SGPath::extension() const {
-    int index = path.rfind(".");
-    if ((index >= 0)  && (path.find("/", index) == string::npos)) {
-       return path.substr(index + 1);
-    } else {
-       return "";
-    }
-}
-
-void SGPath::validate() const
-{
-  if (_cached) {
-    return;
-  }
-  
-#ifdef _WIN32
-  struct _stat buf ;
-
-  if (_stat (path.c_str(), &buf ) < 0) {
-    _exists = false;
-  } else {
-    _exists = true;
-    _isFile = ((S_IFREG & buf.st_mode ) !=0);
-    _isDir = ((S_IFDIR & buf.st_mode ) !=0);
-  }
-
-#else
-  struct stat buf ;
-
-  if (stat(path.c_str(), &buf ) < 0) {
-    _exists = false;
-  } else {
-    _exists = true;
-    _isFile = ((S_ISREG(buf.st_mode )) != 0);
-    _isDir = ((S_ISDIR(buf.st_mode )) != 0);
-  }
-  
-#endif
-  _cached = true;
-}
-
-bool SGPath::exists() const
-{
-  validate();
-  return _exists;
-}
-
-bool SGPath::isDir() const
-{
-  validate();
-  return _exists && _isDir;
-}
-
-bool SGPath::isFile() const
-{
-  validate();
-  return _exists && _isFile;
-}
-
-#ifdef _WIN32
-#  define sgMkDir(d,m)       _mkdir(d)
-#else
-#  define sgMkDir(d,m)       mkdir(d,m)
-#endif
-
-
-int SGPath::create_dir( mode_t mode ) {
-    string_list dirlist = sgPathSplit(dir());
-    if ( dirlist.empty() )
-        return -1;
-    string path = dirlist[0];
-    string_list path_elements = sgPathBranchSplit(path);
-    bool absolute = !path.empty() && path[0] == sgDirPathSep;
-
-    unsigned int i = 1;
-    SGPath dir = absolute ? string( 1, sgDirPathSep ) : "";
-    dir.concat( path_elements[0] );
-#ifdef _WIN32
-    if ( dir.str().find(':') != string::npos && path_elements.size() >= 2 ) {
-        dir.append( path_elements[1] );
-        i = 2;
-    }
-#endif
-    struct stat info;
-    int r;
-    for(; ( r = stat( dir.c_str(), &info ) ) == 0 && i < path_elements.size(); i++) {
-        dir.append(path_elements[i]);
-    }
-    if ( r == 0 ) {
-        return 0; // Directory already exists
-    }
-    if ( sgMkDir( dir.c_str(), mode) ) {
-        SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
-        return -2;
-    }
-    for(; i < path_elements.size(); i++) {
-        dir.append(path_elements[i]);
-        if ( sgMkDir( dir.c_str(), mode) ) {
-            SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
-            return -2;
-        }
-    }
-
-    return 0;
-}
-
-string_list sgPathBranchSplit( const string &dirpath ) {
-    string_list path_elements;
-    string element, path = dirpath;
-    while ( path.size() ) {
-        size_t p = path.find( sgDirPathSep );
-        if ( p != string::npos ) {
-            element = path.substr( 0, p );
-            path.erase( 0, p + 1 );
-        } else {
-            element = path;
-            path = "";
-        }
-        if ( element.size() )
-            path_elements.push_back( element );
-    }
-    return path_elements;
-}
-
-
-string_list sgPathSplit( const string &search_path ) {
-    string tmp = search_path;
-    string_list result;
-    result.clear();
-
-    bool done = false;
-
-    while ( !done ) {
-        int index = tmp.find(sgSearchPathSep);
-        if (index >= 0) {
-            result.push_back( tmp.substr(0, index) );
-            tmp = tmp.substr( index + 1 );
-        } else {
-            if ( !tmp.empty() )
-                result.push_back( tmp );
-            done = true;
-        }
-    }
-
-    return result;
-}
-
-bool SGPath::isAbsolute() const
-{
-  if (path.empty()) {
-    return false;
-  }
-  
-#ifdef _WIN32
-  // detect '[A-Za-z]:/'
-  if (path.size() > 2) {
-    if (isalpha(path[0]) && (path[1] == ':') && (path[2] == sgDirPathSep)) {
-      return true;
-    }
-  }
-#endif
-  
-  return (path[0] == sgDirPathSep);
-}
-
-bool SGPath::isNull() const
-{
-  return path.empty() || (path == "");
-}
+// sg_path.cxx -- routines to abstract out path separator differences\r
+//               between MacOS and the rest of the world\r
+//\r
+// Written by Curtis L. Olson, started April 1999.\r
+//\r
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt\r
+//\r
+// This library is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU Library General Public\r
+// License as published by the Free Software Foundation; either\r
+// version 2 of the License, or (at your option) any later version.\r
+//\r
+// This library is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+// Library General Public License for more details.\r
+//\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software\r
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+//\r
+// $Id$\r
+\r
+\r
+#include <simgear/compiler.h>\r
+\r
+#include <simgear_config.h>\r
+#include <simgear/debug/logstream.hxx>\r
+#include <stdio.h>\r
+#include <sys/stat.h>\r
+#ifdef _WIN32\r
+#  include <direct.h>\r
+#endif\r
+#include "sg_path.hxx"\r
+\r
+using std::string;\r
+\r
+\r
+/**\r
+ * define directory path separators\r
+ */\r
+\r
+static const char sgDirPathSep = '/';\r
+static const char sgDirPathSepBad = '\\';\r
+\r
+#ifdef _WIN32\r
+static const char sgSearchPathSep = ';';\r
+#else\r
+static const char sgSearchPathSep = ':';\r
+#endif\r
+\r
+\r
+// If Unix, replace all ":" with "/".  In windoze, allow the\r
+// second character to be a ":" for things like c:\foo\bar\r
+\r
+void\r
+SGPath::fix()\r
+{\r
+    for ( string::size_type i = 0; i < path.size(); ++i ) {\r
+#if defined( WIN32 )\r
+       // for windoze, don't replace the ":" for the second character\r
+       if ( i == 1 ) {\r
+           continue;\r
+       }\r
+#endif\r
+       if ( path[i] == sgDirPathSepBad ) {\r
+           path[i] = sgDirPathSep;\r
+       }\r
+    }\r
+}\r
+\r
+\r
+// default constructor\r
+SGPath::SGPath()\r
+    : path(""),\r
+    _cached(false)\r
+{\r
+}\r
+\r
+\r
+// create a path based on "path"\r
+SGPath::SGPath( const std::string& p )\r
+    : path(p),\r
+    _cached(false)\r
+{\r
+    fix();\r
+}\r
+\r
+// create a path based on "path" and a "subpath"\r
+SGPath::SGPath( const SGPath& p, const std::string& r )\r
+    : path(p.path),\r
+    _cached(false)\r
+{\r
+    append(r);\r
+    fix();\r
+}\r
+\r
+SGPath::SGPath(const SGPath& p) :\r
+  path(p.path),\r
+  _cached(p._cached),\r
+  _exists(p._exists),\r
+  _isDir(p._isDir),\r
+  _isFile(p._isFile)\r
+{\r
+}\r
+    \r
+SGPath& SGPath::operator=(const SGPath& p)\r
+{\r
+  path = p.path;\r
+  _cached = p._cached;\r
+  _exists = p._exists;\r
+  _isDir = p._isDir;\r
+  _isFile = p._isFile;\r
+  return *this;\r
+}\r
+\r
+// destructor\r
+SGPath::~SGPath() {\r
+}\r
+\r
+\r
+// set path\r
+void SGPath::set( const string& p ) {\r
+    path = p;\r
+    fix();\r
+    _cached = false;\r
+}\r
+\r
+\r
+// append another piece to the existing path\r
+void SGPath::append( const string& p ) {\r
+    if ( path.size() == 0 ) {\r
+       path = p;\r
+    } else {\r
+       if ( p[0] != sgDirPathSep ) {\r
+           path += sgDirPathSep;\r
+       }\r
+       path += p;\r
+    }\r
+    fix();\r
+    _cached = false;\r
+}\r
+\r
+//add a new path component to the existing path string\r
+void SGPath::add( const string& p ) {\r
+    append( sgSearchPathSep+p );\r
+}\r
+\r
+\r
+// concatenate a string to the end of the path without inserting a\r
+// path separator\r
+void SGPath::concat( const string& p ) {\r
+    if ( path.size() == 0 ) {\r
+       path = p;\r
+    } else {\r
+       path += p;\r
+    }\r
+    fix();\r
+    _cached = false;\r
+}\r
+\r
+\r
+// Get the file part of the path (everything after the last path sep)\r
+string SGPath::file() const {\r
+    int index = path.rfind(sgDirPathSep);\r
+    if (index >= 0) {\r
+       return path.substr(index + 1);\r
+    } else {\r
+       return "";\r
+    }\r
+}\r
+  \r
+\r
+// get the directory part of the path.\r
+string SGPath::dir() const {\r
+    int index = path.rfind(sgDirPathSep);\r
+    if (index >= 0) {\r
+       return path.substr(0, index);\r
+    } else {\r
+       return "";\r
+    }\r
+}\r
+\r
+// get the base part of the path (everything but the extension.)\r
+string SGPath::base() const {\r
+    int index = path.rfind(".");\r
+    if ((index >= 0) && (path.find("/", index) == string::npos)) {\r
+       return path.substr(0, index);\r
+    } else {\r
+       return "";\r
+    }\r
+}\r
+\r
+// get the extension (everything after the final ".")\r
+// but make sure no "/" follows the "." character (otherwise it\r
+// is has to be a directory name containing a ".").\r
+string SGPath::extension() const {\r
+    int index = path.rfind(".");\r
+    if ((index >= 0)  && (path.find("/", index) == string::npos)) {\r
+       return path.substr(index + 1);\r
+    } else {\r
+       return "";\r
+    }\r
+}\r
+\r
+void SGPath::validate() const\r
+{\r
+  if (_cached) {\r
+    return;\r
+  }\r
+  \r
+#ifdef _WIN32\r
+  struct _stat buf ;\r
+\r
+  bool remove_trailing = false;\r
+  if ( path.length() > 1 && path[path.length()-1] == '/' )\r
+      remove_trailing=true;\r
+  if (_stat (path.substr(0,remove_trailing?path.length()-1:path.length()).c_str(), &buf ) < 0) {\r
+    _exists = false;\r
+  } else {\r
+    _exists = true;\r
+    _isFile = ((S_IFREG & buf.st_mode ) !=0);\r
+    _isDir = ((S_IFDIR & buf.st_mode ) !=0);\r
+  }\r
+\r
+#else\r
+  struct stat buf ;\r
+\r
+  if (stat(path.c_str(), &buf ) < 0) {\r
+    _exists = false;\r
+  } else {\r
+    _exists = true;\r
+    _isFile = ((S_ISREG(buf.st_mode )) != 0);\r
+    _isDir = ((S_ISDIR(buf.st_mode )) != 0);\r
+  }\r
+  \r
+#endif\r
+  _cached = true;\r
+}\r
+\r
+bool SGPath::exists() const\r
+{\r
+  validate();\r
+  return _exists;\r
+}\r
+\r
+bool SGPath::isDir() const\r
+{\r
+  validate();\r
+  return _exists && _isDir;\r
+}\r
+\r
+bool SGPath::isFile() const\r
+{\r
+  validate();\r
+  return _exists && _isFile;\r
+}\r
+\r
+#ifdef _WIN32\r
+#  define sgMkDir(d,m)       _mkdir(d)\r
+#else\r
+#  define sgMkDir(d,m)       mkdir(d,m)\r
+#endif\r
+\r
+\r
+int SGPath::create_dir( mode_t mode ) {\r
+    string_list dirlist = sgPathSplit(dir());\r
+    if ( dirlist.empty() )\r
+        return -1;\r
+    string path = dirlist[0];\r
+    string_list path_elements = sgPathBranchSplit(path);\r
+    bool absolute = !path.empty() && path[0] == sgDirPathSep;\r
+\r
+    unsigned int i = 1;\r
+    SGPath dir = absolute ? string( 1, sgDirPathSep ) : "";\r
+    dir.concat( path_elements[0] );\r
+#ifdef _WIN32\r
+    if ( dir.str().find(':') != string::npos && path_elements.size() >= 2 ) {\r
+        dir.append( path_elements[1] );\r
+        i = 2;\r
+    }\r
+#endif\r
+    struct stat info;\r
+    int r;\r
+    for(; ( r = stat( dir.c_str(), &info ) ) == 0 && i < path_elements.size(); i++) {\r
+        dir.append(path_elements[i]);\r
+    }\r
+    if ( r == 0 ) {\r
+        return 0; // Directory already exists\r
+    }\r
+    if ( sgMkDir( dir.c_str(), mode) ) {\r
+        SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );\r
+        return -2;\r
+    }\r
+    for(; i < path_elements.size(); i++) {\r
+        dir.append(path_elements[i]);\r
+        if ( sgMkDir( dir.c_str(), mode) ) {\r
+            SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );\r
+            return -2;\r
+        }\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+string_list sgPathBranchSplit( const string &dirpath ) {\r
+    string_list path_elements;\r
+    string element, path = dirpath;\r
+    while ( path.size() ) {\r
+        size_t p = path.find( sgDirPathSep );\r
+        if ( p != string::npos ) {\r
+            element = path.substr( 0, p );\r
+            path.erase( 0, p + 1 );\r
+        } else {\r
+            element = path;\r
+            path = "";\r
+        }\r
+        if ( element.size() )\r
+            path_elements.push_back( element );\r
+    }\r
+    return path_elements;\r
+}\r
+\r
+\r
+string_list sgPathSplit( const string &search_path ) {\r
+    string tmp = search_path;\r
+    string_list result;\r
+    result.clear();\r
+\r
+    bool done = false;\r
+\r
+    while ( !done ) {\r
+        int index = tmp.find(sgSearchPathSep);\r
+        if (index >= 0) {\r
+            result.push_back( tmp.substr(0, index) );\r
+            tmp = tmp.substr( index + 1 );\r
+        } else {\r
+            if ( !tmp.empty() )\r
+                result.push_back( tmp );\r
+            done = true;\r
+        }\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+bool SGPath::isAbsolute() const\r
+{\r
+  if (path.empty()) {\r
+    return false;\r
+  }\r
+  \r
+#ifdef _WIN32\r
+  // detect '[A-Za-z]:/'\r
+  if (path.size() > 2) {\r
+    if (isalpha(path[0]) && (path[1] == ':') && (path[2] == sgDirPathSep)) {\r
+      return true;\r
+    }\r
+  }\r
+#endif\r
+  \r
+  return (path[0] == sgDirPathSep);\r
+}\r
+\r
+bool SGPath::isNull() const\r
+{\r
+  return path.empty() || (path == "");\r
+}\r