Improved handling of directory for user configuration files to work even if $HOME/.config

does not exist, and moved handling of files and directories from user_config to file_manager.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4467 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-01-15 01:46:03 +00:00
parent def4c22a2b
commit 037069a257
7 changed files with 149 additions and 178 deletions

View File

@ -22,7 +22,6 @@
#define HEADER_SFX_HPP
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
class Vec3;

View File

@ -1,34 +1,42 @@
#include "config/player.hpp"
#include "karts/player_kart.hpp"
#include "race/race_manager.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
ActivePlayer::ActivePlayer(PlayerProfile* player, InputDevice *device)
{
m_player = player;
m_device = NULL;
setDevice(device);
}
} // ActivePlayer
// ----------------------------------------------------------------------------
ActivePlayer::~ActivePlayer()
{
setDevice(NULL);
}
} // ~ActivePlayer
// ----------------------------------------------------------------------------
PlayerProfile* ActivePlayer::getProfile()
{
return m_player;
}
} // getProfile
// ----------------------------------------------------------------------------
void ActivePlayer::setPlayerProfile(PlayerProfile* player)
{
m_player = player;
}
} // setPlayerProfile
// ----------------------------------------------------------------------------
InputDevice* ActivePlayer::getDevice() const
{
return m_device;
}
} // getDevice
// ----------------------------------------------------------------------------
void ActivePlayer::setDevice(InputDevice* device)
{
// unset player from previous device he was assigned to, if any
@ -38,8 +46,9 @@ void ActivePlayer::setDevice(InputDevice* device)
// inform the devce of its new owner
if (device != NULL) device->setPlayer(this);
}
} // setDevice
// ----------------------------------------------------------------------------
PlayerKart* ActivePlayer::getKart()
{
const int amount = RaceManager::getWorld()->getCurrentNumLocalPlayers();
@ -53,4 +62,4 @@ PlayerKart* ActivePlayer::getKart()
std::cout << "ActivePlayer::getKart() failed to find player named " << m_player->getName() << std::endl;
return NULL;
}
} // getKart

View File

@ -20,23 +20,15 @@
#include <stdio.h>
#include <stdexcept>
#include <sstream>
//#include <stdio.h>
//#include <stdexcept>
//#include <sstream>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <vector>
#include "utils/ptr_vector.hpp"
// for mkdir:
#if !defined(WIN32) || defined(__CYGWIN__)
# include <sys/stat.h>
# include <sys/types.h>
#else
# include <direct.h>
#endif
class UserConfigParam;
static ptr_vector<UserConfigParam, REF> all_params;
@ -331,24 +323,15 @@ UserConfig *user_config;
UserConfig::UserConfig()
{
setDefaults();
m_filename = "supertuxkart.cfg";
m_warning = "";
//m_blacklist_res.clear();
if(!loadConfig() || UserConfigParams::m_all_players.size() == 0)
{
addDefaultPlayer();
}
} // UserConfig
// -----------------------------------------------------------------------------
UserConfig::UserConfig(const std::string& filename)
{
setDefaults();
if(!loadConfig(filename) || UserConfigParams::m_all_players.size() == 0)
{
addDefaultPlayer();
}
} // UserConfig
// -----------------------------------------------------------------------------
UserConfig::~UserConfig()
{
@ -373,86 +356,10 @@ void UserConfig::addDefaultPlayer()
}
// -----------------------------------------------------------------------------
/**
* Load default values for options
*/
void UserConfig::setDefaults()
{
#ifdef WIN32
m_filename = file_manager->getLogFile("supertuxkart.cfg");
#else
m_filename = file_manager->getLogFile("config");
#endif
m_warning = "";
//m_blacklist_res.clear();
} // setDefaults
// -----------------------------------------------------------------------------
/**
* load default configuration file for this platform
*/
/** Load configuration values from file. */
bool UserConfig::loadConfig()
{
return loadConfig(m_filename);
} // loadConfig
// -----------------------------------------------------------------------------
/**
* Checks for existance of the STK configuration directory. If the
* directory does not exist, it will be created. Return values:
* 1: config dir exists
* 2: does not exist, but was created
* 0: does not exist, and could not be created.
*/
int UserConfig::CheckAndCreateDir()
{
// the standard C/C++ libraries don't include anything allowing to check
// for directory existance. I work around this by checking if trying to
// check for the config file (first reading, then writing)
const std::string filename = file_manager->getHomeDir() + "/config";
std::ofstream test(filename.c_str(), std::ios::in);
if(test.fail() || !test.is_open())
{
std::ofstream test2(filename.c_str(), std::ios::out);
if(test2.fail() || !test2.is_open())
{
int bError;
#if defined(WIN32) && !defined(__CYGWIN__)
bError = _mkdir(file_manager->getHomeDir().c_str() ) != 0;
#else
bError = mkdir(file_manager->getHomeDir().c_str(), 0755) != 0;
#endif
if(bError)
{
fprintf(stderr, "Couldn't create '%s', config files will not be saved.\n",
file_manager->getHomeDir().c_str());
return 0;
}
else
{
printf("Config directory '%s' successfully created.\n", file_manager->getHomeDir().c_str());
return 2;
}
}
if(test2.is_open()) test2.close();
}
if(test.is_open()) test.close();
return 1;
} // CheckAndCreateDir
// -----------------------------------------------------------------------------
/** Load configuration values from file. */
bool UserConfig::loadConfig(const std::string& filename)
{
const std::string filename = file_manager->getConfigDir()+"/"+m_filename;
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "stkconfig")
{
@ -530,26 +437,23 @@ bool UserConfig::loadConfig(const std::string& filename)
// -----------------------------------------------------------------------------
/** Write settings to config file. */
void UserConfig::saveConfig(const std::string& filepath)
void UserConfig::saveConfig()
{
const int DIR_EXIST = CheckAndCreateDir();
// Check if the config directory exists (again, since it was already checked
// when reading the config file - this is done in case that the problem was
// fixed while tuxkart is running). If the directory does not exist and
// can not be created, an error message was already printed to stderr,
// and we can exit here without any further messages.
if (DIR_EXIST == 0)
const std::string dir = file_manager->getConfigDir();
if(dir=="")
{
std::cerr << "User config firectory does not exist, cannot save config file!\n";
return;
}
const std::string filename = dir + "/" + m_filename;
std::ofstream configfile;
configfile.open (filepath.c_str());
configfile.open (filename.c_str());
if(!configfile.is_open())
{
std::cerr << "Failed to open " << filepath.c_str() << " for writing, user config won't be saved\n";
std::cerr << "Failed to open " << filename.c_str() << " for writing, user config won't be saved\n";
return;
}

View File

@ -285,30 +285,22 @@ class UserConfig
private:
/** Filename of the user config file. */
std::string m_filename;
void addDefaultPlayer ();
public:
std::string m_filename;
irr::core::stringw m_warning;
int CheckAndCreateDir();
UserConfig();
UserConfig(const std::string& filename);
~UserConfig();
void setDefaults();
void addDefaultPlayer();
public:
UserConfig();
~UserConfig();
bool loadConfig();
bool loadConfig(const std::string& filename);
void saveConfig() { saveConfig(m_filename); }
void saveConfig(const std::string& filename);
void saveConfig();
const irr::core::stringw& getWarning() { return m_warning; }
void resetWarning() { m_warning=""; }
void setWarning(irr::core::stringw& warning) { m_warning=warning; }
};
}; // UserConfig
extern UserConfig *user_config;

View File

@ -297,7 +297,7 @@ InputDevice* DeviceManager::getLatestUsedDevice()
// -----------------------------------------------------------------------------
bool DeviceManager::deserialize()
{
static std::string filepath = file_manager->getHomeDir() + "/input.config";
static std::string filepath = file_manager->getConfigDir() + "/input.config";
printf("Deserializing input.config...\n");
@ -394,8 +394,7 @@ bool DeviceManager::deserialize()
// -----------------------------------------------------------------------------
void DeviceManager::serialize()
{
static std::string filepath = file_manager->getHomeDir() + "/input.config";
user_config->CheckAndCreateDir();
static std::string filepath = file_manager->getConfigDir() + "/input.config";
printf("Serializing input.config...\n");

View File

@ -20,11 +20,22 @@
#include "io/file_manager.hpp"
#include <stdio.h>
#include <stdexcept>
#include <sstream>
#include <sys/stat.h>
#include <iostream>
#include <string>
// For mkdir
#if !defined(WIN32) || defined(__CYGWIN__)
# include <sys/stat.h>
# include <sys/types.h>
#else
# include <direct.h>
#endif
#ifdef WIN32
# include <io.h>
# include <stdio.h>
@ -36,7 +47,6 @@
# include <unistd.h>
#endif
#define CONFIGDIR "supertuxkart"
#include "irrlicht.h"
#include "btBulletDynamicsCommon.h"
@ -142,7 +152,7 @@ FileManager::FileManager(char *argv[])
// after the filemanager (to get the path to the tranlsations from it)
fprintf(stderr, "Data files will be fetched from: '%s'\n",
m_root_dir.c_str() );
checkAndCreateConfigDir();
} // FileManager
//-----------------------------------------------------------------------------
@ -349,53 +359,107 @@ std::string FileManager::getItemFile(const std::string& fname) const
} // getConfigFile
//-----------------------------------------------------------------------------
std::string FileManager::getHomeDir() const
/** If the directory specified in path does not exist, it is created.
* /params path Directory to test.
* /return True if the directory exists or could be created, false otherwise.
*/
bool FileManager::checkAndCreateDirectory(const std::string &path)
{
io::path p=m_file_system->getWorkingDirectory();
// irrlicht apparently returns true for files and directory
// (using access/_access internally):
if(m_file_system->existFile(io::path(path.c_str())))
return true;
// Otherwise try to create the directory:
#if defined(WIN32) && !defined(__CYGWIN__)
bool error = _mkdir(path.c_str()) != 0;
#else
bool error = mkdir(path.c_str(), 0755) != 0;
#endif
return !error;
} // checkAndCreateDirectory
//-----------------------------------------------------------------------------
/** Checks if the config directory exists, and it not, tries to create it. */
void FileManager::checkAndCreateConfigDir()
{
std::string DIRNAME;
#ifdef WIN32
// Try to use the APPDATA directory to store config files and highscore
// lists. If not defined, used the current directory.
std::ostringstream s;
if(getenv("APPDATA")!=NULL)
{
s<<getenv("APPDATA")<<"/"<<CONFIGDIR<<"/";
DIRNAME=s.str();
m_config_dir = getenv("APPDATA");
if(!checkAndCreateDirectory(m_config_dir))
{
fprintf(stderr, "Can't create config dir '%s', falling back to '.'.\n",
m_config_dir.c_str());
m_config_dir = ".";
}
}
else DIRNAME=".";
#endif
#ifdef linux
// Use new standards for config directory
if (getenv("XDG_CONFIG_HOME")!=NULL){
DIRNAME = getenv("XDG_CONFIG_HOME");
}else if (getenv("HOME")!=NULL){
DIRNAME = getenv("HOME");
DIRNAME += "/.config";
}else{
std::cerr << "No home directory, this should NOT happen!\n";
// This is what was here before, it looks rather questionable.
DIRNAME=".";
}
DIRNAME += "/";
DIRNAME += CONFIGDIR;
#endif
#ifdef __APPLE__
if (getenv("HOME")!=NULL){
DIRNAME = getenv("HOME");
}else{
else
m_config_dir = ".";
#else
# ifdef __APPLE__
if (getenv("HOME")!=NULL)
{
m_config_dir = getenv("HOME");
}
else
{
std::cerr << "No home directory, this should NOT happen!\n";
// Fall back to system-wide app data (rather than user-specific data), but should not happen anyway.
DIRNAME = "";
m_config_dir = "";
}
DIRNAME += "/Library/Application Support/";
DIRNAME += CONFIGDIR;
m_config_dir += "/Library/Application Support/";
# else
// Remaining unix variants. Use the new standards for config directory
// i.e. either XDG_CONFIG_HOME or $HOME/.config
if (getenv("XDG_CONFIG_HOME")!=NULL){
m_config_dir = getenv("XDG_CONFIG_HOME");
}
else if (!getenv("HOME"))
{
std::cerr << "No home directory, this should NOT happen - trying '.' for config files!\n";
m_config_dir = ".";
}
else
{
m_config_dir = getenv("HOME");
m_config_dir += "/.config";
if(!checkAndCreateDirectory(m_config_dir))
{
// If $HOME/.config can not be created:
fprintf(stderr, "Can't create dir '%s', falling back to use '%s'.\n",
m_config_dir.c_str(), getenv("HOME"));
m_config_dir = getenv("HOME");
}
}
# endif
#endif
return DIRNAME;
} // getHomeDir
const std::string CONFIGDIR("supertuxkart");
m_config_dir += "/";
m_config_dir += CONFIGDIR;
if(!checkAndCreateDirectory(m_config_dir))
{
fprintf(stderr, "Can not create config dir '%s', falling back to '.'.\n",
m_config_dir.c_str());
m_config_dir = ".";
}
return;
} // checkAndCreateConfigDir
//-----------------------------------------------------------------------------
std::string FileManager::getConfigDir() const
{
return m_config_dir;
} // getConfigDir
//-----------------------------------------------------------------------------
std::string FileManager::getLogFile(const std::string& fname) const
{
return getHomeDir()+"/"+fname;
return getConfigDir()+"/"+fname;
} // getLogFile
//-----------------------------------------------------------------------------
@ -419,14 +483,14 @@ std::string FileManager::getFontFile(const std::string& fname) const
//-----------------------------------------------------------------------------
std::string FileManager::getHighscoreFile(const std::string& fname) const
{
return getHomeDir()+"/"+fname;
return getConfigDir()+"/"+fname;
} // getHighscoreFile
//-----------------------------------------------------------------------------
/** Returns the full path of the challenge file. */
std::string FileManager::getChallengeFile(const std::string &fname) const
{
return getHomeDir()+"/"+fname;
return getConfigDir()+"/"+fname;
} // getChallengeFile
//-----------------------------------------------------------------------------

View File

@ -40,6 +40,9 @@ private:
IrrlichtDevice *m_device;
bool m_is_full_path;
/** Directory where user config files are stored. */
std::string m_config_dir;
/** Root data directory. */
std::string m_root_dir;
std::vector<std::string> m_texture_search_path,
m_model_search_path,
@ -50,8 +53,9 @@ private:
const;
void makePath (std::string& path, const std::string& dir,
const std::string& fname) const;
io::path createAbsoluteFilename(const std::string &f);
bool checkAndCreateDirectory(const std::string &path);
io::path createAbsoluteFilename(const std::string &f);
void checkAndCreateConfigDir();
public:
FileManager(char *argv[]);
~FileManager();
@ -60,7 +64,7 @@ public:
io::IXMLReader *createXMLReader(const std::string &filename);
XMLNode *createXMLTree(const std::string &filename);
std::string getHomeDir () const;
std::string getConfigDir () const;
std::string getKartDir () const;
std::string getDataDir () const;
std::string getItemsDir () const;