diff options
author | James Brown | 2002-04-27 17:21:38 +0000 |
---|---|---|
committer | James Brown | 2002-04-27 17:21:38 +0000 |
commit | 35ab30657764ed8f4149088bde82628b1b14fe69 (patch) | |
tree | b82a4489aaa24afb5d26e49f86352bd98e2aee10 | |
parent | 2b50dd27420654d3eeee7c163ec96aedc0478936 (diff) | |
download | scummvm-rg350-35ab30657764ed8f4149088bde82628b1b14fe69.tar.gz scummvm-rg350-35ab30657764ed8f4149088bde82628b1b14fe69.tar.bz2 scummvm-rg350-35ab30657764ed8f4149088bde82628b1b14fe69.zip |
<Fingolfin> Endy: hey don't you think adding config-file.* to CVS would be a good idea?
svn-id: r4112
-rw-r--r-- | config-file.cpp | 332 | ||||
-rw-r--r-- | config-file.h | 25 |
2 files changed, 357 insertions, 0 deletions
diff --git a/config-file.cpp b/config-file.cpp new file mode 100644 index 0000000000..4ff771d691 --- /dev/null +++ b/config-file.cpp @@ -0,0 +1,332 @@ +#include <stdio.h> +#include <stdlib.h> +#include "stdafx.h" +#include "config-file.h" +#include "scumm.h" + +#define MAXLINELEN 256 + +static char * ltrim(char * t) { + for (; *t && (*t == ' '); t++); + return t; +} + +static char * rtrim(char * t) { + int l; + + for (l = strlen(t) - 1; l; l--) { + if (t[l] == ' ') { + *t = 0; + } else { + return t; + } + } + return t; +} + +class hashconfig { + public: + hashconfig(const char *); + ~hashconfig(); + const char * get_domain() const; + bool is_domain(const char *) const; + const char * get(const char *) const; + const char * set(const char *, const char *); + const char * getdomain() const; + void flush(FILE *) const; + void rename(const char *); + void merge(const hashconfig *); + private: + char * domain; + char ** keys, ** values; + int nkeys; +}; + +hashconfig::hashconfig(const char * dom) : domain(dom ? Scumm::Strdup(dom) : 0), keys(0), values(0), nkeys(0) { } + +hashconfig::~hashconfig() { + int i; + + Scumm::free(domain); + for (i = 0; i < nkeys; i++) { + } +} + +const char * hashconfig::get_domain() const { + return domain; +} + +bool hashconfig::is_domain(const char * d) const { + if (!this) + return false; + return d ? domain ? !strcmp(d, domain) ? true : false : false : false; +} + +const char * hashconfig::get(const char * key) const { + int i; + + for (i = 0; i < nkeys; i++) { + if (!strcmp(key, keys[i])) { + return values[i]; + } + } + + return 0; +} + +const char * hashconfig::set(const char * key, const char * value) { + int i; + + for (i = 0; i < nkeys; i++) { + if (!strcmp(key, keys[i])) { + Scumm::free(values[i]); + return values[i] = value ? Scumm::Strdup(value) : 0; + } + } + + nkeys++; + keys = (char **) Scumm::realloc(keys, nkeys * sizeof(char *)); + values = (char **) Scumm::realloc(values, nkeys * sizeof(char *)); + keys[nkeys - 1] = Scumm::Strdup(key); + return values[nkeys - 1] = value ? Scumm::Strdup(value) : 0; +} + +const char * hashconfig::getdomain() const { + return domain; +} + +void hashconfig::flush(FILE * cfg_file) const { + int i; + + if (!this || !domain) + return; + + fprintf(cfg_file, "[%s]\n", domain); + + for (i = 0; i < nkeys; i++) { + if (values[i]) { + fprintf(cfg_file, "%s=%s\n", keys[i], values[i]); + } + } + fprintf(cfg_file, "\n"); +} + +void hashconfig::rename(const char * d) { + Scumm::free(domain); + domain = d ? Scumm::Strdup(d) : 0; +} + +void hashconfig::merge(const hashconfig * h) { + int i; + + for (i = 0; i < h->nkeys; i++) { + set(h->keys[i], h->values[i]); + } +} + +// The config-class itself. + +Config::Config(const char * cfg, const char * d) : filename(Scumm::Strdup(cfg)), domain(d ? Scumm::Strdup(d) : 0), hash(0), ndomains(0) { + FILE * cfg_file; + char t[MAXLINELEN]; + + if (!(cfg_file = fopen(cfg, "r"))) { + debug(1, "Unable to open configuration file: %s.\n", filename); + } 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 (!domain) { + 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); + } +} + +Config::~Config() { + int i; + + Scumm::free(filename); + Scumm::free(domain); + + for (i = 0; i < ndomains; i++) { + delete hash[i]; + } + Scumm::free(hash); +} + +const char * Config::get(const char * key, const char * d) const { + int i; + + if (!d) + d = domain; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(d)) { + return hash[i]->get(key); + } + } + + return 0; +} + +const char * Config::set(const char * key, const char * value, const char * d) { + int i; + + if (!d) + d = domain; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(d)) { + return hash[i]->set(key, value); + } + } + + ndomains++; + hash = (hashconfig **) Scumm::realloc(hash, ndomains * sizeof(hashconfig *)); + hash[ndomains - 1] = new hashconfig(domain); + + return hash[ndomains - 1]->set(key, value); +} + +const char * Config::set(const char * key, int value_i, const char * d) { + int i; + char value[MAXLINELEN]; + + sprintf(value, "%i", value_i); + + if (!d) + d = domain; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(d)) { + return hash[i]->set(key, value); + } + } + + ndomains++; + hash = (hashconfig **) Scumm::realloc(hash, ndomains * sizeof(hashconfig *)); + hash[ndomains - 1] = new hashconfig(domain); + + return hash[ndomains - 1]->set(key, value); +} + +void Config::set_domain(const char * d) { + int i; + Scumm::free(domain); + domain = d ? Scumm::Strdup(d) : 0; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(domain)) + return; + } + ndomains++; + hash = (hashconfig **) Scumm::realloc(hash, ndomains * sizeof(hashconfig *)); + hash[ndomains - 1] = new hashconfig(domain); +} + +void Config::flush() const { + FILE * cfg_file; + int i; + + if (!(cfg_file = fopen(filename, "w"))) { + debug(1, "Unable to write configuration file: %s.\n", filename); + } else { + for (i = 0; i < ndomains; i++) { + hash[i]->flush(cfg_file); + } + fclose(cfg_file); + } +} + +void Config::rename_domain(const char * d) { + int i, index = -1; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(d)) { + index = i; + } + } + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(domain)) { + if (index >= 0) { + hash[i]->merge(hash[index]); + hash[index]->rename(0); + rename_domain(d); + } else { + hash[i]->rename(d); + } + } + } +} + +void Config::delete_domain(const char * d) { + int i; + + for (i = 0; i < ndomains; i++) { + if (hash[i]->is_domain(d)) { + hash[i]->rename(0); + } + } +} + +void Config::change_filename(const char * f) { + Scumm::free(filename); + filename = f ? Scumm::Strdup(f) : 0; +} + +void Config::merge_config(const Config * c) { + int i, j; + bool found; + + for (i = 0; i < c->ndomains; i++) { + found = false; + for (j = 0; j < ndomains; j++) { + if (hash[j]->is_domain(c->hash[i]->getdomain())) { + hash[j]->merge(c->hash[i]); + found = true; + break; + } + } + if (!found) { + ndomains++; + hash = (hashconfig **) Scumm::realloc(hash, ndomains * sizeof(hashconfig *)); + hash[ndomains - 1] = new hashconfig(domain); + hash[ndomains - 1]->merge(c->hash[i]); + } + } +} diff --git a/config-file.h b/config-file.h new file mode 100644 index 0000000000..154118b723 --- /dev/null +++ b/config-file.h @@ -0,0 +1,25 @@ +#ifndef __CONFIG_FILE_H__ +#define __CONFIG_FILE_H__ + +class hashconfig; + +class Config { + public: + Config(const char * = "config.cfg", const char * = "default"); + ~Config(); + const char * get(const char *, const char * = 0) const; + const char * set(const char *, const char *, const char * = 0); + const char * set(const char *, int, const char * = 0); + void set_domain(const char *); + void flush() const; + void rename_domain(const char *); + void delete_domain(const char *); + void change_filename(const char *); + void merge_config(const Config *); + private: + char * filename, * domain; + hashconfig ** hash; + int ndomains; +}; + +#endif |