aboutsummaryrefslogtreecommitdiff
path: root/common/config-manager.cpp
diff options
context:
space:
mode:
authorMax Horn2003-10-08 21:59:23 +0000
committerMax Horn2003-10-08 21:59:23 +0000
commitd1773647159f9ef1393d7a1d33204de5886edce5 (patch)
treed31f1a3689fa34a525671f21d7a858fe8570762f /common/config-manager.cpp
parent3c78c0929c553fd67016f87c6cdc38d3f50d7ca2 (diff)
downloadscummvm-rg350-d1773647159f9ef1393d7a1d33204de5886edce5.tar.gz
scummvm-rg350-d1773647159f9ef1393d7a1d33204de5886edce5.tar.bz2
scummvm-rg350-d1773647159f9ef1393d7a1d33204de5886edce5.zip
new config manager. not everything is completed, and some things will still be changed, but it seems to work well enough to put it into CVS
svn-id: r10687
Diffstat (limited to 'common/config-manager.cpp')
-rw-r--r--common/config-manager.cpp370
1 files changed, 370 insertions, 0 deletions
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
new file mode 100644
index 0000000000..f90eefbbd3
--- /dev/null
+++ b/common/config-manager.cpp
@@ -0,0 +1,370 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2003 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/config-manager.h"
+
+#if defined(UNIX)
+#include <sys/param.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 256
+#endif
+#ifdef MACOSX
+#define DEFAULT_CONFIG_FILE "Library/Preferences/ScummVM Preferences"
+#else
+#define DEFAULT_CONFIG_FILE ".scummvmrc"
+#endif
+#else
+#define DEFAULT_CONFIG_FILE "scummvm.ini"
+#endif
+
+#define MAXLINELEN 256
+
+static char *ltrim(char *t) {
+ while (*t == ' ')
+ t++;
+ return t;
+}
+
+static char *rtrim(char *t) {
+ int l = strlen(t) - 1;
+ while (l >= 0 && t[l] == ' ')
+ t[l--] = 0;
+ return t;
+}
+
+
+namespace Common {
+
+const String ConfigManager::kApplicationDomain("scummvm");
+
+const String trueStr("true");
+const String falseStr("false");
+
+
+#pragma mark -
+
+
+ConfigManager::ConfigManager() {
+
+#if defined(UNIX)
+ char configFile[MAXPATHLEN];
+ if(getenv("HOME") != NULL)
+ sprintf(configFile,"%s/%s", getenv("HOME"), DEFAULT_CONFIG_FILE);
+ else strcpy(configFile,DEFAULT_CONFIG_FILE);
+#else
+ char configFile[256];
+ #if defined (WIN32) && !defined(_WIN32_WCE)
+ GetWindowsDirectory(configFile, 256);
+ strcat(configFile, "\\");
+ strcat(configFile, DEFAULT_CONFIG_FILE);
+ #elif defined(__PALM_OS__)
+ strcpy(configFile,"/PALM/Programs/ScummVM/");
+ strcat(configFile, DEFAULT_CONFIG_FILE);
+ #else
+ strcpy(configFile, DEFAULT_CONFIG_FILE);
+ #endif
+#endif
+
+ // Ensure the global domain(s) are setup.
+ _globalDomains.addKey(kApplicationDomain);
+#ifdef _WIN32_WCE
+ // WinCE for some reasons uses additional global domains.
+ _globalDomains.addKey("wince");
+ _globalDomains.addKey("smartfon-keys");
+#endif
+
+ _filename = configFile;
+ loadFile(_filename);
+}
+
+void ConfigManager::loadFile(const String &filename) {
+ FILE *cfg_file;
+ char t[MAXLINELEN];
+ String domain;
+
+ if (!(cfg_file = fopen(filename.c_str(), "r"))) {
+ debug(1, "Unable to open configuration file: %s.\n", filename.c_str());
+ } else {
+ while (!feof(cfg_file)) {
+ if (!fgets(t, MAXLINELEN, cfg_file))
+ continue;
+ if (t[0] != '#') {
+ if (t[0] == '[') {
+ // It's a new domain which begins here.
+ char *p = strchr(t, ']');
+ if (!p) {
+ error("Config file buggy: no ] at the end of the domain name.\n");
+ } else {
+ *p = 0;
+ // TODO: Some kind of domain name verification might be nice.
+ // E.g. restrict to only a-zA-Z0-9 and maybe -_ or so...
+ domain = t + 1;
+ }
+ } else {
+ // It's a new key in the domain.
+ if (domain.isEmpty()) {
+ error("Config file buggy: we have a key without a domain first.\n");
+ }
+ char *p = strchr(t, '\n');
+ if (p)
+ *p = 0;
+ p = strchr(t, '\r');
+ if (p)
+ *p = 0;
+
+ if (!(p = strchr(t, '='))) {
+ if (strlen(t))
+ warning("Config file buggy: there is junk: %s\n", t);
+ } else {
+ *p = 0;
+ String key = ltrim(rtrim(t));
+ String value = ltrim(p + 1);
+ set(key, value, domain);
+ }
+ }
+ }
+ }
+ fclose(cfg_file);
+ }
+}
+
+void ConfigManager::flushToDisk() {
+ FILE *cfg_file;
+
+// TODO
+// if (!willwrite)
+// return;
+
+ if (!(cfg_file = fopen(_filename.c_str(), "w"))) {
+ warning("Unable to write configuration file: %s.\n", _filename.c_str());
+ } else {
+ DomainMap::ConstIterator d;
+
+ // First write the global domains
+ for (d = _globalDomains.begin(); d != _globalDomains.end(); ++d) {
+ writeDomain(cfg_file, d->_key, d->_value);
+ }
+
+ // Second, write the game domains
+ for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) {
+ writeDomain(cfg_file, d->_key, d->_value);
+ }
+
+ fclose(cfg_file);
+ }
+}
+
+void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &domain) {
+ if (domain.isEmpty())
+ return; // Don't bother writing empty domains.
+
+ fprintf(file, "[%s]\n", name.c_str());
+
+ StringMap::ConstIterator x;
+ for (x = domain.begin(); x != domain.end(); ++x) {
+ const String &value = x->_value;
+ if (!value.isEmpty())
+ fprintf(file, "%s=%s\n", x->_key.c_str(), value.c_str());
+ }
+ fprintf(file, "\n");
+}
+
+#pragma mark -
+
+
+bool ConfigManager::hasKey(const String &key) const {
+ // Search the domains in the following order:
+ // 1) Run time domain
+ // 2) Active game domain (if any)
+ // 3) All global domains
+ // The defaults domain is explicitly *not* checked.
+
+// if (_runtimeDomain.contain(key))
+// return true;
+
+ if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
+ return true;
+
+ DomainMap::ConstIterator iter;
+ for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
+ if (iter->_value.contains(key))
+ return true;
+ }
+
+ return false;
+}
+
+
+bool ConfigManager::hasKey(const String &key, const String &dom) const {
+ assert(!dom.isEmpty());
+
+ if (_gameDomains.contains(dom))
+ return _gameDomains[dom].contains(key);
+ if (_globalDomains.contains(dom))
+ return _globalDomains[dom].contains(key);
+
+ return false;
+}
+
+
+#pragma mark -
+
+
+const String & ConfigManager::get(const String &key) const {
+ // Search the domains in the following order:
+ // 1) Run time domain
+ // 2) Active game domain (if any)
+ // 3) All global domains
+ // 4) The defaults
+
+// if (_runtimeDomain.contain(key))
+// return true;
+
+ if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
+ return _gameDomains[_activeDomain][key];
+
+ DomainMap::ConstIterator iter;
+ for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
+ if (iter->_value.contains(key))
+ return iter->_value[key];
+ }
+
+ return _defaultsDomain.get(key);
+}
+
+const String & ConfigManager::get(const String &key, const String &dom) const {
+ if (dom.isEmpty())
+ return get(key);
+
+ // TODO: How exactly should we handle the case were the domain 'dom'
+ // is not found, or were dom is found, but doesn't contain 'key' ?
+ // Right now we just return an empty string. But might want to print
+ // out a warning, or even error out?
+ if (_gameDomains.contains(dom))
+ return _gameDomains[dom].get(key);
+ if (_globalDomains.contains(dom))
+ return _globalDomains[dom].get(key);
+
+ return String::emptyString;
+}
+
+int ConfigManager::getInt(const String &key, const String &dom) const {
+ String value(get(key, dom));
+ // Convert the string to an integer.
+ // TODO: We should perform some error checking.
+ long v = strtol(value.c_str(), 0, 10);
+ return (int)v;
+}
+
+bool ConfigManager::getBool(const String &key, const String &dom) const {
+ String value(get(key, dom));
+ // '1', 'true' and 'yes' are accepted as true values; everything else
+ // maps to value 'false'.
+ return (value == "true") || (value == "yes") || (value == "1");
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::set(const String &key, const String &value) {
+#if 0
+ // TODO ?!?
+// _runtimeDomain[key] = value;
+#else
+ if (_activeDomain.isEmpty())
+ _globalDomains[kApplicationDomain][key] = value;
+ else
+ _gameDomains[_activeDomain][key] = value;
+#endif
+}
+
+void ConfigManager::set(const String &key, const String &value, const String &dom) {
+ if (_globalDomains.contains(dom))
+ _globalDomains[dom][key] = value;
+ else
+ _gameDomains[dom][key] = value;
+}
+
+void ConfigManager::set(const String &key, const char *value, const String &dom) {
+ set(key, String(value), dom);
+}
+
+void ConfigManager::set(const String &key, int value, const String &dom) {
+ char tmp[128];
+ snprintf(tmp, sizeof(tmp), "%i", value);
+ set(key, String(tmp), dom);
+}
+
+void ConfigManager::set(const String &key, bool value, const String &dom) {
+ set(key, value ? trueStr : falseStr, dom);
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::registerDefault(const String &key, const String &value) {
+ _defaultsDomain[key] = value;
+}
+
+void ConfigManager::registerDefault(const String &key, const char *value) {
+ registerDefault(key, String(value));
+}
+
+void ConfigManager::registerDefault(const String &key, int value) {
+ char tmp[128];
+ snprintf(tmp, sizeof(tmp), "%i", value);
+ registerDefault(key, tmp);
+}
+
+void ConfigManager::registerDefault(const String &key, bool value) {
+ registerDefault(key, value ? trueStr : falseStr);
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::setActiveDomain(const String &domain) {
+ _activeDomain = domain;
+ _gameDomains.addKey(domain);
+}
+
+void ConfigManager::removeGameDomain(const String &name) {
+ _gameDomains.remove(name);
+}
+
+void ConfigManager::renameGameDomain(const String &oldName, const String &newName) {
+ if (oldName == newName)
+ return;
+
+ _gameDomains[newName].merge(_gameDomains[oldName]);
+
+ _gameDomains.remove(oldName);
+}
+
+bool ConfigManager::hasGameDomain(const String &domain) const {
+ return _gameDomains.contains(domain);
+}
+
+} // End of namespace Common