diff options
| author | Max Horn | 2004-03-28 20:28:45 +0000 | 
|---|---|---|
| committer | Max Horn | 2004-03-28 20:28:45 +0000 | 
| commit | 09e3fec623c1ecea73a23d12891790569d1baa40 (patch) | |
| tree | 2ecc5506966602daca62f36610cc9bd900e1f8b4 | |
| parent | dbda6299e1037db050634fe3b306779753f4bca8 (diff) | |
| download | scummvm-rg350-09e3fec623c1ecea73a23d12891790569d1baa40.tar.gz scummvm-rg350-09e3fec623c1ecea73a23d12891790569d1baa40.tar.bz2 scummvm-rg350-09e3fec623c1ecea73a23d12891790569d1baa40.zip | |
Preserve comments in config files
svn-id: r13412
| -rw-r--r-- | NEWS | 7 | ||||
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | common/config-manager.cpp | 68 | ||||
| -rw-r--r-- | common/config-manager.h | 33 | 
4 files changed, 76 insertions, 33 deletions
| @@ -4,19 +4,20 @@ For a more comprehensive changelog for the latest experimental CVS code, see:  0.??   General:     - Added support for FLAC (losless) encoded audio files -   - Added an On Screen Display to the SDL backend +   - Added an 'On Screen Display' to the SDL backend     - Rewrote the backend API partially +   - Comments in config files are preserved now   SCUMM:     - Added graphics decoders for 3DO Humongous Entertainment games -0.6.0(PRE) (2003-??-??) +0.6.0 (2004-03-14)   New Games:     - Added Broken Sword 1 engine.     - Added Broken Sword 2 engine.     - Added Flight of the Amazon Queen engine     - Added support for V1 SCUMM games 'Maniac Mansion' and 'Zak McKracken' -   - SCUMM game Full Throttle is now supported. +   - SCUMM game Full Throttle is now supported   General:     - Subtitles now default to disabled. '-n' option now enabled subtitles. @@ -151,7 +151,6 @@ Audio  Config Manager  ============== -* Preserve comments in config file somehow  * Add a 'notification' system. E.g. the SoundMixer could request to be notified    whenever the value of the "volume" config option changes. In other words,    instead of a "pull" approach (where each subsystem has to check whether any diff --git a/common/config-manager.cpp b/common/config-manager.cpp index 1dfd546e41..e19afeced0 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -115,15 +115,22 @@ void ConfigManager::loadFile(const String &filename) {  	} 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 @@ void ConfigManager::loadFile(const String &filename) {  				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 @@ void ConfigManager::loadFile(const String &filename) {  					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 @@ void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &do  	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");  } diff --git a/common/config-manager.h b/common/config-manager.h index 604ccce111..3a54ccfb64 100644 --- a/common/config-manager.h +++ b/common/config-manager.h @@ -38,14 +38,9 @@ namespace Common {   * @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 @@ class ConfigManager : public Singleton<ConfigManager> {  	};  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; | 
