mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-09-02 10:53:01 +02:00
clang-format Configuration/
This commit is contained in:
@@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
void AfterParse::handleDetail(const char* name, Configurable* value) {
|
void AfterParse::handleDetail(const char* name, Configurable* value) {
|
||||||
value->afterParse();
|
value->afterParse();
|
||||||
value->handle(*this);
|
value->handle(*this);
|
||||||
|
@@ -5,28 +5,26 @@
|
|||||||
#include "../Pin.h"
|
#include "../Pin.h"
|
||||||
#include "HandlerBase.h"
|
#include "HandlerBase.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
class Configurable;
|
class Configurable;
|
||||||
|
|
||||||
class AfterParse : public HandlerBase
|
class AfterParse : public HandlerBase {
|
||||||
{
|
|
||||||
AfterParse(const AfterParse&) = delete;
|
AfterParse(const AfterParse&) = delete;
|
||||||
AfterParse& operator=(const AfterParse&) = delete;
|
AfterParse& operator=(const AfterParse&) = delete;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleDetail(const char* name, Configurable* value) override;
|
void handleDetail(const char* name, Configurable* value) override;
|
||||||
bool matchesUninitialized(const char* name) override { return false; }
|
bool matchesUninitialized(const char* name) override { return false; }
|
||||||
HandlerType handlerType() override { return HandlerType::AfterParse; }
|
HandlerType handlerType() override { return HandlerType::AfterParse; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AfterParse() = default;
|
AfterParse() = default;
|
||||||
|
|
||||||
void handle(const char* name, bool& value) override { }
|
void handle(const char* name, bool& value) override {}
|
||||||
void handle(const char* name, int& value) override { }
|
void handle(const char* name, int& value) override {}
|
||||||
void handle(const char* name, float& value) override { }
|
void handle(const char* name, float& value) override {}
|
||||||
void handle(const char* name, double& value) override { }
|
void handle(const char* name, double& value) override {}
|
||||||
void handle(const char* name, StringRange& value) override { }
|
void handle(const char* name, StringRange& value) override {}
|
||||||
void handle(const char* name, Pin& value) override { }
|
void handle(const char* name, Pin& value) override {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -3,14 +3,12 @@
|
|||||||
#include "Generator.h"
|
#include "Generator.h"
|
||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
class HandlerBase;
|
class HandlerBase;
|
||||||
|
|
||||||
class Configurable
|
class Configurable {
|
||||||
{
|
|
||||||
Configurable(const Configurable&) = delete;
|
Configurable(const Configurable&) = delete;
|
||||||
Configurable(Configurable&&) = default;
|
Configurable(Configurable&&) = default;
|
||||||
|
|
||||||
Configurable& operator=(const Configurable&) = delete;
|
Configurable& operator=(const Configurable&) = delete;
|
||||||
Configurable& operator=(Configurable&&) = default;
|
Configurable& operator=(Configurable&&) = default;
|
||||||
@@ -18,7 +16,7 @@ namespace Configuration
|
|||||||
public:
|
public:
|
||||||
Configurable() = default;
|
Configurable() = default;
|
||||||
|
|
||||||
virtual void validate() const = 0;
|
virtual void validate() const = 0;
|
||||||
virtual void handle(HandlerBase& handler) = 0;
|
virtual void handle(HandlerBase& handler) = 0;
|
||||||
virtual void afterParse() {}
|
virtual void afterParse() {}
|
||||||
// virtual const char* name() const = 0;
|
// virtual const char* name() const = 0;
|
||||||
|
@@ -5,27 +5,21 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
void Generator::enter(const char* name) {
|
||||||
void Generator::enter(const char* name)
|
|
||||||
{
|
|
||||||
indent();
|
indent();
|
||||||
dst_ << name << ":\n";
|
dst_ << name << ":\n";
|
||||||
indent_++;
|
indent_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::add(Configuration::Configurable* configurable)
|
void Generator::add(Configuration::Configurable* configurable) {
|
||||||
{
|
if (configurable != nullptr) {
|
||||||
if (configurable != nullptr)
|
|
||||||
{
|
|
||||||
configurable->handle(*this);
|
configurable->handle(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::leave()
|
void Generator::leave() {
|
||||||
{
|
if (!lastIsNewline_) {
|
||||||
if (!lastIsNewline_)
|
|
||||||
{
|
|
||||||
dst_ << '\n';
|
dst_ << '\n';
|
||||||
lastIsNewline_ = true;
|
lastIsNewline_ = true;
|
||||||
}
|
}
|
||||||
@@ -39,4 +33,4 @@ namespace Configuration
|
|||||||
leave();
|
leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,23 +7,20 @@
|
|||||||
#include "../StringStream.h"
|
#include "../StringStream.h"
|
||||||
#include "HandlerBase.h"
|
#include "HandlerBase.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
class Configurable;
|
class Configurable;
|
||||||
|
|
||||||
class Generator : public HandlerBase
|
class Generator : public HandlerBase {
|
||||||
{
|
|
||||||
Generator(const Generator&) = delete;
|
Generator(const Generator&) = delete;
|
||||||
Generator& operator=(const Generator&) = delete;
|
Generator& operator=(const Generator&) = delete;
|
||||||
|
|
||||||
int indent_;
|
int indent_;
|
||||||
SimpleOutputStream& dst_;
|
SimpleOutputStream& dst_;
|
||||||
bool lastIsNewline_ = false;
|
bool lastIsNewline_ = false;
|
||||||
|
|
||||||
inline void indent() {
|
inline void indent() {
|
||||||
lastIsNewline_ = false;
|
lastIsNewline_ = false;
|
||||||
for (int i = 0; i < indent_ * 2; ++i)
|
for (int i = 0; i < indent_ * 2; ++i) {
|
||||||
{
|
|
||||||
dst_ << ' ';
|
dst_ << ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,10 +28,10 @@ namespace Configuration
|
|||||||
void enter(const char* name);
|
void enter(const char* name);
|
||||||
void add(Configuration::Configurable* configurable);
|
void add(Configuration::Configurable* configurable);
|
||||||
void leave();
|
void leave();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleDetail(const char* name, Configurable* value) override;
|
void handleDetail(const char* name, Configurable* value) override;
|
||||||
bool matchesUninitialized(const char* name) override { return false; }
|
bool matchesUninitialized(const char* name) override { return false; }
|
||||||
HandlerType handlerType() override { return HandlerType::Generator; }
|
HandlerType handlerType() override { return HandlerType::Generator; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
namespace Configuration {
|
namespace Configuration {
|
||||||
template <typename BaseType>
|
template <typename BaseType>
|
||||||
class GenericFactory
|
class GenericFactory {
|
||||||
{
|
|
||||||
static GenericFactory& instance() {
|
static GenericFactory& instance() {
|
||||||
static GenericFactory instance_;
|
static GenericFactory instance_;
|
||||||
return instance_;
|
return instance_;
|
||||||
@@ -28,37 +27,26 @@ namespace Configuration {
|
|||||||
BuilderBase& operator=(const BuilderBase& o) = delete;
|
BuilderBase& operator=(const BuilderBase& o) = delete;
|
||||||
|
|
||||||
virtual BaseType* create() const = 0;
|
virtual BaseType* create() const = 0;
|
||||||
const char* name() const { return name_; }
|
const char* name() const { return name_; }
|
||||||
|
|
||||||
virtual ~BuilderBase() = default;
|
virtual ~BuilderBase() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<BuilderBase*> builders_;
|
std::vector<BuilderBase*> builders_;
|
||||||
|
|
||||||
inline static void registerBuilder(BuilderBase* builder)
|
inline static void registerBuilder(BuilderBase* builder) { instance().builders_.push_back(builder); }
|
||||||
{
|
|
||||||
instance().builders_.push_back(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename DerivedType>
|
template <typename DerivedType>
|
||||||
class InstanceBuilder : public BuilderBase
|
class InstanceBuilder : public BuilderBase {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
InstanceBuilder(const char* name) : BuilderBase(name) {
|
InstanceBuilder(const char* name) : BuilderBase(name) { instance().registerBuilder(this); }
|
||||||
instance().registerBuilder(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseType* create() const override
|
BaseType* create() const override { return new DerivedType(); }
|
||||||
{
|
|
||||||
return new DerivedType();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle(Configuration::HandlerBase& handler, BaseType*& inst)
|
static void handle(Configuration::HandlerBase& handler, BaseType*& inst) {
|
||||||
{
|
if (inst == nullptr) {
|
||||||
if (inst == nullptr)
|
|
||||||
{
|
|
||||||
for (auto it : instance().builders_) {
|
for (auto it : instance().builders_) {
|
||||||
if (handler.matchesUninitialized(it->name())) {
|
if (handler.matchesUninitialized(it->name())) {
|
||||||
inst = it->create();
|
inst = it->create();
|
||||||
@@ -67,11 +55,9 @@ namespace Configuration {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
handler.handleDetail(inst->name(), inst);
|
handler.handleDetail(inst->name(), inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -4,36 +4,32 @@
|
|||||||
#include "../Pin.h"
|
#include "../Pin.h"
|
||||||
#include "../StringRange.h"
|
#include "../StringRange.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
class Configurable;
|
class Configurable;
|
||||||
|
|
||||||
template <typename BaseType>
|
template <typename BaseType>
|
||||||
class GenericFactory;
|
class GenericFactory;
|
||||||
|
|
||||||
class HandlerBase
|
class HandlerBase {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
virtual void handleDetail(const char* name, Configurable* value) = 0;
|
virtual void handleDetail(const char* name, Configurable* value) = 0;
|
||||||
virtual bool matchesUninitialized(const char* name) = 0;
|
virtual bool matchesUninitialized(const char* name) = 0;
|
||||||
|
|
||||||
template <typename BaseType>
|
template <typename BaseType>
|
||||||
friend class GenericFactory;
|
friend class GenericFactory;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void handle(const char* name, bool& value) = 0;
|
virtual void handle(const char* name, bool& value) = 0;
|
||||||
virtual void handle(const char* name, int& value) = 0;
|
virtual void handle(const char* name, int& value) = 0;
|
||||||
virtual void handle(const char* name, double& value) = 0;
|
virtual void handle(const char* name, double& value) = 0;
|
||||||
virtual void handle(const char* name, float& value) = 0;
|
virtual void handle(const char* name, float& value) = 0;
|
||||||
virtual void handle(const char* name, StringRange& value) = 0;
|
virtual void handle(const char* name, StringRange& value) = 0;
|
||||||
virtual void handle(const char* name, Pin& value) = 0;
|
virtual void handle(const char* name, Pin& value) = 0;
|
||||||
|
|
||||||
virtual void handle(const char* name, String& value)
|
virtual void handle(const char* name, String& value) {
|
||||||
{
|
|
||||||
StringRange range;
|
StringRange range;
|
||||||
handle(name, range);
|
handle(name, range);
|
||||||
if (range.begin() != nullptr)
|
if (range.begin() != nullptr) {
|
||||||
{
|
|
||||||
value = range.str();
|
value = range.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,15 +38,12 @@ namespace Configuration
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void handle(const char* name, T*& value) {
|
void handle(const char* name, T*& value) {
|
||||||
if (handlerType() == HandlerType::Parser)
|
if (handlerType() == HandlerType::Parser) {
|
||||||
{
|
if (value == nullptr && matchesUninitialized(name)) {
|
||||||
if (value == nullptr && matchesUninitialized(name))
|
|
||||||
{
|
|
||||||
value = new T();
|
value = new T();
|
||||||
handleDetail(name, value);
|
handleDetail(name, value);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (value != nullptr) {
|
if (value != nullptr) {
|
||||||
handleDetail(name, value);
|
handleDetail(name, value);
|
||||||
}
|
}
|
||||||
@@ -58,6 +51,8 @@ namespace Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void handle(const char* name, T& value) { handleDetail(name, &value); }
|
void handle(const char* name, T& value) {
|
||||||
|
handleDetail(name, &value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
enum struct HandlerType { Parser, AfterParse, Runtime, Generator, Validator };
|
||||||
enum struct HandlerType
|
|
||||||
{
|
|
||||||
Parser,
|
|
||||||
AfterParse,
|
|
||||||
Runtime,
|
|
||||||
Generator,
|
|
||||||
Validator
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@@ -2,24 +2,20 @@
|
|||||||
|
|
||||||
#include "LegacySettingRegistry.h"
|
#include "LegacySettingRegistry.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
class LegacySettingHandler {
|
||||||
class LegacySettingHandler
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
inline LegacySettingHandler() {
|
inline LegacySettingHandler() { LegacySettingRegistry::registerHandler(this); }
|
||||||
LegacySettingRegistry::registerHandler(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
LegacySettingHandler(const LegacySettingHandler&) = delete;
|
LegacySettingHandler(const LegacySettingHandler&) = delete;
|
||||||
LegacySettingHandler(LegacySettingHandler&&) = delete;
|
LegacySettingHandler(LegacySettingHandler&&) = delete;
|
||||||
LegacySettingHandler& operator=(const LegacySettingHandler&) = delete;
|
LegacySettingHandler& operator=(const LegacySettingHandler&) = delete;
|
||||||
LegacySettingHandler& operator=(LegacySettingHandler&&) = delete;
|
LegacySettingHandler& operator=(LegacySettingHandler&&) = delete;
|
||||||
|
|
||||||
virtual int index() = 0;
|
virtual int index() = 0;
|
||||||
virtual void handle(const char* value) = 0;
|
virtual void handle(const char* value) = 0;
|
||||||
virtual ~LegacySettingHandler() {
|
virtual ~LegacySettingHandler() {
|
||||||
// Remove from factory? We shouldn't remove handlers...
|
// Remove from factory? We shouldn't remove handlers...
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,10 @@
|
|||||||
|
|
||||||
#include "LegacySettingHandler.h"
|
#include "LegacySettingHandler.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
bool LegacySettingRegistry::isLegacySetting(const char* str) { return str[0] == '$' && (str[1] >= '0' && str[1] <= '9'); }
|
||||||
bool LegacySettingRegistry::isLegacySetting(const char* str)
|
|
||||||
{
|
|
||||||
return str[0] == '$' && (str[1] >= '0' && str[1] <= '9');
|
|
||||||
}
|
|
||||||
|
|
||||||
void LegacySettingRegistry::registerHandler(LegacySettingHandler* handler)
|
void LegacySettingRegistry::registerHandler(LegacySettingHandler* handler) { instance().handlers_.push_back(handler); }
|
||||||
{
|
|
||||||
instance().handlers_.push_back(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LegacySettingRegistry::tryHandleLegacy(const char* str) {
|
bool LegacySettingRegistry::tryHandleLegacy(const char* str) {
|
||||||
if (isLegacySetting(str)) {
|
if (isLegacySetting(str)) {
|
||||||
@@ -21,8 +14,7 @@ namespace Configuration
|
|||||||
int value = 0;
|
int value = 0;
|
||||||
++str;
|
++str;
|
||||||
|
|
||||||
while (*str && *str >= '0' && *str <= '9')
|
while (*str && *str >= '0' && *str <= '9') {
|
||||||
{
|
|
||||||
value = value * 10 + (*str - '0');
|
value = value * 10 + (*str - '0');
|
||||||
++str;
|
++str;
|
||||||
}
|
}
|
||||||
@@ -31,13 +23,11 @@ namespace Configuration
|
|||||||
++str;
|
++str;
|
||||||
|
|
||||||
handleLegacy(value, str);
|
handleLegacy(value, str);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
log_warn("Incorrect setting '" << start << "': cannot find '='.");
|
log_warn("Incorrect setting '" << start << "': cannot find '='.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +35,7 @@ namespace Configuration
|
|||||||
void LegacySettingRegistry::handleLegacy(int index, const char* value) {
|
void LegacySettingRegistry::handleLegacy(int index, const char* value) {
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
for (auto it : instance().handlers_) {
|
for (auto it : instance().handlers_) {
|
||||||
if (it->index() == index)
|
if (it->index() == index) {
|
||||||
{
|
|
||||||
handled = true;
|
handled = true;
|
||||||
it->handle(value);
|
it->handle(value);
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,7 @@
|
|||||||
namespace Configuration {
|
namespace Configuration {
|
||||||
class LegacySettingHandler;
|
class LegacySettingHandler;
|
||||||
|
|
||||||
class LegacySettingRegistry
|
class LegacySettingRegistry {
|
||||||
{
|
|
||||||
static LegacySettingRegistry& instance() {
|
static LegacySettingRegistry& instance() {
|
||||||
static LegacySettingRegistry instance_;
|
static LegacySettingRegistry instance_;
|
||||||
return instance_;
|
return instance_;
|
||||||
|
@@ -17,8 +17,7 @@ namespace Configuration {
|
|||||||
// Attempt to use the correct position in the parser:
|
// Attempt to use the correct position in the parser:
|
||||||
if (current_.keyEnd_) {
|
if (current_.keyEnd_) {
|
||||||
throw ParseException(start_, current_.keyEnd_, description);
|
throw ParseException(start_, current_.keyEnd_, description);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Tokenizer::ParseError(description);
|
Tokenizer::ParseError(description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +72,7 @@ namespace Configuration {
|
|||||||
// At this point, we just know the indent is smaller. We don't know if we're in
|
// At this point, we just know the indent is smaller. We don't know if we're in
|
||||||
// the *right* section tho.
|
// the *right* section tho.
|
||||||
auto last = indentStack_.top();
|
auto last = indentStack_.top();
|
||||||
indent_ = last;
|
indent_ = last;
|
||||||
indentStack_.pop();
|
indentStack_.pop();
|
||||||
|
|
||||||
if (last == token_.indent_) {
|
if (last == token_.indent_) {
|
||||||
@@ -92,21 +91,21 @@ namespace Configuration {
|
|||||||
}
|
}
|
||||||
return StringRange(current_.sValueStart_, current_.sValueEnd_);
|
return StringRange(current_.sValueStart_, current_.sValueEnd_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::boolValue() const {
|
bool Parser::boolValue() const {
|
||||||
if (current_.kind_ != TokenKind::Boolean) {
|
if (current_.kind_ != TokenKind::Boolean) {
|
||||||
parseError("Expected a boolean value (e.g. true or value)");
|
parseError("Expected a boolean value (e.g. true or value)");
|
||||||
}
|
}
|
||||||
return current_.bValue_;
|
return current_.bValue_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Parser::intValue() const {
|
int Parser::intValue() const {
|
||||||
if (current_.kind_ != TokenKind::IntegerValue) {
|
if (current_.kind_ != TokenKind::IntegerValue) {
|
||||||
parseError("Expected an integer value (e.g. 123456)");
|
parseError("Expected an integer value (e.g. 123456)");
|
||||||
}
|
}
|
||||||
return current_.iValue_;
|
return current_.iValue_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Parser::doubleValue() const {
|
double Parser::doubleValue() const {
|
||||||
if (current_.kind_ != TokenKind::FloatingPoint) {
|
if (current_.kind_ != TokenKind::FloatingPoint) {
|
||||||
parseError("Expected a float value (e.g. 123.456)");
|
parseError("Expected a float value (e.g. 123.456)");
|
||||||
@@ -114,8 +113,7 @@ namespace Configuration {
|
|||||||
return current_.fValue_;
|
return current_.fValue_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pin Parser::pinValue() const
|
Pin Parser::pinValue() const {
|
||||||
{
|
|
||||||
if (current_.kind_ != TokenKind::String) {
|
if (current_.kind_ != TokenKind::String) {
|
||||||
parseError("Expected a string value (e.g. 'foo')");
|
parseError("Expected a string value (e.g. 'foo')");
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ namespace Configuration {
|
|||||||
|
|
||||||
std::stack<int> indentStack_;
|
std::stack<int> indentStack_;
|
||||||
TokenData current_;
|
TokenData current_;
|
||||||
int indent_ = 0;
|
int indent_ = 0;
|
||||||
|
|
||||||
void parseError(const char* description) const;
|
void parseError(const char* description) const;
|
||||||
|
|
||||||
@@ -39,16 +39,15 @@ namespace Configuration {
|
|||||||
void leave();
|
void leave();
|
||||||
|
|
||||||
inline bool is(const char* expected) const {
|
inline bool is(const char* expected) const {
|
||||||
return current_.keyStart_ != nullptr &&
|
return current_.keyStart_ != nullptr && !strncmp(expected, current_.keyStart_, size_t(current_.keyEnd_ - current_.keyStart_));
|
||||||
!strncmp(expected, current_.keyStart_, size_t(current_.keyEnd_ - current_.keyStart_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StringRange key() const { return StringRange(current_.keyStart_, current_.keyEnd_); }
|
inline StringRange key() const { return StringRange(current_.keyStart_, current_.keyEnd_); }
|
||||||
|
|
||||||
StringRange stringValue() const;
|
StringRange stringValue() const;
|
||||||
bool boolValue() const;
|
bool boolValue() const;
|
||||||
int intValue() const;
|
int intValue() const;
|
||||||
double doubleValue() const;
|
double doubleValue() const;
|
||||||
Pin pinValue() const;
|
Pin pinValue() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,15 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
void RuntimeSetting::handleDetail(const char* name, Configuration::Configurable* value) {
|
||||||
void RuntimeSetting::handleDetail(const char* name, Configuration::Configurable* value)
|
if (is(name) && this->value() == nullptr) {
|
||||||
{
|
|
||||||
if (is(name) && this->value() == nullptr)
|
|
||||||
{
|
|
||||||
auto previous = start_;
|
auto previous = start_;
|
||||||
|
|
||||||
// Figure out next node
|
// Figure out next node
|
||||||
auto next = start_;
|
auto next = start_;
|
||||||
for (; *next && *next != '=' && *next != '/'; ++next)
|
for (; *next && *next != '=' && *next != '/'; ++next) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do we have a child?
|
// Do we have a child?
|
||||||
if (*next == '/') {
|
if (*next == '/') {
|
||||||
++next;
|
++next;
|
||||||
@@ -30,35 +25,27 @@ namespace Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeSetting::handle(const char* name, int& value)
|
void RuntimeSetting::handle(const char* name, int& value) {
|
||||||
{
|
if (is(name) && this->value() != nullptr) {
|
||||||
if (is(name) && this->value() != nullptr)
|
|
||||||
{
|
|
||||||
value = atoi(this->value());
|
value = atoi(this->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeSetting::handle(const char* name, double& value)
|
void RuntimeSetting::handle(const char* name, double& value) {
|
||||||
{
|
if (is(name) && this->value() != nullptr) {
|
||||||
if (is(name) && this->value() != nullptr)
|
|
||||||
{
|
|
||||||
char* floatEnd;
|
char* floatEnd;
|
||||||
value = strtod(this->value(), &floatEnd);
|
value = strtod(this->value(), &floatEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeSetting::handle(const char* name, StringRange& value)
|
void RuntimeSetting::handle(const char* name, StringRange& value) {
|
||||||
{
|
if (is(name) && this->value() != nullptr) {
|
||||||
if (is(name) && this->value() != nullptr)
|
|
||||||
{
|
|
||||||
value = this->value();
|
value = this->value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeSetting::handle(const char* name, Pin& value)
|
void RuntimeSetting::handle(const char* name, Pin& value) {
|
||||||
{
|
if (is(name) && this->value() != nullptr) {
|
||||||
if (is(name) && this->value() != nullptr)
|
|
||||||
{
|
|
||||||
value = Pin::create(StringRange(this->value()));
|
value = Pin::create(StringRange(this->value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,30 +3,28 @@
|
|||||||
#include "HandlerBase.h"
|
#include "HandlerBase.h"
|
||||||
#include "Configurable.h"
|
#include "Configurable.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
class RuntimeSetting : public Configuration::HandlerBase {
|
||||||
class RuntimeSetting : public Configuration::HandlerBase
|
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
const char* setting_; // $foo/bar=12
|
const char* setting_; // $foo/bar=12
|
||||||
const char* start_;
|
const char* start_;
|
||||||
|
|
||||||
bool is(const char* name) const {
|
bool is(const char* name) const {
|
||||||
if (start_ != nullptr) {
|
if (start_ != nullptr) {
|
||||||
auto len = strlen(name);
|
auto len = strlen(name);
|
||||||
return !strncmp(name, start_, len) && (start_[len] == '=' || start_[len] == '/');
|
return !strncmp(name, start_, len) && (start_[len] == '=' || start_[len] == '/');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* value() const
|
const char* value() const {
|
||||||
{
|
for (const char* it = start_; *it; ++it) {
|
||||||
for (const char* it = start_; *it; ++it)
|
if (*it == '/') {
|
||||||
{
|
return nullptr;
|
||||||
if (*it == '/') { return nullptr; }
|
} else if (*it == '=') {
|
||||||
else if (*it == '=') { return it + 1; }
|
return it + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -37,7 +35,7 @@ namespace Configuration
|
|||||||
bool matchesUninitialized(const char* name) override { return false; }
|
bool matchesUninitialized(const char* name) override { return false; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RuntimeSetting(const char* runtimeSetting) : setting_(runtimeSetting + 1), start_(runtimeSetting+1) {}
|
RuntimeSetting(const char* runtimeSetting) : setting_(runtimeSetting + 1), start_(runtimeSetting + 1) {}
|
||||||
|
|
||||||
void handle(const char* name, int& value) override;
|
void handle(const char* name, int& value) override;
|
||||||
void handle(const char* name, double& value) override;
|
void handle(const char* name, double& value) override;
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace Configuration {
|
namespace Configuration {
|
||||||
|
|
||||||
Tokenizer::Tokenizer(const char* start, const char* end) : current_(start), end_(end), start_(start), token_() {
|
Tokenizer::Tokenizer(const char* start, const char* end) : current_(start), end_(end), start_(start), token_() {
|
||||||
// If start is a yaml document start ('---' [newline]), skip that first.
|
// If start is a yaml document start ('---' [newline]), skip that first.
|
||||||
if (EqualsCaseInsensitive("---")) {
|
if (EqualsCaseInsensitive("---")) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
@@ -39,164 +39,158 @@ namespace Configuration {
|
|||||||
|
|
||||||
if (!Eof()) {
|
if (!Eof()) {
|
||||||
switch (Current()) {
|
switch (Current()) {
|
||||||
case '\t':
|
case '\t':
|
||||||
// TODO FIXME: We can do tabs or spaces, not both. However, we *could* let the user decide.
|
// TODO FIXME: We can do tabs or spaces, not both. However, we *could* let the user decide.
|
||||||
ParseError("Indentation through tabs is not allowed. Convert all tabs to spaces please.");
|
ParseError("Indentation through tabs is not allowed. Convert all tabs to spaces please.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#': // Comment till end of line
|
case '#': // Comment till end of line
|
||||||
Inc();
|
|
||||||
while (!Eof() && !IsEndLine()) {
|
|
||||||
Inc();
|
Inc();
|
||||||
}
|
while (!Eof() && !IsEndLine()) {
|
||||||
return;
|
Inc();
|
||||||
|
}
|
||||||
case '\r':
|
return;
|
||||||
case '\n':
|
|
||||||
Inc();
|
|
||||||
if (!Eof() && Current() == '\n') {
|
|
||||||
Inc();
|
|
||||||
} // \r\n
|
|
||||||
goto parseAgain;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (!IsAlpha()) {
|
|
||||||
ParseError("Expected identifier.");
|
|
||||||
}
|
|
||||||
|
|
||||||
token_.keyStart_ = current_;
|
|
||||||
Inc();
|
|
||||||
while (!Eof() && (IsAlpha() || IsDigit() || Current() == '_')) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
token_.keyEnd_ = current_;
|
|
||||||
|
|
||||||
// Skip whitespaces:
|
|
||||||
while (!Eof() && IsWhiteSpace()) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Current() != ':') {
|
|
||||||
ParseError("After a key or section name, we expect a colon character ':'.");
|
|
||||||
}
|
|
||||||
Inc();
|
|
||||||
|
|
||||||
// Skip whitespaces after the colon:
|
|
||||||
while (!Eof() && IsWhiteSpace()) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
token_.indent_ = indent;
|
|
||||||
if (IsEndLine()) {
|
|
||||||
token_.kind_ = TokenKind::Section;
|
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
Inc();
|
Inc();
|
||||||
if (!Eof() && Current() == '\n') {
|
if (!Eof() && Current() == '\n') {
|
||||||
Inc();
|
Inc();
|
||||||
} // \r\n
|
} // \r\n
|
||||||
}
|
goto parseAgain;
|
||||||
else {
|
|
||||||
switch (Current()) {
|
|
||||||
case '"':
|
|
||||||
case '\'': {
|
|
||||||
auto delimiter = Current();
|
|
||||||
|
|
||||||
token_.kind_ = TokenKind::String;
|
default:
|
||||||
Inc();
|
if (!IsAlpha()) {
|
||||||
token_.sValueStart_ = current_;
|
ParseError("Expected identifier.");
|
||||||
while (!Eof() && Current() != delimiter && !IsEndLine()) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
token_.sValueEnd_ = current_;
|
|
||||||
if (Current() != delimiter) {
|
|
||||||
ParseError("Could not find matching delimiter in string value.");
|
|
||||||
}
|
|
||||||
Inc();
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (EqualsCaseInsensitive("true")) {
|
|
||||||
token_.kind_ = TokenKind::Boolean;
|
|
||||||
token_.bValue_ = true;
|
|
||||||
|
|
||||||
for (auto i = 0; i < 4; ++i) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (EqualsCaseInsensitive("false")) {
|
|
||||||
token_.kind_ = TokenKind::Boolean;
|
|
||||||
token_.bValue_ = false;
|
|
||||||
|
|
||||||
for (auto i = 0; i < 5; ++i) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsDigit() || Current() == '-') {
|
|
||||||
auto doubleOrIntStart = current_;
|
|
||||||
|
|
||||||
int intValue = 0;
|
|
||||||
bool negative = false;
|
|
||||||
|
|
||||||
if (Current() == '-') {
|
|
||||||
Inc();
|
|
||||||
negative = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (IsDigit()) {
|
|
||||||
intValue = intValue * 10 + int(Current() - '0');
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Current() == 'e' || Current() == 'E' || Current() == '.' || // markers
|
|
||||||
(current_ - doubleOrIntStart) >= 9) { // liberal interpretation of 'out of int range'
|
|
||||||
char* floatEnd;
|
|
||||||
token_.fValue_ = strtod(doubleOrIntStart, &floatEnd);
|
|
||||||
token_.kind_ = TokenKind::FloatingPoint;
|
|
||||||
|
|
||||||
current_ = floatEnd;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (negative) {
|
|
||||||
intValue = -intValue;
|
|
||||||
}
|
|
||||||
token_.iValue_ = intValue;
|
|
||||||
token_.kind_ = TokenKind::IntegerValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If it's not 'true', not 'false', and not a digit, we have a string delimited by a whitespace
|
|
||||||
token_.kind_ = TokenKind::String;
|
|
||||||
token_.sValueStart_ = current_;
|
|
||||||
while (!Eof() && !IsWhiteSpace() && !IsEndLine()) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
token_.sValueEnd_ = current_;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip more whitespaces
|
token_.keyStart_ = current_;
|
||||||
|
Inc();
|
||||||
|
while (!Eof() && (IsAlpha() || IsDigit() || Current() == '_')) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
token_.keyEnd_ = current_;
|
||||||
|
|
||||||
|
// Skip whitespaces:
|
||||||
while (!Eof() && IsWhiteSpace()) {
|
while (!Eof() && IsWhiteSpace()) {
|
||||||
Inc();
|
Inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// A comment after a key-value pair is allowed.
|
if (Current() != ':') {
|
||||||
if (Current() == '#') {
|
ParseError("After a key or section name, we expect a colon character ':'.");
|
||||||
|
}
|
||||||
|
Inc();
|
||||||
|
|
||||||
|
// Skip whitespaces after the colon:
|
||||||
|
while (!Eof() && IsWhiteSpace()) {
|
||||||
Inc();
|
Inc();
|
||||||
while (!Eof() && !IsEndLine()) {
|
|
||||||
Inc();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be EOL or EOF at this point.
|
token_.indent_ = indent;
|
||||||
if (!IsEndLine() && !Eof()) {
|
if (IsEndLine()) {
|
||||||
ParseError("Expected line end after key/value pair.");
|
token_.kind_ = TokenKind::Section;
|
||||||
|
|
||||||
|
Inc();
|
||||||
|
if (!Eof() && Current() == '\n') {
|
||||||
|
Inc();
|
||||||
|
} // \r\n
|
||||||
|
} else {
|
||||||
|
switch (Current()) {
|
||||||
|
case '"':
|
||||||
|
case '\'': {
|
||||||
|
auto delimiter = Current();
|
||||||
|
|
||||||
|
token_.kind_ = TokenKind::String;
|
||||||
|
Inc();
|
||||||
|
token_.sValueStart_ = current_;
|
||||||
|
while (!Eof() && Current() != delimiter && !IsEndLine()) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
token_.sValueEnd_ = current_;
|
||||||
|
if (Current() != delimiter) {
|
||||||
|
ParseError("Could not find matching delimiter in string value.");
|
||||||
|
}
|
||||||
|
Inc();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (EqualsCaseInsensitive("true")) {
|
||||||
|
token_.kind_ = TokenKind::Boolean;
|
||||||
|
token_.bValue_ = true;
|
||||||
|
|
||||||
|
for (auto i = 0; i < 4; ++i) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
} else if (EqualsCaseInsensitive("false")) {
|
||||||
|
token_.kind_ = TokenKind::Boolean;
|
||||||
|
token_.bValue_ = false;
|
||||||
|
|
||||||
|
for (auto i = 0; i < 5; ++i) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
} else if (IsDigit() || Current() == '-') {
|
||||||
|
auto doubleOrIntStart = current_;
|
||||||
|
|
||||||
|
int intValue = 0;
|
||||||
|
bool negative = false;
|
||||||
|
|
||||||
|
if (Current() == '-') {
|
||||||
|
Inc();
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (IsDigit()) {
|
||||||
|
intValue = intValue * 10 + int(Current() - '0');
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Current() == 'e' || Current() == 'E' || Current() == '.' || // markers
|
||||||
|
(current_ - doubleOrIntStart) >= 9) { // liberal interpretation of 'out of int range'
|
||||||
|
char* floatEnd;
|
||||||
|
token_.fValue_ = strtod(doubleOrIntStart, &floatEnd);
|
||||||
|
token_.kind_ = TokenKind::FloatingPoint;
|
||||||
|
|
||||||
|
current_ = floatEnd;
|
||||||
|
} else {
|
||||||
|
if (negative) {
|
||||||
|
intValue = -intValue;
|
||||||
|
}
|
||||||
|
token_.iValue_ = intValue;
|
||||||
|
token_.kind_ = TokenKind::IntegerValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If it's not 'true', not 'false', and not a digit, we have a string delimited by a whitespace
|
||||||
|
token_.kind_ = TokenKind::String;
|
||||||
|
token_.sValueStart_ = current_;
|
||||||
|
while (!Eof() && !IsWhiteSpace() && !IsEndLine()) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
token_.sValueEnd_ = current_;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip more whitespaces
|
||||||
|
while (!Eof() && IsWhiteSpace()) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A comment after a key-value pair is allowed.
|
||||||
|
if (Current() == '#') {
|
||||||
|
Inc();
|
||||||
|
while (!Eof() && !IsEndLine()) {
|
||||||
|
Inc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be EOL or EOF at this point.
|
||||||
|
if (!IsEndLine() && !Eof()) {
|
||||||
|
ParseError("Expected line end after key/value pair.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
token_.kind_ = TokenKind::Eof;
|
||||||
token_.kind_ = TokenKind::Eof;
|
|
||||||
token_.indent_ = 0;
|
token_.indent_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,9 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
void Validator::handleDetail(const char* name, Configurable* value) {
|
void Validator::handleDetail(const char* name, Configurable* value) {
|
||||||
value->validate();
|
value->validate();
|
||||||
value->handle(*this);
|
value->handle(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,28 +5,26 @@
|
|||||||
#include "../Pin.h"
|
#include "../Pin.h"
|
||||||
#include "HandlerBase.h"
|
#include "HandlerBase.h"
|
||||||
|
|
||||||
namespace Configuration
|
namespace Configuration {
|
||||||
{
|
|
||||||
class Configurable;
|
class Configurable;
|
||||||
|
|
||||||
class Validator : public HandlerBase
|
class Validator : public HandlerBase {
|
||||||
{
|
|
||||||
Validator(const Validator&) = delete;
|
Validator(const Validator&) = delete;
|
||||||
Validator& operator=(const Validator&) = delete;
|
Validator& operator=(const Validator&) = delete;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleDetail(const char* name, Configurable* value) override;
|
void handleDetail(const char* name, Configurable* value) override;
|
||||||
bool matchesUninitialized(const char* name) override { return false; }
|
bool matchesUninitialized(const char* name) override { return false; }
|
||||||
HandlerType handlerType() override { return HandlerType::Validator; }
|
HandlerType handlerType() override { return HandlerType::Validator; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Validator() = default;
|
Validator() = default;
|
||||||
|
|
||||||
void handle(const char* name, bool& value) override { }
|
void handle(const char* name, bool& value) override {}
|
||||||
void handle(const char* name, int& value) override { }
|
void handle(const char* name, int& value) override {}
|
||||||
void handle(const char* name, float& value) override { }
|
void handle(const char* name, float& value) override {}
|
||||||
void handle(const char* name, double& value) override { }
|
void handle(const char* name, double& value) override {}
|
||||||
void handle(const char* name, StringRange& value) override { }
|
void handle(const char* name, StringRange& value) override {}
|
||||||
void handle(const char* name, Pin& value) override { }
|
void handle(const char* name, Pin& value) override {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user