diff options
| -rw-r--r-- | src/configfile.cc | 178 | ||||
| -rw-r--r-- | src/configfile.h | 8 | ||||
| -rw-r--r-- | test/configtest.cc | 46 | 
3 files changed, 97 insertions, 135 deletions
| diff --git a/src/configfile.cc b/src/configfile.cc index 54fb4d1..a1494a8 100644 --- a/src/configfile.cc +++ b/src/configfile.cc @@ -26,13 +26,7 @@   */  #include "configfile.h" -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -  #include <sys/stat.h> -#include <sys/types.h>  #include "platform.h" @@ -47,28 +41,34 @@  #include <hugin.hpp>  #if DG_PLATFORM == DG_PLATFORM_WINDOWS -#define SEP "\\" +static const std::string SEP = "\\"; +#else +static const std::string SEP = "/"; +#endif + +#if DG_PLATFORM == DG_PLATFORM_WINDOWS +static const std::string CONFIGDIRNAME = "DrumGizmo";  #else -#define SEP "/" +static const std::string CONFIGDIRNAME = ".drumgizmo";  #endif -#define CONFIGDIRNAME ".drumgizmo" +namespace +{  /**   * Return the path containing the config files.   */ -static std::string getConfigPath() +std::string getConfigPath()  { -#if DG_PLATFORM == DG_PLATFORM_WINDOWS  	std::string configpath; +#if DG_PLATFORM == DG_PLATFORM_WINDOWS  	TCHAR szPath[256]; -	if(SUCCEEDED(SHGetFolderPath( -	       NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath))) +	if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath)))  	{  		configpath = szPath;  	}  #else -	std::string configpath = getenv("HOME"); +	configpath = getenv("HOME");  #endif  	configpath += SEP;  	configpath += CONFIGDIRNAME; @@ -79,9 +79,9 @@ static std::string getConfigPath()  /**   * Calling this makes sure that the config path exists   */ -static bool createConfigPath() +bool createConfigPath()  { -	std::string configpath = getConfigPath(); +	std::string const configpath = getConfigPath();  	struct stat st;  	if(stat(configpath.c_str(), &st) != 0) @@ -90,11 +90,10 @@ static bool createConfigPath()  		      configpath.c_str());  #if DG_PLATFORM == DG_PLATFORM_WINDOWS  		if(mkdir(configpath.c_str()) < 0) -		{  #else  		if(mkdir(configpath.c_str(), 0755) < 0) -		{  #endif +		{  			DEBUG(configfile, "Could not create config directory\n");  		} @@ -104,24 +103,26 @@ static bool createConfigPath()  	return true;  } +} // end anonymous namespace +  ConfigFile::ConfigFile(std::string const& filename)  	: filename(filename) -	, fp(nullptr)  {  }  ConfigFile::~ConfigFile()  { -	if (fp != nullptr) +	if (current_file.is_open())  	{  		DEBUG(configfile, "File has not been closed by the client...\n"); +		current_file.close();  	}  }  bool ConfigFile::load()  {  	DEBUG(configfile, "Loading config file...\n"); -	if(!open("r")) +	if(!open(std::ios_base::in))  	{  		return false;  	} @@ -129,20 +130,15 @@ bool ConfigFile::load()  	values.clear();  	std::string line; -	while(true) +	while(std::getline(current_file, line) && line != "")  	{ -		line = readLine(); - -		if(line == "") -			break; -  		if(!parseLine(line))  		{  			return false;  		}  	} -	close(); +	current_file.close();  	return true;  } @@ -153,18 +149,16 @@ bool ConfigFile::save()  	createConfigPath(); -	if(!open("w")) +	if(!open(std::ios_base::out))  	{  		return false;  	} -	std::map<std::string, std::string>::iterator v = values.begin(); -	for(; v != values.end(); ++v) +	for(auto const& value: values)  	{ -		fprintf(fp, "%s:%s\n", v->first.c_str(), v->second.c_str()); +		current_file << value.first << ":" << value.second << std::endl;  	} - -	close(); +	current_file.close();  	return true;  } @@ -185,65 +179,26 @@ void ConfigFile::setValue(const std::string& key, const std::string& value)  	values[key] = value;  } -bool ConfigFile::open(std::string mode) +bool ConfigFile::open(std::ios_base::openmode mode)  { -	if(fp) +	if(current_file.is_open())  	{ -		close(); +		current_file.close();  	} -	std::string configpath = getConfigPath(); - -	std::string configfile = configpath; -	configfile += SEP; -	configfile += filename; +	std::string filename = getConfigPath(); +	filename += SEP; +	filename += filename; -	DEBUG(configfile, "Opening config file '%s'\n", configfile.c_str()); -	fp = fopen(configfile.c_str(), mode.c_str()); +	DEBUG(configfile, "Opening config file '%s'\n", filename.c_str()); +	current_file.open(filename, mode); -	if(!fp) -	{ -		return false; -	} - -	return true; -} - -void ConfigFile::close() -{ -	fclose(fp); -	fp = nullptr; -} - -std::string ConfigFile::readLine() -{ -	if(!fp) -	{ -		return ""; -	} - -	std::string line; - -	char buf[1024]; -	while(!feof(fp)) -	{ -		char* s = fgets(buf, sizeof(buf), fp); -		if(s) -		{ -			line += buf; -			if(buf[strlen(buf) - 1] == '\n') -				break; -		} -	} - -	return line; +	return current_file.is_open();  }  bool ConfigFile::parseLine(const std::string& line)  { -	std::string key; -	std::string value; -	enum +	enum State  	{  		before_key,  		in_key, @@ -253,47 +208,52 @@ bool ConfigFile::parseLine(const std::string& line)  		in_value_single_quoted,  		in_value_double_quoted,  		after_value, -	} state = before_key; +	}; + +	std::string key; +	std::string value; +	State state = before_key; -	for(std::size_t p = 0; p < line.size(); ++p) +	for(std::size_t pos = 0; pos < line.size(); ++pos)  	{ +		auto c = line[pos];  		switch(state)  		{  		case before_key: -			if(line[p] == '#') +			if(c == '#')  			{  				// Comment: Ignore line. -				p = line.size(); +				pos = line.size();  				continue;  			} -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				continue;  			} -			key += line[p]; +			key += c;  			state = in_key;  			break;  		case in_key: -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				state = after_key;  				continue;  			} -			if(line[p] == ':' || line[p] == '=') +			if(c == ':' || c == '=')  			{  				state = before_value;  				continue;  			} -			key += line[p]; +			key += c;  			break;  		case after_key: -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				continue;  			} -			if(line[p] == ':' || line[p] == '=') +			if(c == ':' || c == '=')  			{  				state = before_value;  				continue; @@ -305,67 +265,67 @@ bool ConfigFile::parseLine(const std::string& line)  			return false;  		case before_value: -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				continue;  			} -			if(line[p] == '\'') +			if(c == '\'')  			{  				state = in_value_single_quoted;  				continue;  			} -			if(line[p] == '"') +			if(c == '"')  			{  				state = in_value_double_quoted;  				continue;  			} -			value += line[p]; +			value += c;  			state = in_value;  			break;  		case in_value: -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				state = after_value;  				continue;  			} -			if(line[p] == '#') +			if(c == '#')  			{  				// Comment: Ignore the rest of the line. -				p = line.size(); +				pos = line.size();  				state = after_value;  				continue;  			} -			value += line[p]; +			value += c;  			break;  		case in_value_single_quoted: -			if(line[p] == '\'') +			if(c == '\'')  			{  				state = after_value;  				continue;  			} -			value += line[p]; +			value += c;  			break;  		case in_value_double_quoted: -			if(line[p] == '"') +			if(c == '"')  			{  				state = after_value;  				continue;  			} -			value += line[p]; +			value += c;  			break;  		case after_value: -			if(std::isspace(line[p])) +			if(std::isspace(c))  			{  				continue;  			} -			if(line[p] == '#') +			if(c == '#')  			{  				// Comment: Ignore the rest of the line. -				p = line.size(); +				pos = line.size();  				continue;  			}  			ERR(configfile, diff --git a/src/configfile.h b/src/configfile.h index 47ae80b..1513897 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -28,7 +28,7 @@  #include <string>  #include <map> -#include <stdio.h> +#include <fstream>  class ConfigFile  { @@ -45,11 +45,9 @@ public:  protected:  	std::map<std::string, std::string> values;  	std::string filename; +	std::fstream current_file; -	virtual bool open(std::string mode); -	void close(); +	virtual bool open(std::ios_base::openmode mode);  	std::string readLine();  	bool parseLine(const std::string& line); - -	FILE* fp;  }; diff --git a/test/configtest.cc b/test/configtest.cc index 85a59ca..953c899 100644 --- a/test/configtest.cc +++ b/test/configtest.cc @@ -41,10 +41,10 @@ public:  protected:  	// Overload the built-in open method to use local file instead of homedir. -	virtual bool open(std::string mode) +	virtual bool open(std::ios_base::openmode mode)  	{ -		fp = fopen("test.conf", mode.c_str()); -		return fp != NULL; +		current_file.open("test.conf", mode); +		return current_file.is_open();  	}  }; @@ -77,16 +77,20 @@ public:  		unlink("test.conf");  	} -	void writeFile(const char* str) +	void writeFile(const std::string& content, bool newline = true)  	{ -		FILE* fp = fopen("test.conf", "w"); -		fprintf(fp, "%s", str); -		fclose(fp); +		std::fstream file("test.conf", std::ios_base::out); +		file << content; +		if (newline) +		{ +			file << std::endl; +		} +		file.close();  	}  	void loading_no_newline()  	{ -		writeFile("a:b"); +		writeFile("a:b", false);  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -95,7 +99,7 @@ public:  	void loading_equal_sign()  	{ -		writeFile(" a =\tb\t\n"); +		writeFile(" a =\tb\t");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -104,7 +108,7 @@ public:  	void loading_newline()  	{ -		writeFile("a:b\n"); +		writeFile("a:b");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -113,7 +117,7 @@ public:  	void loading_padding_space()  	{ -		writeFile(" a : b "); +		writeFile(" a : b ", false);  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -122,7 +126,7 @@ public:  	void loading_padding_tab()  	{ -		writeFile("\ta\t:\tb\t"); +		writeFile("\ta\t:\tb\t", false);  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -131,7 +135,7 @@ public:  	void loading_padding_space_newline()  	{ -		writeFile(" a : b \n"); +		writeFile(" a : b ");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -140,7 +144,7 @@ public:  	void loading_padding_tab_newline()  	{ -		writeFile("\ta\t:\tb\t\n"); +		writeFile("\ta\t:\tb\t");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -149,7 +153,7 @@ public:  	void loading_comment()  	{ -		writeFile("# comment\na:b\n"); +		writeFile("# comment\na:b");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -158,7 +162,7 @@ public:  	void loading_inline_comment()  	{ -		writeFile("a:b #comment\n"); +		writeFile("a:b #comment");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -167,7 +171,7 @@ public:  	void loading_single_quoted_string()  	{ -		writeFile("a: '#\"b\" ' \n"); +		writeFile("a: '#\"b\" ' ");  		TestConfigFile cf;  		DGUNIT_ASSERT(cf.load()); @@ -176,7 +180,7 @@ public:  	void loading_double_quoted_string()  	{ -		writeFile("a: \"#'b' \" \n"); +		writeFile("a: \"#'b' \" ");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); @@ -201,7 +205,7 @@ public:  	void loading_error_string_not_terminated_single()  	{ -		writeFile("a:'b\n"); +		writeFile("a:'b");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(false, cf.load()); @@ -209,7 +213,7 @@ public:  	void loading_error_string_not_terminated_double()  	{ -		writeFile("a:\"b\n"); +		writeFile("a:\"b");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(false, cf.load()); @@ -217,7 +221,7 @@ public:  	void empty_value()  	{ -		writeFile("a:\n"); +		writeFile("a:");  		TestConfigFile cf;  		DGUNIT_ASSERT_EQUAL(true, cf.load()); | 
