Browse Source

prepare for translator impl

pull/2/head
Skycoder42 7 years ago
parent
commit
9dac7d9f61
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 12
      tools/settingsgenerator/main.cpp
  2. 109
      tools/settingsgenerator/settingsconfigimpl.cpp
  3. 21
      tools/settingsgenerator/settingsconfigimpl.h
  4. 2
      tools/settingsgenerator/settingsgenerator.cpp
  5. 2
      tools/settingsgenerator/settingsgenerator.h
  6. 6
      tools/settingsgenerator/settingsgenerator.pro
  7. 109
      tools/settingsgenerator/settingstranslator.cpp
  8. 24
      tools/settingsgenerator/settingstranslator.h

12
tools/settingsgenerator/main.cpp

@ -5,6 +5,7 @@
#include <QDebug>
#include "settingsgenerator.h"
#include "settingstranslator.h"
int main(int argc, char *argv[])
{
@ -42,6 +43,16 @@ int main(int argc, char *argv[])
parser.process(a);
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")),
@ -54,3 +65,4 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
}
}

109
tools/settingsgenerator/settingsconfigimpl.cpp

@ -0,0 +1,109 @@
#include "settingsconfigimpl.h"
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QDebug>
namespace {
using SourceType = SettingsConfigBase::variant<SettingsConfigBase::SettingsConfigType, SettingsConfigBase::CategoryType, SettingsConfigBase::SectionType, SettingsConfigBase::GroupType, SettingsConfigBase::EntryType>;
template <typename TVariantTarget>
void convertElement(QXmlStreamReader &reader, TVariantTarget &, SourceType &&)
{
throw SettingsConfigBase::XmlException{reader, QStringLiteral("Unexpected root element in included file")};
}
template <typename TVariantTarget, typename TType, typename... TArgs>
void convertElement(QXmlStreamReader &reader, TVariantTarget &target, SourceType &&source)
{
if(nonstd::holds_alternative<TType>(source))
target = nonstd::get<TType>(std::move(source));
else
convertElement<TVariantTarget, TArgs...>(reader, target, std::move(source));
}
template <typename T>
struct VariantInfo {};
template <typename... TArgs>
struct VariantInfo<QList<SettingsConfigBase::variant<SettingsConfigBase::IncludeType, TArgs...>>>
{
using TargetType = SettingsConfigBase::variant<SettingsConfigBase::IncludeType, TArgs...>;
static void convert(QXmlStreamReader &reader, TargetType &target, SourceType &&source) {
convertElement<TargetType, TArgs...>(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<typename TGroup>
void SettingsConfigImpl::finishContents(QXmlStreamReader &reader, TGroup &group)
{
optional<std::size_t> index;
for(auto it = group.begin(); it != group.end();) {
// convert includes to the actual data
if(nonstd::holds_alternative<IncludeType>(*it)) {
if(!readGeneralInclude(reader, nonstd::get<IncludeType>(*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<typename TIter, typename TList>
bool SettingsConfigImpl::readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list)
{
try {
//make the path relative if possbile
if(dynamic_cast<QFileDevice*>(reader.device())) {
QFileInfo docInfo{static_cast<QFileDevice*>(reader.device())->fileName()};
include.includePath = docInfo.dir().absoluteFilePath(include.includePath);
}
// read the document
VariantInfo<TList>::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;
}
}

21
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 <typename TGroup>
void finishContents(QXmlStreamReader &reader, TGroup &group);
template <typename TIter, typename TList>
bool readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list);
};
#endif // SETTINGSCONFIGIMPL_H

2
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);

2
tools/settingsgenerator/settingsgenerator.h

@ -5,7 +5,7 @@
#include <QTextStream>
#include "qsettingsgenerator.h"
#include "settingstranslator.h"
#include "settingsconfigimpl.h"
class SettingsGenerator : public SettingsGeneratorBase
{

6
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 \

109
tools/settingsgenerator/settingstranslator.cpp

@ -1,108 +1,19 @@
#include "settingstranslator.h"
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QDebug>
SettingsTranslator::SettingsTranslator(const QString &srcPath) :
_srcFile{srcPath},
_src{&_srcFile}
{}
namespace {
using SourceType = SettingsConfigBase::variant<SettingsConfigBase::SettingsConfigType, SettingsConfigBase::CategoryType, SettingsConfigBase::SectionType, SettingsConfigBase::GroupType, SettingsConfigBase::EntryType>;
template <typename TVariantTarget>
void convertElement(QXmlStreamReader &reader, TVariantTarget &, SourceType &&)
{
throw SettingsConfigBase::XmlException{reader, QStringLiteral("Unexpected root element in included file")};
}
template <typename TVariantTarget, typename TType, typename... TArgs>
void convertElement(QXmlStreamReader &reader, TVariantTarget &target, SourceType &&source)
void SettingsTranslator::process(const QString &inPath)
{
if(nonstd::holds_alternative<TType>(source))
target = nonstd::get<TType>(std::move(source));
else
convertElement<TVariantTarget, TArgs...>(reader, target, std::move(source));
auto settings = readDocument(inPath);
if(!nonstd::holds_alternative<SettingsConfigType>(settings))
throw XmlException{inPath, 0, 0, QStringLiteral("Expected the root element to be a SettingsConfig element")};
writeTranslations(nonstd::get<SettingsConfigType>(settings));
}
template <typename T>
struct VariantInfo {};
template <typename... TArgs>
struct VariantInfo<QList<SettingsConfigBase::variant<SettingsConfigBase::IncludeType, TArgs...>>>
void SettingsTranslator::writeTranslations(const SettingsConfigBase::SettingsConfigType &settings)
{
using TargetType = SettingsConfigBase::variant<SettingsConfigBase::IncludeType, TArgs...>;
static void convert(QXmlStreamReader &reader, TargetType &target, SourceType &&source) {
convertElement<TargetType, TArgs...>(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)
{
hasNext = read_SettingsConfigContentGroup(reader, data, hasNext);
finishContents(reader, data.content);
return hasNext;
}
template<typename TGroup>
void SettingsTranslator::finishContents(QXmlStreamReader &reader, TGroup &group)
{
optional<std::size_t> index;
for(auto it = group.begin(); it != group.end();) {
// convert includes to the actual data
if(nonstd::holds_alternative<IncludeType>(*it)) {
if(!readGeneralInclude(reader, nonstd::get<IncludeType>(*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<typename TIter, typename TList>
bool SettingsTranslator::readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list)
{
try {
//make the path relative if possbile
if(dynamic_cast<QFileDevice*>(reader.device())) {
QFileInfo docInfo{static_cast<QFileDevice*>(reader.device())->fileName()};
include.includePath = docInfo.dir().absoluteFilePath(include.includePath);
}
// read the document
VariantInfo<TList>::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;
}
}

24
tools/settingsgenerator/settingstranslator.h

@ -1,21 +1,23 @@
#ifndef SETTINGSTRANSLATOR_H
#define SETTINGSTRANSLATOR_H
#include "settingsconfig.h"
#include <QFile>
#include <QTextStream>
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 <typename TGroup>
void finishContents(QXmlStreamReader &reader, TGroup &group);
template <typename TIter, typename TList>
bool readGeneralInclude(QXmlStreamReader &reader, IncludeType include, TIter &it, TList &list);
QFile _srcFile;
QTextStream _src;
void writeTranslations(const SettingsConfigType &settings);
};
#endif // SETTINGSTRANSLATOR_H

Loading…
Cancel
Save