scummvm/common/config-file.cpp

241 lines
5.4 KiB
C++

/* 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 "stdafx.h"
#include "common/config-file.h"
#include "base/engine.h" // for debug()
#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;
}
// The config-class itself.
Config::Config (const String &cfg, const String &d)
: filename(cfg), defaultDomain(d), willwrite(false) {
FILE *cfg_file;
char t[MAXLINELEN];
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) {
debug(1, "Config file buggy: no ] at the end of the domain name.\n");
} else {
*p = 0;
set_domain(t + 1);
}
} else {
// It's a new key in the domain.
if (defaultDomain.isEmpty()) {
debug(1, "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))
debug(1, "Config file buggy: there is junk: %s\n", t);
} else {
char *key, *value;
*p = 0;
key = ltrim(rtrim(t));
value = ltrim(p + 1);
set(key, value);
}
}
}
}
set_domain(d);
fclose(cfg_file);
}
}
const char *Config::get(const String &key, const String &d) const {
String domain;
if (d.isEmpty())
domain = defaultDomain;
else
domain = d;
domain.toLowercase();
if (domains.contains(domain) && domains[domain].contains(key))
return domains[domain][key].c_str();
return 0;
}
const int Config::getInt(const String &key, int def, const String &d) const {
const char *value = get(key, d);
if (value)
return atoi(value);
return def;
}
const bool Config::getBool(const String &key, bool def, const String &d) const {
const char *value = get(key, d);
if (value)
return !scumm_stricmp(value, "true");
return def;
}
void Config::set(const String &key, const String &value, const String &d) {
String domain(d);
if (domain.isEmpty())
domain = defaultDomain;
domain.toLowercase();
domains[domain][key] = value;
}
void Config::setInt(const String &key, int value_i, const String &d) {
char value[MAXLINELEN];
sprintf(value, "%i", value_i);
set(key, String(value), d);
}
void Config::setBool(const String &key, bool value_b, const String &d) {
String value(value_b ? "true" : "false");
set(key, value, d);
}
void Config::set_domain(const String &d) {
defaultDomain = d;
defaultDomain.toLowercase();
}
bool Config::has_domain(const String &d) const {
String temp(d);
temp.toLowercase();
return domains.contains(temp);
}
void Config::flush() const {
FILE *cfg_file;
if (!willwrite)
return;
if (!(cfg_file = fopen(filename.c_str(), "w"))) {
debug(1, "Unable to write configuration file: %s.\n", filename.c_str());
} else {
DomainMap::Iterator d;
for (d = domains.begin(); d != domains.end(); ++d) {
fprintf(cfg_file, "[%s]\n", d->_key.c_str());
const StringMap &data = d->_value;
StringMap::Iterator x;
for (x = data.begin(); x != data.end(); ++x) {
const String &value = x->_value;
if (!value.isEmpty())
fprintf(cfg_file, "%s=%s\n", x->_key.c_str(), value.c_str());
}
fprintf(cfg_file, "\n");
}
fclose(cfg_file);
}
}
void Config::rename_domain(const String &oldD, const String &newD) {
String oldDomain(oldD);
String newDomain(newD);
oldDomain.toLowercase();
newDomain.toLowercase();
if (oldDomain == newDomain)
return;
StringMap &oldHash = domains[oldDomain];
StringMap &newHash = domains[newDomain];
newHash.merge(oldHash);
domains.remove(oldDomain);
}
void Config::delete_domain(const String &d) {
String domain(d);
domain.toLowercase();
domains.remove(d);
}
void Config::set_filename(const String &f) {
filename = f;
}
void Config::merge_config(const Config &c) {
DomainMap::Iterator d, end(c.domains.end());
for (d = c.domains.begin(); d != end; ++d) {
domains[d->_key].merge(d->_value);
}
}
void Config::set_writing(bool w) {
willwrite = w;
}
const int Config::count_domains() {
int count = 0;
DomainMap::Iterator d, end(domains.end());
for (d = domains.begin(); d != end; ++d)
count++;
return count;
}
ScummVM::StringList Config::get_domains() {
StringList domainNames;
DomainMap::Iterator d, end(domains.end());
for (d = domains.begin(); d != end; ++d) {
domainNames.push_back(d->_key);
}
return domainNames;
}