summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CRSMConfig.hpp2
-rw-r--r--src/CRSMPackCompatibility.hpp2
-rw-r--r--src/CRSMStats.hpp2
-rw-r--r--src/ConfigBase.cpp207
-rw-r--r--src/ConfigBase.hpp330
-rw-r--r--src/CrServerManager.pro4
l---------[-rw-r--r--]src/Util.cpp192
l---------[-rw-r--r--]src/Util.hpp19
m---------src/qt-config0
9 files changed, 7 insertions, 751 deletions
diff --git a/src/CRSMConfig.hpp b/src/CRSMConfig.hpp
index ceba46b..76bc850 100644
--- a/src/CRSMConfig.hpp
+++ b/src/CRSMConfig.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "ConfigBase.hpp"
+#include "qt-config/ConfigBase.hpp"
#include "GreetingSetting.hpp"
class CRSMConfig : public ConfigBase {
diff --git a/src/CRSMPackCompatibility.hpp b/src/CRSMPackCompatibility.hpp
index 08b666e..3b13cda 100644
--- a/src/CRSMPackCompatibility.hpp
+++ b/src/CRSMPackCompatibility.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "ConfigBase.hpp"
+#include "qt-config/ConfigBase.hpp"
class CRSMPackCompatibility : public ConfigBase
{
diff --git a/src/CRSMStats.hpp b/src/CRSMStats.hpp
index 595c58b..bed5e26 100644
--- a/src/CRSMStats.hpp
+++ b/src/CRSMStats.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "ConfigBase.hpp"
+#include "qt-config/ConfigBase.hpp"
#include "ClientInfo.hpp"
#include "CmdFunctionRef.hpp"
diff --git a/src/ConfigBase.cpp b/src/ConfigBase.cpp
deleted file mode 100644
index ce4bcc0..0000000
--- a/src/ConfigBase.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-#include "CRSMConfig.hpp"
-
-#include <QFile>
-
-void ConfigBase::addConfigValue(QString name, ConfigValueBase* value)
-{
- configValues[name] = value;
-}
-
-void ConfigBase::setConfigValue(const QString &name, const QString &value)
-{
- ConfigValueBase& configValue = getConfigValue(name);
- configValue.setValue(Util::unescape(value));
-}
-
-QString ConfigBase::getConfigValueLine(const QString &name)
-{
- if(configValues.contains(name))
- {
- ConfigValueBase& value = *configValues[name];
- switch(value.type())
- {
- case ConfigValueType::Map:
- {
- QString ret;
- const QMap<QString, QString>& values = (dynamic_cast<ConfigValueMap*>(&value))->getValues();
- foreach(const QString& mapKey, values.keys())
- {
- ret += name + "[" + Util::escape(mapKey, '\\', "]") + "]" + " = " + Util::escape(values.value(mapKey)) + "\n";
- }
- return ret;
- break;
- }
- case ConfigValueType::List:
- {
- QString ret;
- foreach(const QString& val, (dynamic_cast<ConfigValueList*>(&value))->getValues())
- {
- ret += name + " += " + Util::escape(val) + "\n";
- }
- return ret;
- break;
- }
- default:
- return name + " = " + Util::escape(value.value()) + "\n";
- }
- }
- else
- {
- throw ConfigException("Unknown config value \"" + name.toStdString() + "\"");
- }
-}
-
-void ConfigBase::addConfigListEntry(const QString &name, const QString &value)
-{
- ConfigValueBase& configValue = getConfigValue(name);
- if(configValue.type() != ConfigValueType::List)
- {
- throw ConfigException("Cannot add a list entry to a non-list-config value \"" + name.toStdString() + "\"");
- }
- ((ConfigValueList*)&configValue)->append(Util::unescape(value));
-}
-
-void ConfigBase::removeConfigMapListEntry(const QString &name, const QString &value)
-{
- ConfigValueBase& configValue = getConfigValue(name);
- if(configValue.type() == ConfigValueType::List)
- {
- ((ConfigValueList*)&configValue)->remove(Util::unescape(value));
- }
- else if(configValue.type() == ConfigValueType::Map)
- {
- ((ConfigValueMap*)&configValue)->remove(Util::unescape(value));
- }
- else
- {
- throw ConfigException("Cannot remove a list entry from a value which is neither a list nor a map \"" + name.toStdString() + "\"");
- }
-}
-
-void ConfigBase::setConfigMapValue(const QString &name, const QString &key, const QString &value)
-{
- ConfigValueBase& configValue = getConfigValue(name);
- if(configValue.type() != ConfigValueType::Map)
- {
- throw ConfigException("Cannot set a map value on a non-map-config value \"" + name.toStdString() + "\"");
- }
- ((ConfigValueMap*)&configValue)->setKeyValue(Util::unescape(key), Util::unescape(value));
-}
-
-ConfigValueBase& ConfigBase::getConfigValue(const QString& name)
-{
- if(!configValues.contains(name))
- {
- throw ConfigException("Unknown config value \"" + name.toStdString() + "\"");
- }
- else
- {
- return *configValues[name];
- }
-}
-
-QString ConfigBase::read(const QString &fileName, bool writeDefault)
-{
- curFileName = fileName;
- QString ret = "";
-
- QFile config(fileName);
- if(!config.exists())
- {
- if(writeDefault)
- {
- if(write(fileName))
- {
- return fileName + ": The config-file did not exist, a new one with default values has been created.\n";
- }
- else
- {
- return fileName + ": The config-file did not exist, a new one could not be created.\n";
- }
- }
- else
- {
- return ret;
- }
- }
- else if(config.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QString line;
- for(size_t lineNr = 1; !config.atEnd(); ++lineNr)
- {
- try
- {
- line = config.readLine().trimmed();
- if(!line.isEmpty())
- {
- setConfigLine(line);
- }
- }
- catch(ConfigException e)
- {
- ret += fileName + ":" + QString::number(lineNr) + ": " + e.what() + "\n";
- }
- }
- }
- else
- {
- return fileName + ": The config-file could not be read.\n";
- }
-
- return ret;
-}
-
-bool ConfigBase::write(QString fileName)
-{
- if(fileName.isEmpty())
- {
- fileName = curFileName;
- }
- if(fileName.isEmpty())
- {
- return false;
- }
- QFile config(fileName);
- if(config.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- {
- foreach(const QString& key, configValues.keys())
- {
- config.write(getConfigValueLine(key).toUtf8());
- }
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void ConfigBase::setConfigLine(const QString &line)
-{
- static QRegExp valueExp(R"(^([^=]+)=(.*)$)");
- static QRegExp listExp(R"(^([^=]+)\+=(.*)$)");
- static QRegExp listMapRemoveExp(R"(^([^=]+)\-=(.*)$)");
- static QRegExp mapExp(R"(^([^\[]+)\[((?:[^\]\\]|\\\]|\\\\)+)\]\s*=\s*(.*)$)");
-
- if(listExp.exactMatch(line))
- {
- addConfigListEntry(listExp.cap(1).trimmed(), listExp.cap(2).trimmed());
- }
- else if(listMapRemoveExp.exactMatch(line))
- {
- removeConfigMapListEntry(listMapRemoveExp.cap(1).trimmed(), listMapRemoveExp.cap(2).trimmed());
- }
- else if(mapExp.exactMatch(line))
- {
- setConfigMapValue(mapExp.cap(1).trimmed(), mapExp.cap(2).trimmed(), mapExp.cap(3).trimmed());
- }
- else if(valueExp.exactMatch(line))
- {
- setConfigValue(valueExp.cap(1).trimmed(), valueExp.cap(2).trimmed());
- }
- else
- {
- throw ConfigException("Syntax error: unkown syntax");
- }
-}
diff --git a/src/ConfigBase.hpp b/src/ConfigBase.hpp
deleted file mode 100644
index ade454a..0000000
--- a/src/ConfigBase.hpp
+++ /dev/null
@@ -1,330 +0,0 @@
-#ifndef CONFIGBASE
-#define CONFIGBASE
-
-#include <QString>
-#include <QStringList>
-#include <QList>
-#include <QMap>
-#include <QRegularExpression>
-
-#include <exception>
-#include <type_traits>
-#include <limits>
-
-#include "Util.hpp"
-
-using ConfigException = std::logic_error;
-
-namespace ConfigValueType {
-enum Type {
- None,
- String,
- Integer,
- Boolean,
- List,
- Map
-};
-}
-
-class ConfigValueBase {
-public:
-
- virtual void setValue(const QString&) { }
- virtual QString value() { return ""; }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::None; }
-
-
-
- template<typename Type>
- static Type getValue(const QString& value);
-
- template<typename Type>
- static QString getStringValue(Type val);
-};
-
-template<typename Type, typename = void>
-class ConfigValue : public ConfigValueBase {
-public:
- virtual void setValue(const QString&) { throw ConfigException("Cannot assign"); }
- virtual QString value() { throw ConfigException("Cannot get the value"); }
-};
-
-using String = QString;
-using Integer = int;
-using Port = ushort;
-using Boolean = bool;
-#define List(Type) QList<Type>
-#define Map(KeyType, ValueType) QMap<KeyType, ValueType>
-
-
-#define ConfigVal(Value) {#Value, mkConfigValue(Value)}
-#define ConfigValEx(Value, ...) {#Value, mkConfigValue(Value, __VA_ARGS__)}
-
-template<>
-class ConfigValue<String> : public ConfigValueBase {
- String& config;
- bool trimmedQuotes = false;
-
-public:
- ConfigValue(String& config) : config(config) { }
-
- virtual void setValue(const QString& value) { config = Util::trimQuotes(value, trimmedQuotes); }
- virtual QString value()
- {
- static QRegularExpression quoteExp(R"(^(\s.*|.*\s)$)");
- if(trimmedQuotes || quoteExp.match(config).hasMatch())
- {
- return "\"" + config + "\"";
- }
- else
- {
- return config;
- }
- }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::String; }
-};
-
-template<typename Type>
-class ConfigValue<Type, typename std::enable_if<std::is_integral<Type>::value>::type> : public ConfigValueBase {
- Type& config;
-
-public:
- ConfigValue(Type& config) : config(config) { }
-
- virtual void setValue(const QString& value)
- {
- bool ok = true;
- long long longLongVal = value.toLongLong(&ok, 0);
- if(!ok) throw ConfigException("\"" + value.toStdString() + "\" could not be parsed as an Integer");
- if(longLongVal < std::numeric_limits<Type>::min() || longLongVal > std::numeric_limits<Type>::max()) throw ConfigException((QString::number(longLongVal) + " is out of range (" + QString::number(std::numeric_limits<Type>::min()) + " - " + QString::number(std::numeric_limits<Type>::max()) + ")").toStdString());
- config = static_cast<Type>(longLongVal);
- }
- virtual QString value() { return QString::number(config); }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::Integer; }
-};
-
-template<>
-class ConfigValue<Boolean> : public ConfigValueBase {
- Boolean& config;
-
-public:
- ConfigValue(Boolean& config) : config(config) { }
-
- virtual void setValue(const QString& value)
- {
- if(value == "true")
- {
- config = true;
- }
- else if(value == "false")
- {
- config = false;
- }
- else
- {
- throw ConfigException("\"" + value.toStdString() + "\" could not be parsed as a Boolean");
- }
- }
- virtual QString value() { return config ? "true" : "false"; }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::Boolean; }
-};
-
-class ConfigValueList : public ConfigValueBase {
-public:
- virtual void append(const QString& entry) = 0;
- virtual void remove(const QString& entry) = 0;
- virtual QStringList getValues() = 0;
-};
-
-class ConfigValueMap : public ConfigValueBase {
-public:
- virtual void setKeyValue(const QString& key, const QString& value) = 0;
- virtual void remove(const QString& key) = 0;
- virtual QMap<QString, QString> getValues() = 0;
-};
-
-template<typename Type>
-class ConfigValue<QList<Type>> : public ConfigValueList {
- using ListType = QList<Type>;
-
- ListType& config;
- const bool deduplicate;
- const QChar splitChar;
-
-public:
- ConfigValue(ListType& config, bool deduplicate = true, const QChar splitChar = ';') : config(config), deduplicate(deduplicate), splitChar(splitChar) {}
-
- virtual ListType& list() { return config; }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::List; }
-
- virtual void append(const QString &entry)
- {
- Type val = ConfigValueBase::getValue<Type>(entry);
- if(!deduplicate || !config.contains(val))
- {
- config.append(val);
- }
- }
-
- virtual void remove(const QString &entry) { config.removeAll(ConfigValueBase::getValue<Type>(entry)); }
-
- virtual QStringList getValues()
- {
- QStringList ret;
-
- foreach(Type val, config)
- {
- ret.append(ConfigValueBase::getStringValue(val));
- }
-
- return ret;
- }
-
- void setValue(const QString& value)
- {
- config.clear();
- if(value.isEmpty())
- {
- return;
- }
- QStringList parts = Util::splitEscaped(value, splitChar);
- foreach(const QString& part, parts)
- {
- config.append(ConfigValueBase::getValue<Type>(part));
- }
- }
-
- QString value()
- {
- QStringList parts;
- foreach(const Type& part, config)
- {
- parts.append(ConfigValueBase::getStringValue(part));
- }
- return Util::joinEscape(parts, splitChar);
- }
-};
-
-template<typename KeyType, typename ValueType>
-class ConfigValue<QMap<KeyType, ValueType>> : public ConfigValueMap {
- using MapType = QMap<KeyType, ValueType>;
-
- MapType& config;
- const QChar assignChar;
- const QChar splitChar;
-
-public:
- ConfigValue(MapType& config, const QChar assignChar = ':', const QChar splitChar = ';') : config(config), assignChar(assignChar), splitChar(splitChar) {}
-
- virtual MapType& map() { return config; }
- virtual ConfigValueType::Type type() { return ConfigValueType::Type::Map; }
-
- virtual void setKeyValue(const QString& key, const QString& value)
- {
- config[ConfigValueBase::getValue<KeyType>(key)] = ConfigValueBase::getValue<ValueType>(value);
- }
-
- virtual QMap<QString, QString> getValues()
- {
- QMap<QString, QString> ret;
-
- foreach(KeyType key, config.keys())
- {
- ret[ConfigValueBase::getStringValue(key)] = ConfigValueBase::getStringValue(config[key]);
- }
-
- return ret;
- }
-
- virtual void remove(const QString &key)
- {
- config.remove(ConfigValueBase::getValue<KeyType>(key));
- }
-
- QString value()
- {
- QStringList ret;
- foreach(const KeyType& key, config.keys())
- {
- ret.append(Util::joinEscape({ConfigValueBase::getStringValue(key), ConfigValueBase::getStringValue(config.value(key))}, assignChar));
- }
- return Util::joinEscape(ret, splitChar);
- }
-
- void setValue(const QString& value)
- {
- config.clear();
- if(value.isEmpty())
- {
- return;
- }
- QStringList parts = Util::splitEscaped(value, splitChar);
- foreach(const QString& part, parts)
- {
- QStringList parts = Util::splitEscaped(part, assignChar);
- if(parts.length() != 2)
- {
- throw ConfigException("Cannot parse corrupt map key-value-pair");
- }
- config[ConfigValueBase::getValue<KeyType>(parts.first())] = ConfigValueBase::getValue<ValueType>(parts.at(1));
- }
- }
-};
-
-template<typename Type>
-class ConfigValue<Type, typename std::enable_if<std::is_enum<Type>::value>::type> : public ConfigValue<typename std::underlying_type<Type>::type> {
- using UndType = typename std::underlying_type<Type>::type;
-public:
- ConfigValue(Type& config) : ConfigValue<UndType>::ConfigValue((UndType&)config) {}
-};
-
-template<typename Type, typename... Types>
-ConfigValue<Type>* mkConfigValue(Type& Value, Types... values)
-{
- return new ConfigValue<Type>(Value, values...);
-}
-
-template<typename Type>
-Type ConfigValueBase::getValue(const QString& value)
-{
- Type ret;
- ConfigValue<Type> val(ret);
- val.setValue(value);
- return ret;
-}
-
-template<typename Type>
-QString ConfigValueBase::getStringValue(Type value)
-{
- ConfigValue<Type> val(value);
- return val.value();
-}
-
-class ConfigBase
-{
-public:
- explicit ConfigBase(QMap<QString, ConfigValueBase*> configValues) : configValues(configValues) {}
-
- void setConfigValue(const QString& name, const QString& value);
- QString getConfigValueLine(const QString& name);
- void addConfigListEntry(const QString& name, const QString& value);
- void removeConfigMapListEntry(const QString &name, const QString &value);
- void setConfigMapValue(const QString& name, const QString& key, const QString& value);
-
- QString read(const QString& fileName, bool writeDefault = true);
- bool write(QString fileName = "");
-
- void setConfigLine(const QString& line);
-
-protected:
- void addConfigValue(QString name, ConfigValueBase *value);
- ConfigValueBase& getConfigValue(const QString &name);
-
- QMap<QString, ConfigValueBase*> configValues;
-
-private:
- QString curFileName = "";
-};
-
-#endif // CONFIGBASE
-
diff --git a/src/CrServerManager.pro b/src/CrServerManager.pro
index cca74e8..786c8a9 100644
--- a/src/CrServerManager.pro
+++ b/src/CrServerManager.pro
@@ -20,7 +20,7 @@ TEMPLATE = app
SOURCES += main.cpp \
crsm.cpp \
ProcessManager.cpp \
- ConfigBase.cpp \
+ qt-config/ConfigBase.cpp \
Util.cpp \
CRSMStats.cpp \
CRSMPackCompatibility.cpp \
@@ -32,7 +32,7 @@ HEADERS += \
crsm.hpp \
ProcessManager.hpp \
CRSMConfig.hpp \
- ConfigBase.hpp \
+ qt-config/ConfigBase.hpp \
Util.hpp \
CRSMStats.hpp \
CRSMPackCompatibility.hpp \
diff --git a/src/Util.cpp b/src/Util.cpp
index 41500da..bbc718a 100644..120000
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -1,191 +1 @@
-#include "Util.hpp"
-
-#include <QRegularExpression>
-
-namespace Util {
- QString trimQuotes(QString string, bool& trimmed)
- {
- if(string.isEmpty()) return string;
-
- trimmed = false;
- if(string.length() >= 2 && string.at(0) == '"' && string.at(string.length() - 1) == '"')
- {
- string.remove(0, 1);
- string.remove(string.length() - 1, 1);
- trimmed = true;
- }
- return string;
- }
-
- QString unescape(const QString &string, const QChar escapeChar)
- {
- if(string.isEmpty()) return string;
- QString ret;
- bool escaped = false;
- QChar c = string.at(0);
- for(int i = 0; i < string.length(); ++i)
- {
- c = string.at(i);
- if(!escaped)
- {
- if(c == escapeChar)
- {
- escaped = true;
- continue;
- }
- else
- {
- ret.append(c);
- }
- }
- else
- {
- if(unescapeChars.contains(c))
- {
- ret.append(unescapeChars.value(c));
- }
- else
- {
- ret.append(c);
- }
- escaped = false;
- }
- }
- if(escaped)
- {
- ret.append(escapeChar);
- }
- return ret;
- }
-
- QString escape(const QString &string, const QChar escapeChar, const QString &escapeChars)
- {
- QString ret;
-
- for(int i = 0; i < string.length(); ++i)
- {
- QChar c = string.at(i);
-
- if(c == escapeChar)
- {
- ret.append(escapeChar);
- ret.append(escapeChar);
- }
- else if(escapeChars.contains(c))
- {
- ret.append(escapeChar);
- ret.append(c);
- }
- else if(unescapeChars.values().contains(c))
- {
- ret.append(unescapeChars.key(c));
- }
- else
- {
- ret.append(c);
- }
- }
-
- return ret;
- }
-
- QString joinEscape(const QStringList &list, const QChar joinChar, const QChar escapeChar)
- {
- QString ret;
- bool first = true;
- foreach(const QString& part, list)
- {
- if(!first)
- {
- ret.append(joinChar);
- }
- else
- {
- first = false;
- }
- ret.append(escape(part, escapeChar, joinChar));
- }
- return ret;
- }
-
- QStringList splitEscaped(const QString &joined, const QChar splitChar, const QChar escapeChar)
- {
- QStringList ret;
-
- int partPos = 0;
- bool escaped = false;
- for(int i = 0; i < joined.length(); ++i)
- {
- QChar c = joined.at(i);
- if(!escaped)
- {
- if(c == escapeChar)
- {
- escaped = true;
- }
- else if(c == splitChar)
- {
- ret.append(Util::unescape(joined.mid(partPos, i - partPos), escapeChar));
- partPos = i + 1;
- }
- }
- else
- {
- escaped = false;
- }
- }
- ret.append(Util::unescape(joined.mid(partPos), escapeChar));
-
- return ret;
- }
-
- QString& unescapeClonkString(QString&& string)
- {
- static QRegularExpression escapeExp(R"(\\[0-7]+)");
- QRegularExpressionMatch match;
- while((match = escapeExp.match(string)).hasMatch())
- {
- unsigned char c = (unsigned char)match.capturedRef(0).mid(1).toInt(0, 8);
-
- string.replace(match.capturedStart(), match.capturedLength(), c);
- }
- return string;
- }
-
- int indexOfEscaped(const QString& string, const QChar subject, int startPos, const QChar escapeChar)
- {
- if(string.isEmpty())
- {
- return -1;
- }
- if(startPos < 0)
- {
- startPos += string.length();
- }
- bool escaped = false;
- for(int pos = startPos; pos < string.length(); ++pos)
- {
- QChar c = string.at(pos);
- if(!escaped)
- {
- if(c == escapeChar)
- {
- escaped = true;
- continue;
- }
- else
- {
- if(c == subject)
- {
- return pos;
- }
- }
- }
- else
- {
- escaped = false;
- }
- }
- return -1;
- }
-}
+qt-config/Util.cpp \ No newline at end of file
diff --git a/src/Util.hpp b/src/Util.hpp
index f90e108..bcc063c 100644..120000
--- a/src/Util.hpp
+++ b/src/Util.hpp
@@ -1,18 +1 @@
-#pragma once
-
-#include <QString>
-#include <QMap>
-
-namespace Util {
- static const QMap<QChar, QChar> unescapeChars {
- {'n', '\n'},
- };
-
- QString trimQuotes(QString string, bool& trimmed);
- QString unescape(const QString& string, const QChar escapeChar = '\\');
- QString escape(const QString& string, const QChar escapeChar = '\\', const QString& escapeChars = "");
- QString joinEscape(const QStringList& list, const QChar joinChar, const QChar escapeChar = '\\');
- QStringList splitEscaped(const QString& joined, const QChar splitChar, const QChar escapeChar = '\\');
- QString& unescapeClonkString(QString&& string);
- int indexOfEscaped(const QString& string, const QChar subject, int startPos = 0, const QChar escapeChar = '\\');
-}
+qt-config/Util.hpp \ No newline at end of file
diff --git a/src/qt-config b/src/qt-config
new file mode 160000
+Subproject 11a2c0f3e7fe3eff64fdd9ffb40727412e0d221