SGPath: new helpers and static members for home and desktop path
This commit is contained in:
@@ -26,9 +26,11 @@
|
||||
|
||||
#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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user