[Scummvm-cvs-logs] CVS: scummvm/common config-manager.h,1.13,1.14 config-manager.cpp,1.19,1.20
Max Horn
fingolfin at users.sourceforge.net
Sun Mar 28 12:38:01 CEST 2004
Update of /cvsroot/scummvm/scummvm/common
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30250/common
Modified Files:
config-manager.h config-manager.cpp
Log Message:
Preserve comments in config files
Index: config-manager.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/config-manager.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- config-manager.h 21 Mar 2004 18:54:47 -0000 1.13
+++ config-manager.h 28 Mar 2004 20:26:13 -0000 1.14
@@ -38,14 +38,9 @@
* @todo Implement the callback based notification system (outline below)
* which sends out notifications to interested parties whenever the value
* of some specific (or any) configuration key changes.
- * @todo Store comments and write them back out to disk. A simple approach for
- * that would be to store comments which come before a section, and
- * comments which comes before a specific config key. While this is
- * limited, it is at least much better than not saving any comments, and
- * it shouldn't be hard to implement either.
- * @todo Allow preserving the order of the entries in the config file. Maybe
- * even add an API to query/modify that order, which could be used by the
- * launcher to allow arranging the game targets.
+ * @todo Preserve the order of the entries in the config file. Maybe even add
+ * an API to query/modify that order, which could be used by the launcher
+ * to allow arranging the game targets.
*/
class ConfigManager : public Singleton<ConfigManager> {
struct IgnoreCaseComparator {
@@ -53,12 +48,32 @@
};
public:
- class Domain : public Map<String, String, IgnoreCaseComparator> {
+ typedef Map<String, String, IgnoreCaseComparator> StringMap;
+
+ class Domain : public StringMap {
+ private:
+ StringMap _keyValueComments;
+ String _domainComment;
public:
+
const String &get(const String &key) const {
Node *node = findNode(_root, key);
return node ? node->_value : String::emptyString;
}
+
+ void setDomainComment(const String &comment) {
+ _domainComment = comment;
+ }
+ const String &getDomainComment() const {
+ return _domainComment;
+ }
+
+ void setKVComment(const String &key, const String &comment) {
+ _keyValueComments[key] = comment;
+ }
+ const String &getKVComment(const String &key) const {
+ return _keyValueComments[key];
+ }
};
typedef Map<String, Domain, IgnoreCaseComparator> DomainMap;
Index: config-manager.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/config-manager.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- config-manager.cpp 28 Mar 2004 18:29:27 -0000 1.19
+++ config-manager.cpp 28 Mar 2004 20:26:14 -0000 1.20
@@ -115,15 +115,22 @@
} else {
char buf[MAXLINELEN];
String domain;
+ String comment;
int lineno = 0;
+
+ // TODO: Detect if a domain occurs multiple times (or likewise, if
+ // a key occurs multiple times inside one domain).
while (!feof(cfg_file)) {
lineno++;
if (!fgets(buf, MAXLINELEN, cfg_file))
continue;
- if (!buf[0] || buf[0] == '#') {
- // Skip empty lines and comments
- // TODO: Comments should be preserved here!
+
+ if (buf[0] == '#') {
+ // Accumulate comments here. Once we encounter either the start
+ // of a new domain, or a key-value-pair, we associate the value
+ // of the 'comment' variable with that entity.
+ comment += buf;
} else if (buf[0] == '[') {
// It's a new domain which begins here.
char *p = buf + 1;
@@ -144,9 +151,17 @@
default:
error("Config file buggy: Invalid character '%c' occured in domain name in line %d", *p, lineno);
}
+
+ // Store domain comment
+ if (_globalDomains.contains(domain)) {
+ _globalDomains[domain].setDomainComment(comment);
+ } else {
+ _gameDomains[domain].setDomainComment(comment);
+ }
+ comment.clear();
} else {
- // Skip leading whitespaces
- char *t = ltrim(buf);
+ // Skip leading & trailing whitespaces
+ char *t = rtrim(ltrim(buf));
// Skip empty lines
if (*t == 0)
@@ -157,24 +172,22 @@
error("Config file buggy: Key/value pair found outside a domain in line %d", lineno);
}
- // It's a new key in the domain.
- char *p = strchr(t, '\n');
- if (p)
- *p = 0;
- p = strchr(t, '\r');
- if (p)
- *p = 0;
-
// Split string at '=' into 'key' and 'value'.
- p = strchr(t, '=');
- if (!p) {
+ char *p = strchr(t, '=');
+ if (!p)
error("Config file buggy: Junk found in line line %d: '%s'", lineno, t);
+ *p = 0;
+ String key = rtrim(t);
+ String value = ltrim(p + 1);
+ set(key, value, domain);
+
+ // Store comment
+ if (_globalDomains.contains(domain)) {
+ _globalDomains[domain].setKVComment(key, comment);
} else {
- *p = 0;
- String key = rtrim(t);
- String value = rtrim(ltrim(p + 1));
- set(key, value, domain);
+ _gameDomains[domain].setKVComment(key, comment);
}
+ comment.clear();
}
}
fclose(cfg_file);
@@ -211,13 +224,28 @@
if (domain.isEmpty())
return; // Don't bother writing empty domains.
+ String comment;
+
+ // Write domain comment (if any)
+ comment = domain.getDomainComment();
+ if (!comment.isEmpty())
+ fprintf(file, "%s", comment.c_str());
+
+ // Write domain start
fprintf(file, "[%s]\n", name.c_str());
+ // Write all key/value pairs in this domain, including comments
Domain::const_iterator x;
for (x = domain.begin(); x != domain.end(); ++x) {
const String &value = x->_value;
- if (!value.isEmpty())
+ if (!value.isEmpty()) {
+ // Write comment (if any)
+ comment = domain.getKVComment(x->_key);
+ if (!comment.isEmpty())
+ fprintf(file, "%s", comment.c_str());
+ // Write the key/value pair
fprintf(file, "%s=%s\n", x->_key.c_str(), value.c_str());
+ }
}
fprintf(file, "\n");
}
More information about the Scummvm-git-logs
mailing list