Issue #168 - Configuration cleanup

Added tokens processing, modified getInstallPath for linux
so we could use ~/.wine/dosdevices symlinks.

Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
actorid
Lukasz Gromanowski 13 years ago
parent 841bdded76
commit 1d96b99532

@ -157,6 +157,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.enableFSStrict(variables["fs-strict"].as<bool>());
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
cfgMgr.processPaths(dataDirs);
std::string local(variables["data-local"].as<std::string>());
if (!local.empty())
@ -166,7 +167,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
if (dataDirs.empty())
{
dataDirs.push_back(cfgMgr.getDataPath(Files::localDataToken));
dataDirs.push_back(cfgMgr.getLocalDataPath());
}
engine.setDataDirs(dataDirs);

@ -3,7 +3,7 @@
#include <string>
#include <fstream>
#include <iostream>
#include <functional>
#include <algorithm>
namespace Files
{
@ -24,7 +24,7 @@ ConfigurationManager::ConfigurationManager()
/**
* According to task #168 plugins.cfg file shall be located in global
* configuration path or in runtime configuration path.
* configuration path or in local configuration path.
*/
mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile;
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
@ -55,10 +55,10 @@ ConfigurationManager::~ConfigurationManager()
void ConfigurationManager::setupTokensMapping()
{
mTokensMapping.insert(std::make_pair(mwDataToken, &FixedPath<>::getInstallPath));
mTokensMapping.insert(std::make_pair(localDataToken, &FixedPath<>::getLocalDataPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::getUserDataPath));
mTokensMapping.insert(std::make_pair(globalDataToken, &FixedPath<>::getGlobalDataPath));
mTokensMapping.insert(std::make_pair(mwDataToken, &FixedPath<>::setInstallPath));
mTokensMapping.insert(std::make_pair(localDataToken, &FixedPath<>::setLocalDataPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::setUserDataPath));
mTokensMapping.insert(std::make_pair(globalDataToken, &FixedPath<>::setGlobalDataPath));
}
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables,
@ -66,10 +66,54 @@ void ConfigurationManager::readConfiguration(boost::program_options::variables_m
{
loadConfig(mFixedPath.getUserPath(), variables, description);
boost::program_options::notify(variables);
loadConfig(mFixedPath.getLocalPath(), variables, description);
boost::program_options::notify(variables);
loadConfig(mFixedPath.getGlobalPath(), variables, description);
boost::program_options::notify(variables);
}
struct EmptyPath : public std::unary_function<const boost::filesystem::path&, bool>
{
bool operator()(const boost::filesystem::path& path) const
{
return path.empty();
}
};
void ConfigurationManager::processPaths(Files::PathContainer& dataDirs)
{
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
{
const std::string& path = it->string();
if (!path.empty() && path[0] == '?')
{
std::string::size_type pos = path.find('?', 1);
if (pos != std::string::npos)
{
++pos;
TokensMappingContainer::iterator tokenIt = mTokensMapping.find(path.substr(0, pos));
if (tokenIt != mTokensMapping.end())
{
boost::filesystem::path tempPath(path.substr(pos, path.length() - pos));
if (boost::filesystem::is_directory(tempPath))
{
((mFixedPath).*(tokenIt->second))(tempPath);
(*it) = tempPath;
}
else
{
(*it).clear();
}
}
}
}
}
dataDirs.erase(std::remove_if(dataDirs.begin(), dataDirs.end(), EmptyPath()), dataDirs.end());
}
void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
@ -112,17 +156,26 @@ const boost::filesystem::path& ConfigurationManager::getLocalPath() const
return mFixedPath.getLocalPath();
}
const boost::filesystem::path& ConfigurationManager::getDataPath(const std::string& type) const
const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const
{
TokensMappingContainer::const_iterator it = mTokensMapping.find(type);
if (it != mTokensMapping.end())
{
return ((mFixedPath).*(it->second))();
}
return mFixedPath.getGlobalDataPath();
}
const boost::filesystem::path& ConfigurationManager::getUserDataPath() const
{
return mFixedPath.getUserDataPath();
}
const boost::filesystem::path& ConfigurationManager::getLocalDataPath() const
{
return mFixedPath.getLocalDataPath();
}
const boost::filesystem::path& ConfigurationManager::getInstallPath() const
{
return mFixedPath.getInstallPath();
}
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
{
return mOgreCfgPath;

@ -7,6 +7,7 @@
#include <boost/filesystem.hpp>
#include <components/files/fixedpath.hpp>
#include <components/files/collections.hpp>
/**
* \namespace Files
@ -14,12 +15,6 @@
namespace Files
{
extern const char* const mwDataToken;
extern const char* const localDataToken;
extern const char* const userDataToken;
extern const char* const globalDataToken;
/**
* \struct ConfigurationManager
*/
@ -30,13 +25,17 @@ struct ConfigurationManager
void readConfiguration(boost::program_options::variables_map& variables,
boost::program_options::options_description& description);
void processPaths(Files::PathContainer& dataDirs);
/**< Fixed paths */
const boost::filesystem::path& getGlobalPath() const;
const boost::filesystem::path& getUserPath() const;
const boost::filesystem::path& getLocalPath() const ;
const boost::filesystem::path& getLocalPath() const;
const boost::filesystem::path& getDataPath(const std::string& type) const;
const boost::filesystem::path& getGlobalDataPath() const;
const boost::filesystem::path& getUserDataPath() const;
const boost::filesystem::path& getLocalDataPath() const;
const boost::filesystem::path& getInstallPath() const;
const boost::filesystem::path& getOgreConfigPath() const;
const boost::filesystem::path& getPluginsConfigPath() const;
@ -45,7 +44,7 @@ struct ConfigurationManager
private:
typedef Files::FixedPath<> FixedPathType;
typedef const boost::filesystem::path& (FixedPathType::*path_type_f)() const;
typedef void (FixedPathType::*path_type_f)(const boost::filesystem::path&);
typedef std::tr1::unordered_map<std::string, path_type_f> TokensMappingContainer;
void loadConfig(const boost::filesystem::path& path,

@ -122,11 +122,12 @@ struct FixedPath
const boost::filesystem::path& getInstallPath() const
{
// TODO: It will be corrected later.
static boost::filesystem::path p("./");
return p;
return mInstallPath;
}
//return mFixedPath.getInstallPath();
void setInstallPath(const boost::filesystem::path& path)
{
mInstallPath = path;
}
const boost::filesystem::path& getGlobalDataPath() const
@ -134,16 +135,31 @@ struct FixedPath
return mGlobalDataPath;
}
void setGlobalDataPath(const boost::filesystem::path& path)
{
mGlobalDataPath = path;
}
const boost::filesystem::path& getUserDataPath() const
{
return mUserDataPath;
}
void setUserDataPath(const boost::filesystem::path& path)
{
mUserDataPath = path;
}
const boost::filesystem::path& getLocalDataPath() const
{
return mLocalDataPath;
}
void setLocalDataPath(const boost::filesystem::path& path)
{
mLocalDataPath = path;
}
private:
PathType mPath;

@ -157,73 +157,75 @@ boost::filesystem::path LinuxPath::getLocalDataPath() const
boost::filesystem::path LinuxPath::getInstallPath() const
{
boost::filesystem::path installPath;
char *homePath = getenv("HOME");
if(!homePath)
{
return boost::filesystem::path("");
}
boost::filesystem::path wineDefaultRegistry(homePath);
wineDefaultRegistry /= ".wine/system.reg";
boost::filesystem::path wineDriveC(homePath);
wineDriveC /= ".wine/drive_c";
boost::filesystem::file_status fileStatus = boost::filesystem::status(wineDefaultRegistry);
boost::filesystem::file_status dirStatus = boost::filesystem::status(wineDriveC);
if(!boost::filesystem::is_regular_file(fileStatus) || !boost::filesystem::is_directory(dirStatus))
if (homePath == NULL)
{
return boost::filesystem::path("");
}
boost::filesystem::ifstream file(wineDefaultRegistry);
bool isRegEntry = false;
std::string line;
while (std::getline(file, line))
{
if(!line.empty() && line[0] == '[') // we found an entry
struct passwd* pwd = getpwuid(getuid());
if (pwd != NULL)
{
std::string regkey = line.substr(1, line.find(']')-1);
if( regkey.compare("SOFTWARE\\\\Wow6432Node\\\\Bethesda Softworks\\\\Morrowind") == 0
|| regkey.compare("SOFTWARE\\\\Bethesda Softworks\\\\Morrowind") == 0 )
{
isRegEntry = true;
}
homePath = pwd->pw_dir;
}
else if(isRegEntry)
}
if (homePath != NULL)
{
boost::filesystem::path wineDefaultRegistry(homePath);
wineDefaultRegistry /= ".wine/system.reg";
if (boost::filesystem::is_regular_file(wineDefaultRegistry))
{
if(line.empty() || line[0] != '"') // empty line means new registry key
boost::filesystem::ifstream file(wineDefaultRegistry);
bool isRegEntry = false;
std::string line;
std::string mwpath;
while (std::getline(file, line) && !line.empty())
{
break;
}
std::string key = line.substr(1, line.find('"', 1)-1);
if(key.compare("Installed Path") == 0) {
std::string::size_type pos, startPos;
startPos = line.find('=')+2;
std::string installPath = line.substr(startPos, line.find('"', startPos+1)-startPos);
installPath.replace(0, 2, wineDriveC.string());
pos = -1;
do
if (line[0] == '[') // we found an entry
{
isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
}
else if (isRegEntry)
{
pos = installPath.find("\\\\", pos+1);
if(pos == std::string::npos)
if (line[0] == '"') // empty line means new registry key
{
break;
std::string key = line.substr(1, line.find('"', 1) - 1);
if (strcasecmp(key.c_str(), "Installed Path") == 0)
{
std::string::size_type valuePos = line.find('=') + 2;
mwpath = line.substr(valuePos, line.rfind('"') - valuePos);
std::string::size_type pos = mwpath.find("\\");
while (pos != std::string::npos)
{
mwpath.replace(pos, 2, "/");
pos = mwpath.find("\\", pos + 1);
}
break;
}
}
installPath.replace(pos, 2, "/");
} while(true);
return boost::filesystem::path(installPath);
}
}
if (!mwpath.empty())
{
// Change drive letter to lowercase, so we could use ~/.wine/dosdevice symlinks
mwpath[0] = tolower(mwpath[0]);
installPath /= homePath;
installPath /= ".wine/dosdevices/";
installPath /= mwpath;
if (!boost::filesystem::is_directory(installPath))
{
installPath.clear();
}
}
}
}
return boost::filesystem::path("");
return installPath;
}
} /* namespace Files */

@ -112,11 +112,83 @@ boost::filesystem::path MacOsPath::getLocalDataPath() const
return boost::filesystem::path("./data/");
}
boost::filesystem::path MacOsPath::getInstallPath() const;
/**
* FIXME: This should be verified on MacOS system!
*/
boost::filesystem::path MacOsPath::getInstallPath() const
{
return boost::filesystem::path("./");
boost::filesystem::path installPath;
char *homePath = getenv("HOME");
if (homePath == NULL)
{
struct passwd* pwd = getpwuid(getuid());
if (pwd != NULL)
{
homePath = pwd->pw_dir;
}
}
if (homePath != NULL)
{
boost::filesystem::path wineDefaultRegistry(homePath);
wineDefaultRegistry /= ".wine/system.reg";
if (boost::filesystem::is_regular_file(wineDefaultRegistry))
{
boost::filesystem::ifstream file(wineDefaultRegistry);
bool isRegEntry = false;
std::string line;
std::string mwpath;
while (std::getline(file, line) && !line.empty())
{
if (line[0] == '[') // we found an entry
{
isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
}
else if (isRegEntry)
{
if (line[0] == '"') // empty line means new registry key
{
std::string key = line.substr(1, line.find('"', 1) - 1);
if (strcasecmp(key.c_str(), "Installed Path") == 0)
{
std::string::size_type valuePos = line.find('=') + 2;
mwpath = line.substr(valuePos, line.rfind('"') - valuePos);
std::string::size_type pos = mwpath.find("\\");
while (pos != std::string::npos)
{
mwpath.replace(pos, 2, "/");
pos = mwpath.find("\\", pos + 1);
}
break;
}
}
}
}
if (!mwpath.empty())
{
// Change drive letter to lowercase, so we could use ~/.wine/dosdevice symlinks
mwpath[0] = tolower(mwpath[0]);
installPath /= homePath;
installPath /= ".wine/dosdevices/";
installPath /= mwpath;
if (!boost::filesystem::is_directory(installPath))
{
installPath.clear();
}
}
}
}
return installPath;
}
} /* namespace Files */
#endif /* defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) */

Loading…
Cancel
Save