forked from teamnwah/openmw-tes3coop
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>
This commit is contained in:
parent
841bdded76
commit
1d96b99532
6 changed files with 226 additions and 83 deletions
|
@ -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
|
||||
{
|
||||
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::path installPath;
|
||||
|
||||
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))
|
||||
char *homePath = getenv("HOME");
|
||||
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
|
||||
{
|
||||
pos = installPath.find("\\\\", pos+1);
|
||||
if(pos == std::string::npos)
|
||||
isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
|
||||
}
|
||||
else if (isRegEntry)
|
||||
{
|
||||
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…
Reference in a new issue