#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>
#include <boost/algorithm/string/case_conv.hpp>
using std::string;
+using simgear::strutils::starts_with;
/**
* define directory path separators
_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 );
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)
* @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.
* 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();