]> git.mxchange.org Git - simgear.git/commitdiff
SGPath: new helpers and static members for home and desktop path
authorThomas Geymayer <tomgey@gmail.com>
Mon, 10 Jun 2013 19:37:00 +0000 (21:37 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Mon, 10 Jun 2013 19:37:00 +0000 (21:37 +0200)
simgear/misc/sg_path.cxx
simgear/misc/sg_path.hxx

index 7db261da67e6314cb56119ad2218f7a267b91080..9267cedf6a1c6971cc76d28ca1bb8d415579f290 100644 (file)
 
 #include <simgear_config.h>
 #include <simgear/debug/logstream.hxx>
+#include <simgear/misc/strutils.hxx>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <fstream>
 
 #ifdef _WIN32
 #  include <direct.h>
@@ -38,6 +40,7 @@
 #include <boost/algorithm/string/case_conv.hpp>
 
 using std::string;
+using simgear::strutils::starts_with;
 
 /**
  * define directory path separators
@@ -153,6 +156,14 @@ void SGPath::append( const string& p ) {
     _cached = false;
 }
 
+//------------------------------------------------------------------------------
+SGPath SGPath::operator/( const std::string& p ) const
+{
+  SGPath ret = *this;
+  ret.append(p);
+  return ret;
+}
+
 //add a new path component to the existing path string
 void SGPath::add( const string& p ) {
     append( sgSearchPathSep+p );
@@ -483,6 +494,94 @@ bool SGPath::rename(const SGPath& newName)
     return true;
 }
 
+//------------------------------------------------------------------------------
+SGPath SGPath::fromEnv(const char* name, const SGPath& def)
+{
+  const char* val = getenv(name);
+  if( val && val[0] )
+    return SGPath(val);
+  return def;
+}
+
+#ifdef _WIN32
+//------------------------------------------------------------------------------
+SGPath SGPath::home()
+{
+  // TODO
+  return SGPath();
+}
+#else
+//------------------------------------------------------------------------------
+SGPath SGPath::home()
+{
+  return fromEnv("HOME");
+}
+#endif
+
+#ifdef _WIN32
+//------------------------------------------------------------------------------
+SGPath SGPath::desktop()
+{
+  // TODO
+  return SGPath();
+}
+#elif __APPLE__
+#include <CoreServices/CoreServices.h>
+
+//------------------------------------------------------------------------------
+SGPath SGPath::desktop()
+{
+  FSRef ref;
+  OSErr err = FSFindFolder(kUserDomain, kDesktopFolderType, false, &ref);
+  if (err) {
+    return SGPath();
+  }
+
+  unsigned char path[1024];
+  if (FSRefMakePath(&ref, path, 1024) != noErr) {
+    return SGPath();
+  }
+
+  return SGPath((const char*) path);
+}
+#else
+//------------------------------------------------------------------------------
+SGPath SGPath::desktop()
+{
+  // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+  // $XDG_CONFIG_HOME defines the base directory relative to which user specific
+  // configuration files should be stored. If $XDG_CONFIG_HOME is either not set
+  // or empty, a default equal to $HOME/.config should be used.
+  const SGPath user_dirs = fromEnv("XDG_CONFIG_HOME", home() / ".config")
+                         / "user-dirs.dirs";
+
+  // Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
+  // homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an absolute
+  // path. No other format is supported.
+  const std::string DESKTOP = "XDG_DESKTOP_DIR=\"";
+
+  std::ifstream user_dirs_file( user_dirs.c_str() );
+  std::string line;
+  while( std::getline(user_dirs_file, line).good() )
+  {
+    if( !starts_with(line, DESKTOP) || *line.rbegin() != '"' )
+      continue;
+
+    // Extract dir from XDG_DESKTOP_DIR="<dir>"
+    line = line.substr(DESKTOP.length(), line.length() - DESKTOP.length() - 1 );
+
+    const std::string HOME = "$HOME";
+    if( starts_with(line, HOME) )
+      return home() / simgear::strutils::unescape(line.substr(HOME.length()));
+
+    return SGPath(line);
+  }
+
+  return home() / "Desktop";
+}
+#endif
+
 std::string SGPath::realpath() const
 {
 #if (defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050)
index 1f9dfbe706c4d3a0d663001e4d977d5446be907a..bd27694f0dc6f5b6f53893f60cb06f4f92b9c7b0 100644 (file)
@@ -98,6 +98,13 @@ public:
      * @param p additional path component */
     void append( const std::string& p );
 
+    /**
+     * Get a copy of this path with another piece appended.
+     *
+     * @param p additional path component
+     */
+    SGPath operator/( const std::string& p ) const;
+
     /**
      * Append a new piece to the existing path.  Inserts a search path
      * separator to the existing path and the new patch component.
@@ -226,6 +233,26 @@ public:
      * or if the destination already exists, or is not writeable
      */
     bool rename(const SGPath& newName);
+
+    /**
+     * Get a path stored in the environment variable with the given \a name.
+     *
+     * @param name  Name of the environment variable
+     * @param def   Default path to return if the environment variable does not
+     *              exist or is empty.
+     */
+    static SGPath fromEnv(const char* name, const SGPath& def = SGPath());
+
+    /**
+     * Get path to user's home directory
+     */
+    static SGPath home();
+
+    /**
+     * Get path to the user's desktop directory
+     */
+    static SGPath desktop();
+
 private:
 
     void fix();