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_config.h>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/misc/strutils.hxx>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <direct.h>
|
# include <direct.h>
|
||||||
@@ -38,6 +40,7 @@
|
|||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using simgear::strutils::starts_with;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* define directory path separators
|
* define directory path separators
|
||||||
@@ -153,6 +156,14 @@ void SGPath::append( const string& p ) {
|
|||||||
_cached = false;
|
_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
|
//add a new path component to the existing path string
|
||||||
void SGPath::add( const string& p ) {
|
void SGPath::add( const string& p ) {
|
||||||
append( sgSearchPathSep+p );
|
append( sgSearchPathSep+p );
|
||||||
@@ -483,6 +494,94 @@ bool SGPath::rename(const SGPath& newName)
|
|||||||
return true;
|
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
|
std::string SGPath::realpath() const
|
||||||
{
|
{
|
||||||
#if (defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050)
|
#if (defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050)
|
||||||
|
|||||||
@@ -98,6 +98,13 @@ public:
|
|||||||
* @param p additional path component */
|
* @param p additional path component */
|
||||||
void append( const std::string& p );
|
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
|
* Append a new piece to the existing path. Inserts a search path
|
||||||
* separator to the existing path and the new patch component.
|
* 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
|
* or if the destination already exists, or is not writeable
|
||||||
*/
|
*/
|
||||||
bool rename(const SGPath& newName);
|
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:
|
private:
|
||||||
|
|
||||||
void fix();
|
void fix();
|
||||||
|
|||||||
Reference in New Issue
Block a user