From 9dac7d9f61d4f563a86a0e3812467da135aa5bf8 Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Tue, 17 Jul 2018 18:52:54 +0200 Subject: [PATCH] prepare for translator impl --- tools/settingsgenerator/main.cpp | 32 +++-- .../settingsgenerator/settingsconfigimpl.cpp | 109 ++++++++++++++++++ tools/settingsgenerator/settingsconfigimpl.h | 21 ++++ tools/settingsgenerator/settingsgenerator.cpp | 2 +- tools/settingsgenerator/settingsgenerator.h | 2 +- tools/settingsgenerator/settingsgenerator.pro | 6 +- .../settingsgenerator/settingstranslator.cpp | 109 ++---------------- tools/settingsgenerator/settingstranslator.h | 24 ++-- 8 files changed, 181 insertions(+), 124 deletions(-) create mode 100644 tools/settingsgenerator/settingsconfigimpl.cpp create mode 100644 tools/settingsgenerator/settingsconfigimpl.h diff --git a/tools/settingsgenerator/main.cpp b/tools/settingsgenerator/main.cpp index 7197ad1..c588eab 100644 --- a/tools/settingsgenerator/main.cpp +++ b/tools/settingsgenerator/main.cpp @@ -5,6 +5,7 @@ #include #include "settingsgenerator.h" +#include "settingstranslator.h" int main(int argc, char *argv[]) { @@ -42,15 +43,26 @@ int main(int argc, char *argv[]) parser.process(a); - try { - SettingsGenerator generator { - parser.value(QStringLiteral("header")), - parser.value(QStringLiteral("impl")) - }; - generator.process(parser.value(QStringLiteral("in"))); - return EXIT_SUCCESS; - } catch (SettingsGenerator::Exception &e) { - qCritical() << e.what(); - return EXIT_FAILURE; + if(parser.isSet(QStringLiteral("translate"))) { + try { + SettingsTranslator translator {parser.value(QStringLiteral("impl"))}; + translator.process(parser.value(QStringLiteral("in"))); + return EXIT_SUCCESS; + } catch (SettingsTranslator::Exception &e) { + qCritical() << e.what(); + return EXIT_FAILURE; + } + } else { + try { + SettingsGenerator generator { + parser.value(QStringLiteral("header")), + parser.value(QStringLiteral("impl")) + }; + generator.process(parser.value(QStringLiteral("in"))); + return EXIT_SUCCESS; + } catch (SettingsGenerator::Exception &e) { + qCritical() << e.what(); + return EXIT_FAILURE; + } } } diff --git a/tools/settingsgenerator/settingsconfigimpl.cpp b/tools/settingsgenerator/settingsconfigimpl.cpp new file mode 100644 index 0000000..0be0620 --- /dev/null +++ b/tools/settingsgenerator/settingsconfigimpl.cpp @@ -0,0 +1,109 @@ +#include "settingsconfigimpl.h" + +#include +#include +#include + +namespace { + +using SourceType = SettingsConfigBase::variant; + +template +void convertElement(QXmlStreamReader &reader, TVariantTarget &, SourceType &&) +{ + throw SettingsConfigBase::XmlException{reader, QStringLiteral("Unexpected root element in included file")}; +} + +template +void convertElement(QXmlStreamReader &reader, TVariantTarget &target, SourceType &&source) +{ + if(nonstd::holds_alternative(source)) + target = nonstd::get(std::move(source)); + else + convertElement(reader, target, std::move(source)); +} + +template +struct VariantInfo {}; + +template +struct VariantInfo>> +{ + using TargetType = SettingsConfigBase::variant; + static void convert(QXmlStreamReader &reader, TargetType &target, SourceType &&source) { + convertElement(reader, target, std::move(source)); + } +}; + +} + +bool SettingsConfigImpl::finish_group_content(QXmlStreamReader &reader, GroupContentGroup &data, bool hasNext) +{ + hasNext = read_GroupContentGroup(reader, data, hasNext); + finishContents(reader, data.content); + return hasNext; +} + +bool SettingsConfigImpl::finish_section_content(QXmlStreamReader &reader, SectionContentGroup &data, bool hasNext) +{ + hasNext = read_SectionContentGroup(reader, data, hasNext); + finishContents(reader, data.content); + return hasNext; +} + +bool SettingsConfigImpl::finish_category_content(QXmlStreamReader &reader, CategoryContentGroup &data, bool hasNext) +{ + hasNext = read_CategoryContentGroup(reader, data, hasNext); + finishContents(reader, data.content); + return hasNext; +} + +bool SettingsConfigImpl::finish_settings_config_content(QXmlStreamReader &reader, SettingsConfigContentGroup &data, bool hasNext) +{ + hasNext = read_SettingsConfigContentGroup(reader, data, hasNext); + finishContents(reader, data.content); + return hasNext; +} + +template +void SettingsConfigImpl::finishContents(QXmlStreamReader &reader, TGroup &group) +{ + optional index; + for(auto it = group.begin(); it != group.end();) { + // convert includes to the actual data + if(nonstd::holds_alternative(*it)) { + if(!readGeneralInclude(reader, nonstd::get(*it), it, group)) + continue; + } + // verify that the contents are all of the same type + if(index) { + if(index.value() != it->index()) + throw XmlException{reader, QStringLiteral("Detected mixture of different child elements. Only includes and a single other type are allowed")}; + } else + index = it->index(); + ++it; + } +} + +template +bool SettingsConfigImpl::readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list) +{ + try { + //make the path relative if possbile + if(dynamic_cast(reader.device())) { + QFileInfo docInfo{static_cast(reader.device())->fileName()}; + include.includePath = docInfo.dir().absoluteFilePath(include.includePath); + } + // read the document + VariantInfo::convert(reader, *it, readDocument(include.includePath)); + return true; + } catch(FileException &e) { + if(include.optional) { + qWarning() << e.what(); + it = list.erase(it); + return false; + } else + throw; + } +} + diff --git a/tools/settingsgenerator/settingsconfigimpl.h b/tools/settingsgenerator/settingsconfigimpl.h new file mode 100644 index 0000000..cac452f --- /dev/null +++ b/tools/settingsgenerator/settingsconfigimpl.h @@ -0,0 +1,21 @@ +#ifndef SETTINGSCONFIGIMPL_H +#define SETTINGSCONFIGIMPL_H + +#include "settingsconfig.h" + +class SettingsConfigImpl : public SettingsConfigBase +{ +protected: + bool finish_group_content(QXmlStreamReader &reader, GroupContentGroup &data, bool hasNext) override; + bool finish_section_content(QXmlStreamReader &reader, SectionContentGroup &data, bool hasNext) override; + bool finish_category_content(QXmlStreamReader &reader, CategoryContentGroup &data, bool hasNext) override; + bool finish_settings_config_content(QXmlStreamReader &reader, SettingsConfigContentGroup &data, bool hasNext) override; + +private: + template + void finishContents(QXmlStreamReader &reader, TGroup &group); + template + bool readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list); +}; + +#endif // SETTINGSCONFIGIMPL_H diff --git a/tools/settingsgenerator/settingsgenerator.cpp b/tools/settingsgenerator/settingsgenerator.cpp index 3491e06..05e0dbd 100644 --- a/tools/settingsgenerator/settingsgenerator.cpp +++ b/tools/settingsgenerator/settingsgenerator.cpp @@ -64,7 +64,7 @@ void SettingsGenerator::read_included_file(QXmlStreamReader &reader, NodeContent if(subReader.name() == QStringLiteral("Settings")) { read_SettingsType(subReader, settings); } else if(subReader.name() == QStringLiteral("SettingsConfig")) { - SettingsTranslator confReader; + SettingsConfigImpl confReader; SettingsConfigBase::SettingsConfigType settingsConf; confReader.read_SettingsConfigType(subReader, settingsConf); convertFromConf(reader, settingsConf, settings); diff --git a/tools/settingsgenerator/settingsgenerator.h b/tools/settingsgenerator/settingsgenerator.h index 651931d..3dab964 100644 --- a/tools/settingsgenerator/settingsgenerator.h +++ b/tools/settingsgenerator/settingsgenerator.h @@ -5,7 +5,7 @@ #include #include "qsettingsgenerator.h" -#include "settingstranslator.h" +#include "settingsconfigimpl.h" class SettingsGenerator : public SettingsGeneratorBase { diff --git a/tools/settingsgenerator/settingsgenerator.pro b/tools/settingsgenerator/settingsgenerator.pro index 7e7a01d..4dafe7e 100644 --- a/tools/settingsgenerator/settingsgenerator.pro +++ b/tools/settingsgenerator/settingsgenerator.pro @@ -16,12 +16,14 @@ DEFINES += "BUNDLE_PREFIX=\\\"$$BUNDLE_PREFIX\\\"" HEADERS += \ settingsgenerator.h \ - settingstranslator.h + settingstranslator.h \ + settingsconfigimpl.h SOURCES += \ main.cpp \ settingsgenerator.cpp \ - settingstranslator.cpp + settingstranslator.cpp \ + settingsconfigimpl.cpp XML_SCHEMA_DEFINITIONS += \ qsettingsgenerator.xsd \ diff --git a/tools/settingsgenerator/settingstranslator.cpp b/tools/settingsgenerator/settingstranslator.cpp index df63f4e..84e72b1 100644 --- a/tools/settingsgenerator/settingstranslator.cpp +++ b/tools/settingsgenerator/settingstranslator.cpp @@ -1,108 +1,19 @@ #include "settingstranslator.h" -#include -#include -#include +SettingsTranslator::SettingsTranslator(const QString &srcPath) : + _srcFile{srcPath}, + _src{&_srcFile} +{} -namespace { - -using SourceType = SettingsConfigBase::variant; - -template -void convertElement(QXmlStreamReader &reader, TVariantTarget &, SourceType &&) -{ - throw SettingsConfigBase::XmlException{reader, QStringLiteral("Unexpected root element in included file")}; -} - -template -void convertElement(QXmlStreamReader &reader, TVariantTarget &target, SourceType &&source) -{ - if(nonstd::holds_alternative(source)) - target = nonstd::get(std::move(source)); - else - convertElement(reader, target, std::move(source)); -} - -template -struct VariantInfo {}; - -template -struct VariantInfo>> -{ - using TargetType = SettingsConfigBase::variant; - static void convert(QXmlStreamReader &reader, TargetType &target, SourceType &&source) { - convertElement(reader, target, std::move(source)); - } -}; - -} - -bool SettingsTranslator::finish_group_content(QXmlStreamReader &reader, GroupContentGroup &data, bool hasNext) -{ - hasNext = read_GroupContentGroup(reader, data, hasNext); - finishContents(reader, data.content); - return hasNext; -} - -bool SettingsTranslator::finish_section_content(QXmlStreamReader &reader, SectionContentGroup &data, bool hasNext) -{ - hasNext = read_SectionContentGroup(reader, data, hasNext); - finishContents(reader, data.content); - return hasNext; -} - -bool SettingsTranslator::finish_category_content(QXmlStreamReader &reader, CategoryContentGroup &data, bool hasNext) -{ - hasNext = read_CategoryContentGroup(reader, data, hasNext); - finishContents(reader, data.content); - return hasNext; -} - -bool SettingsTranslator::finish_settings_config_content(QXmlStreamReader &reader, SettingsConfigContentGroup &data, bool hasNext) +void SettingsTranslator::process(const QString &inPath) { - hasNext = read_SettingsConfigContentGroup(reader, data, hasNext); - finishContents(reader, data.content); - return hasNext; + auto settings = readDocument(inPath); + if(!nonstd::holds_alternative(settings)) + throw XmlException{inPath, 0, 0, QStringLiteral("Expected the root element to be a SettingsConfig element")}; + writeTranslations(nonstd::get(settings)); } -template -void SettingsTranslator::finishContents(QXmlStreamReader &reader, TGroup &group) +void SettingsTranslator::writeTranslations(const SettingsConfigBase::SettingsConfigType &settings) { - optional index; - for(auto it = group.begin(); it != group.end();) { - // convert includes to the actual data - if(nonstd::holds_alternative(*it)) { - if(!readGeneralInclude(reader, nonstd::get(*it), it, group)) - continue; - } - // verify that the contents are all of the same type - if(index) { - if(index.value() != it->index()) - throw XmlException{reader, QStringLiteral("Detected mixture of different child elements. Only includes and a single other type are allowed")}; - } else - index = it->index(); - ++it; - } -} -template -bool SettingsTranslator::readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list) -{ - try { - //make the path relative if possbile - if(dynamic_cast(reader.device())) { - QFileInfo docInfo{static_cast(reader.device())->fileName()}; - include.includePath = docInfo.dir().absoluteFilePath(include.includePath); - } - // read the document - VariantInfo::convert(reader, *it, readDocument(include.includePath)); - return true; - } catch(FileException &e) { - if(include.optional) { - qWarning() << e.what(); - it = list.erase(it); - return false; - } else - throw; - } } diff --git a/tools/settingsgenerator/settingstranslator.h b/tools/settingsgenerator/settingstranslator.h index dd832ea..5967ebf 100644 --- a/tools/settingsgenerator/settingstranslator.h +++ b/tools/settingsgenerator/settingstranslator.h @@ -1,21 +1,23 @@ #ifndef SETTINGSTRANSLATOR_H #define SETTINGSTRANSLATOR_H -#include "settingsconfig.h" +#include +#include -class SettingsTranslator : public SettingsConfigBase +#include "settingsconfigimpl.h" + +class SettingsTranslator : public SettingsConfigImpl { -protected: - bool finish_group_content(QXmlStreamReader &reader, GroupContentGroup &data, bool hasNext) override; - bool finish_section_content(QXmlStreamReader &reader, SectionContentGroup &data, bool hasNext) override; - bool finish_category_content(QXmlStreamReader &reader, CategoryContentGroup &data, bool hasNext) override; - bool finish_settings_config_content(QXmlStreamReader &reader, SettingsConfigContentGroup &data, bool hasNext) override; +public: + SettingsTranslator(const QString &srcPath); + + void process(const QString &inPath); private: - template - void finishContents(QXmlStreamReader &reader, TGroup &group); - template - bool readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list); + QFile _srcFile; + QTextStream _src; + + void writeTranslations(const SettingsConfigType &settings); }; #endif // SETTINGSTRANSLATOR_H