[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