summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Nusser <andre.nusser@googlemail.com>2020-04-07 22:19:10 +0200
committerAndré Nusser <andre.nusser@googlemail.com>2020-04-08 20:56:29 +0200
commitad8c3a178ddbf561e08d800372979eaf54986a9c (patch)
treed654b16f1cf79663acc875d7d8fb92132e217812
parent22d2d946da85e513b67affc87dfef2b42ded3b27 (diff)
Refactoring configfile.
The most important changes are: * general cleaning up * changing to platform independent newline in reading and writing * changing the Windows config directory to DrumGizmo (instead of .drumgizmo) And also, regarding the old code: C called, they wanted all their file operations back. ;-p
-rw-r--r--src/configfile.cc178
-rw-r--r--src/configfile.h8
-rw-r--r--test/configtest.cc46
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());