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

@ -3,7 +3,7 @@
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <functional> #include <algorithm>
namespace Files namespace Files
{ {
@ -24,7 +24,7 @@ ConfigurationManager::ConfigurationManager()
/** /**
* According to task #168 plugins.cfg file shall be located in global * 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; mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile;
if (!boost::filesystem::is_regular_file(mPluginsCfgPath)) if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
@ -55,10 +55,10 @@ ConfigurationManager::~ConfigurationManager()
void ConfigurationManager::setupTokensMapping() void ConfigurationManager::setupTokensMapping()
{ {
mTokensMapping.insert(std::make_pair(mwDataToken, &FixedPath<>::getInstallPath)); mTokensMapping.insert(std::make_pair(mwDataToken, &FixedPath<>::setInstallPath));
mTokensMapping.insert(std::make_pair(localDataToken, &FixedPath<>::getLocalDataPath)); mTokensMapping.insert(std::make_pair(localDataToken, &FixedPath<>::setLocalDataPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::getUserDataPath)); mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::setUserDataPath));
mTokensMapping.insert(std::make_pair(globalDataToken, &FixedPath<>::getGlobalDataPath)); mTokensMapping.insert(std::make_pair(globalDataToken, &FixedPath<>::setGlobalDataPath));
} }
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables, 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); loadConfig(mFixedPath.getUserPath(), variables, description);
boost::program_options::notify(variables); boost::program_options::notify(variables);
loadConfig(mFixedPath.getLocalPath(), variables, description); loadConfig(mFixedPath.getLocalPath(), variables, description);
boost::program_options::notify(variables); boost::program_options::notify(variables);
loadConfig(mFixedPath.getGlobalPath(), variables, description); loadConfig(mFixedPath.getGlobalPath(), variables, description);
boost::program_options::notify(variables); 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, void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
@ -112,17 +156,26 @@ const boost::filesystem::path& ConfigurationManager::getLocalPath() const
return mFixedPath.getLocalPath(); 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); return mFixedPath.getGlobalDataPath();
if (it != mTokensMapping.end()) }
{
return ((mFixedPath).*(it->second))(); const boost::filesystem::path& ConfigurationManager::getUserDataPath() const
} {
return mFixedPath.getUserDataPath();
}
const boost::filesystem::path& ConfigurationManager::getLocalDataPath() const
{
return mFixedPath.getLocalDataPath(); return mFixedPath.getLocalDataPath();
} }
const boost::filesystem::path& ConfigurationManager::getInstallPath() const
{
return mFixedPath.getInstallPath();
}
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
{ {
return mOgreCfgPath; return mOgreCfgPath;

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

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

@ -157,73 +157,75 @@ boost::filesystem::path LinuxPath::getLocalDataPath() const
boost::filesystem::path LinuxPath::getInstallPath() const boost::filesystem::path LinuxPath::getInstallPath() const
{ {
boost::filesystem::path installPath;
char *homePath = getenv("HOME"); char *homePath = getenv("HOME");
if(!homePath) if (homePath == NULL)
{
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))
{ {
return boost::filesystem::path(""); struct passwd* pwd = getpwuid(getuid());
} if (pwd != NULL)
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
{ {
std::string regkey = line.substr(1, line.find(']')-1); homePath = pwd->pw_dir;
if( regkey.compare("SOFTWARE\\\\Wow6432Node\\\\Bethesda Softworks\\\\Morrowind") == 0
|| regkey.compare("SOFTWARE\\\\Bethesda Softworks\\\\Morrowind") == 0 )
{
isRegEntry = true;
}
} }
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; if (line[0] == '[') // we found an entry
} {
std::string key = line.substr(1, line.find('"', 1)-1); isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
if(key.compare("Installed Path") == 0) { }
std::string::size_type pos, startPos; else if (isRegEntry)
startPos = line.find('=')+2;
std::string installPath = line.substr(startPos, line.find('"', startPos+1)-startPos);
installPath.replace(0, 2, wineDriveC.string());
pos = -1;
do
{ {
pos = installPath.find("\\\\", pos+1); if (line[0] == '"') // empty line means new registry key
if(pos == std::string::npos)
{ {
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);
if (!mwpath.empty())
return boost::filesystem::path(installPath); {
// 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 */ } /* namespace Files */

@ -112,11 +112,83 @@ boost::filesystem::path MacOsPath::getLocalDataPath() const
return boost::filesystem::path("./data/"); 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 */ } /* namespace Files */
#endif /* defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) */ #endif /* defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) */

Loading…
Cancel
Save