diff --git a/Grbl_Esp32/src/Configuration/AfterParse.cpp b/Grbl_Esp32/src/Configuration/AfterParse.cpp index 3d4c3fa9..92cf9918 100644 --- a/Grbl_Esp32/src/Configuration/AfterParse.cpp +++ b/Grbl_Esp32/src/Configuration/AfterParse.cpp @@ -4,8 +4,7 @@ #include -namespace Configuration -{ +namespace Configuration { void AfterParse::handleDetail(const char* name, Configurable* value) { value->afterParse(); value->handle(*this); diff --git a/Grbl_Esp32/src/Configuration/AfterParse.h b/Grbl_Esp32/src/Configuration/AfterParse.h index 5f10b9db..05015b47 100644 --- a/Grbl_Esp32/src/Configuration/AfterParse.h +++ b/Grbl_Esp32/src/Configuration/AfterParse.h @@ -5,28 +5,26 @@ #include "../Pin.h" #include "HandlerBase.h" -namespace Configuration -{ +namespace Configuration { class Configurable; - class AfterParse : public HandlerBase - { + class AfterParse : public HandlerBase { AfterParse(const AfterParse&) = delete; AfterParse& operator=(const AfterParse&) = delete; protected: - void handleDetail(const char* name, Configurable* value) override; - bool matchesUninitialized(const char* name) override { return false; } + void handleDetail(const char* name, Configurable* value) override; + bool matchesUninitialized(const char* name) override { return false; } HandlerType handlerType() override { return HandlerType::AfterParse; } public: AfterParse() = default; - void handle(const char* name, bool& value) override { } - void handle(const char* name, int& value) override { } - void handle(const char* name, float& value) override { } - void handle(const char* name, double& value) override { } - void handle(const char* name, StringRange& value) override { } - void handle(const char* name, Pin& value) override { } + void handle(const char* name, bool& value) override {} + void handle(const char* name, int& value) override {} + void handle(const char* name, float& value) override {} + void handle(const char* name, double& value) override {} + void handle(const char* name, StringRange& value) override {} + void handle(const char* name, Pin& value) override {} }; } diff --git a/Grbl_Esp32/src/Configuration/Configurable.h b/Grbl_Esp32/src/Configuration/Configurable.h index 99959373..a58d80d9 100644 --- a/Grbl_Esp32/src/Configuration/Configurable.h +++ b/Grbl_Esp32/src/Configuration/Configurable.h @@ -3,14 +3,12 @@ #include "Generator.h" #include "Parser.h" -namespace Configuration -{ +namespace Configuration { class HandlerBase; - class Configurable - { + class Configurable { Configurable(const Configurable&) = delete; - Configurable(Configurable&&) = default; + Configurable(Configurable&&) = default; Configurable& operator=(const Configurable&) = delete; Configurable& operator=(Configurable&&) = default; @@ -18,7 +16,7 @@ namespace Configuration public: Configurable() = default; - virtual void validate() const = 0; + virtual void validate() const = 0; virtual void handle(HandlerBase& handler) = 0; virtual void afterParse() {} // virtual const char* name() const = 0; diff --git a/Grbl_Esp32/src/Configuration/Generator.cpp b/Grbl_Esp32/src/Configuration/Generator.cpp index fee14f7f..8e7ab3e0 100644 --- a/Grbl_Esp32/src/Configuration/Generator.cpp +++ b/Grbl_Esp32/src/Configuration/Generator.cpp @@ -5,27 +5,21 @@ #include #include -namespace Configuration -{ - void Generator::enter(const char* name) - { +namespace Configuration { + void Generator::enter(const char* name) { indent(); dst_ << name << ":\n"; indent_++; } - void Generator::add(Configuration::Configurable* configurable) - { - if (configurable != nullptr) - { + void Generator::add(Configuration::Configurable* configurable) { + if (configurable != nullptr) { configurable->handle(*this); } } - void Generator::leave() - { - if (!lastIsNewline_) - { + void Generator::leave() { + if (!lastIsNewline_) { dst_ << '\n'; lastIsNewline_ = true; } @@ -39,4 +33,4 @@ namespace Configuration leave(); } -} \ No newline at end of file +} diff --git a/Grbl_Esp32/src/Configuration/Generator.h b/Grbl_Esp32/src/Configuration/Generator.h index d9c794cc..9a56a7fb 100644 --- a/Grbl_Esp32/src/Configuration/Generator.h +++ b/Grbl_Esp32/src/Configuration/Generator.h @@ -7,23 +7,20 @@ #include "../StringStream.h" #include "HandlerBase.h" -namespace Configuration -{ +namespace Configuration { class Configurable; - class Generator : public HandlerBase - { + class Generator : public HandlerBase { Generator(const Generator&) = delete; Generator& operator=(const Generator&) = delete; - int indent_; + int indent_; SimpleOutputStream& dst_; - bool lastIsNewline_ = false; + bool lastIsNewline_ = false; inline void indent() { lastIsNewline_ = false; - for (int i = 0; i < indent_ * 2; ++i) - { + for (int i = 0; i < indent_ * 2; ++i) { dst_ << ' '; } } @@ -31,10 +28,10 @@ namespace Configuration void enter(const char* name); void add(Configuration::Configurable* configurable); void leave(); - + protected: - void handleDetail(const char* name, Configurable* value) override; - bool matchesUninitialized(const char* name) override { return false; } + void handleDetail(const char* name, Configurable* value) override; + bool matchesUninitialized(const char* name) override { return false; } HandlerType handlerType() override { return HandlerType::Generator; } public: diff --git a/Grbl_Esp32/src/Configuration/GenericFactory.h b/Grbl_Esp32/src/Configuration/GenericFactory.h index fe2fb31a..a18a4d3d 100644 --- a/Grbl_Esp32/src/Configuration/GenericFactory.h +++ b/Grbl_Esp32/src/Configuration/GenericFactory.h @@ -6,8 +6,7 @@ namespace Configuration { template - class GenericFactory - { + class GenericFactory { static GenericFactory& instance() { static GenericFactory instance_; return instance_; @@ -28,37 +27,26 @@ namespace Configuration { BuilderBase& operator=(const BuilderBase& o) = delete; virtual BaseType* create() const = 0; - const char* name() const { return name_; } + const char* name() const { return name_; } virtual ~BuilderBase() = default; }; std::vector builders_; - inline static void registerBuilder(BuilderBase* builder) - { - instance().builders_.push_back(builder); - } + inline static void registerBuilder(BuilderBase* builder) { instance().builders_.push_back(builder); } public: template - class InstanceBuilder : public BuilderBase - { + class InstanceBuilder : public BuilderBase { public: - InstanceBuilder(const char* name) : BuilderBase(name) { - instance().registerBuilder(this); - } + InstanceBuilder(const char* name) : BuilderBase(name) { instance().registerBuilder(this); } - BaseType* create() const override - { - return new DerivedType(); - } + BaseType* create() const override { return new DerivedType(); } }; - static void handle(Configuration::HandlerBase& handler, BaseType*& inst) - { - if (inst == nullptr) - { + static void handle(Configuration::HandlerBase& handler, BaseType*& inst) { + if (inst == nullptr) { for (auto it : instance().builders_) { if (handler.matchesUninitialized(it->name())) { inst = it->create(); @@ -67,11 +55,9 @@ namespace Configuration { return; } } - } - else - { + } else { handler.handleDetail(inst->name(), inst); } } }; -} \ No newline at end of file +} diff --git a/Grbl_Esp32/src/Configuration/HandlerBase.h b/Grbl_Esp32/src/Configuration/HandlerBase.h index a9c9ff46..9079c22e 100644 --- a/Grbl_Esp32/src/Configuration/HandlerBase.h +++ b/Grbl_Esp32/src/Configuration/HandlerBase.h @@ -4,36 +4,32 @@ #include "../Pin.h" #include "../StringRange.h" -namespace Configuration -{ +namespace Configuration { class Configurable; template class GenericFactory; - class HandlerBase - { + class HandlerBase { protected: virtual void handleDetail(const char* name, Configurable* value) = 0; - virtual bool matchesUninitialized(const char* name) = 0; + virtual bool matchesUninitialized(const char* name) = 0; template friend class GenericFactory; public: - virtual void handle(const char* name, bool& 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, float& 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, double& 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, 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; handle(name, range); - if (range.begin() != nullptr) - { + if (range.begin() != nullptr) { value = range.str(); } } @@ -42,15 +38,12 @@ namespace Configuration template void handle(const char* name, T*& value) { - if (handlerType() == HandlerType::Parser) - { - if (value == nullptr && matchesUninitialized(name)) - { + if (handlerType() == HandlerType::Parser) { + if (value == nullptr && matchesUninitialized(name)) { value = new T(); handleDetail(name, value); } - } - else { + } else { if (value != nullptr) { handleDetail(name, value); } @@ -58,6 +51,8 @@ namespace Configuration } template - void handle(const char* name, T& value) { handleDetail(name, &value); } + void handle(const char* name, T& value) { + handleDetail(name, &value); + } }; } diff --git a/Grbl_Esp32/src/Configuration/HandlerType.h b/Grbl_Esp32/src/Configuration/HandlerType.h index 104605c7..5bc3c606 100644 --- a/Grbl_Esp32/src/Configuration/HandlerType.h +++ b/Grbl_Esp32/src/Configuration/HandlerType.h @@ -1,13 +1,5 @@ #pragma once -namespace Configuration -{ - enum struct HandlerType - { - Parser, - AfterParse, - Runtime, - Generator, - Validator - }; +namespace Configuration { + enum struct HandlerType { Parser, AfterParse, Runtime, Generator, Validator }; } diff --git a/Grbl_Esp32/src/Configuration/LegacySettingHandler.h b/Grbl_Esp32/src/Configuration/LegacySettingHandler.h index a5fbf94f..1b49bbef 100644 --- a/Grbl_Esp32/src/Configuration/LegacySettingHandler.h +++ b/Grbl_Esp32/src/Configuration/LegacySettingHandler.h @@ -2,24 +2,20 @@ #include "LegacySettingRegistry.h" -namespace Configuration -{ - class LegacySettingHandler - { +namespace Configuration { + class LegacySettingHandler { public: - inline LegacySettingHandler() { - LegacySettingRegistry::registerHandler(this); - } + inline LegacySettingHandler() { LegacySettingRegistry::registerHandler(this); } LegacySettingHandler(const LegacySettingHandler&) = delete; - LegacySettingHandler(LegacySettingHandler&&) = delete; + LegacySettingHandler(LegacySettingHandler&&) = delete; LegacySettingHandler& operator=(const LegacySettingHandler&) = delete; LegacySettingHandler& operator=(LegacySettingHandler&&) = delete; - virtual int index() = 0; + virtual int index() = 0; virtual void handle(const char* value) = 0; virtual ~LegacySettingHandler() { // Remove from factory? We shouldn't remove handlers... } }; -} \ No newline at end of file +} diff --git a/Grbl_Esp32/src/Configuration/LegacySettingRegistry.cpp b/Grbl_Esp32/src/Configuration/LegacySettingRegistry.cpp index 97c9ebfc..efdb0f79 100644 --- a/Grbl_Esp32/src/Configuration/LegacySettingRegistry.cpp +++ b/Grbl_Esp32/src/Configuration/LegacySettingRegistry.cpp @@ -2,17 +2,10 @@ #include "LegacySettingHandler.h" -namespace Configuration -{ - bool LegacySettingRegistry::isLegacySetting(const char* str) - { - return str[0] == '$' && (str[1] >= '0' && str[1] <= '9'); - } +namespace Configuration { + bool LegacySettingRegistry::isLegacySetting(const char* str) { return str[0] == '$' && (str[1] >= '0' && str[1] <= '9'); } - void LegacySettingRegistry::registerHandler(LegacySettingHandler* handler) - { - instance().handlers_.push_back(handler); - } + void LegacySettingRegistry::registerHandler(LegacySettingHandler* handler) { instance().handlers_.push_back(handler); } bool LegacySettingRegistry::tryHandleLegacy(const char* str) { if (isLegacySetting(str)) { @@ -21,8 +14,7 @@ namespace Configuration int value = 0; ++str; - while (*str && *str >= '0' && *str <= '9') - { + while (*str && *str >= '0' && *str <= '9') { value = value * 10 + (*str - '0'); ++str; } @@ -31,13 +23,11 @@ namespace Configuration ++str; handleLegacy(value, str); - } - else { + } else { log_warn("Incorrect setting '" << start << "': cannot find '='."); } return true; - } - else { + } else { return false; } } @@ -45,8 +35,7 @@ namespace Configuration void LegacySettingRegistry::handleLegacy(int index, const char* value) { bool handled = false; for (auto it : instance().handlers_) { - if (it->index() == index) - { + if (it->index() == index) { handled = true; it->handle(value); } diff --git a/Grbl_Esp32/src/Configuration/LegacySettingRegistry.h b/Grbl_Esp32/src/Configuration/LegacySettingRegistry.h index 109e0765..bd27027f 100644 --- a/Grbl_Esp32/src/Configuration/LegacySettingRegistry.h +++ b/Grbl_Esp32/src/Configuration/LegacySettingRegistry.h @@ -6,8 +6,7 @@ namespace Configuration { class LegacySettingHandler; - class LegacySettingRegistry - { + class LegacySettingRegistry { static LegacySettingRegistry& instance() { static LegacySettingRegistry instance_; return instance_; diff --git a/Grbl_Esp32/src/Configuration/Parser.cpp b/Grbl_Esp32/src/Configuration/Parser.cpp index 98477374..3de08576 100644 --- a/Grbl_Esp32/src/Configuration/Parser.cpp +++ b/Grbl_Esp32/src/Configuration/Parser.cpp @@ -17,8 +17,7 @@ namespace Configuration { // Attempt to use the correct position in the parser: if (current_.keyEnd_) { throw ParseException(start_, current_.keyEnd_, description); - } - else { + } else { 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 // the *right* section tho. auto last = indentStack_.top(); - indent_ = last; + indent_ = last; indentStack_.pop(); if (last == token_.indent_) { @@ -92,21 +91,21 @@ namespace Configuration { } return StringRange(current_.sValueStart_, current_.sValueEnd_); } - + bool Parser::boolValue() const { if (current_.kind_ != TokenKind::Boolean) { parseError("Expected a boolean value (e.g. true or value)"); } return current_.bValue_; } - + int Parser::intValue() const { if (current_.kind_ != TokenKind::IntegerValue) { parseError("Expected an integer value (e.g. 123456)"); } return current_.iValue_; } - + double Parser::doubleValue() const { if (current_.kind_ != TokenKind::FloatingPoint) { parseError("Expected a float value (e.g. 123.456)"); @@ -114,8 +113,7 @@ namespace Configuration { return current_.fValue_; } - Pin Parser::pinValue() const - { + Pin Parser::pinValue() const { if (current_.kind_ != TokenKind::String) { parseError("Expected a string value (e.g. 'foo')"); } diff --git a/Grbl_Esp32/src/Configuration/Parser.h b/Grbl_Esp32/src/Configuration/Parser.h index f68e2b8b..8ae169e0 100644 --- a/Grbl_Esp32/src/Configuration/Parser.h +++ b/Grbl_Esp32/src/Configuration/Parser.h @@ -15,7 +15,7 @@ namespace Configuration { std::stack indentStack_; TokenData current_; - int indent_ = 0; + int indent_ = 0; void parseError(const char* description) const; @@ -39,16 +39,15 @@ namespace Configuration { void leave(); inline bool is(const char* expected) const { - return current_.keyStart_ != nullptr && - !strncmp(expected, current_.keyStart_, size_t(current_.keyEnd_ - current_.keyStart_)); + return current_.keyStart_ != nullptr && !strncmp(expected, current_.keyStart_, size_t(current_.keyEnd_ - current_.keyStart_)); } inline StringRange key() const { return StringRange(current_.keyStart_, current_.keyEnd_); } StringRange stringValue() const; - bool boolValue() const; - int intValue() const; - double doubleValue() const; - Pin pinValue() const; + bool boolValue() const; + int intValue() const; + double doubleValue() const; + Pin pinValue() const; }; } diff --git a/Grbl_Esp32/src/Configuration/RuntimeSetting.cpp b/Grbl_Esp32/src/Configuration/RuntimeSetting.cpp index 4a868317..caa0c3a2 100644 --- a/Grbl_Esp32/src/Configuration/RuntimeSetting.cpp +++ b/Grbl_Esp32/src/Configuration/RuntimeSetting.cpp @@ -2,20 +2,15 @@ #include -namespace Configuration -{ - void RuntimeSetting::handleDetail(const char* name, Configuration::Configurable* value) - { - if (is(name) && this->value() == nullptr) - { +namespace Configuration { + void RuntimeSetting::handleDetail(const char* name, Configuration::Configurable* value) { + if (is(name) && this->value() == nullptr) { auto previous = start_; // Figure out next node auto next = start_; - for (; *next && *next != '=' && *next != '/'; ++next) - { - } - + for (; *next && *next != '=' && *next != '/'; ++next) {} + // Do we have a child? if (*next == '/') { ++next; @@ -30,35 +25,27 @@ namespace Configuration } } - void RuntimeSetting::handle(const char* name, int& value) - { - if (is(name) && this->value() != nullptr) - { + void RuntimeSetting::handle(const char* name, int& value) { + if (is(name) && this->value() != nullptr) { value = atoi(this->value()); } } - void RuntimeSetting::handle(const char* name, double& value) - { - if (is(name) && this->value() != nullptr) - { + void RuntimeSetting::handle(const char* name, double& value) { + if (is(name) && this->value() != nullptr) { char* floatEnd; value = strtod(this->value(), &floatEnd); } } - void RuntimeSetting::handle(const char* name, StringRange& value) - { - if (is(name) && this->value() != nullptr) - { + void RuntimeSetting::handle(const char* name, StringRange& value) { + if (is(name) && this->value() != nullptr) { value = this->value(); } } - void RuntimeSetting::handle(const char* name, Pin& value) - { - if (is(name) && this->value() != nullptr) - { + void RuntimeSetting::handle(const char* name, Pin& value) { + if (is(name) && this->value() != nullptr) { value = Pin::create(StringRange(this->value())); } } diff --git a/Grbl_Esp32/src/Configuration/RuntimeSetting.h b/Grbl_Esp32/src/Configuration/RuntimeSetting.h index bc1bb306..acacd071 100644 --- a/Grbl_Esp32/src/Configuration/RuntimeSetting.h +++ b/Grbl_Esp32/src/Configuration/RuntimeSetting.h @@ -3,30 +3,28 @@ #include "HandlerBase.h" #include "Configurable.h" -namespace Configuration -{ - class RuntimeSetting : public Configuration::HandlerBase - { +namespace Configuration { + class RuntimeSetting : public Configuration::HandlerBase { private: - const char* setting_; // $foo/bar=12 + const char* setting_; // $foo/bar=12 const char* start_; bool is(const char* name) const { if (start_ != nullptr) { auto len = strlen(name); return !strncmp(name, start_, len) && (start_[len] == '=' || start_[len] == '/'); - } - else { + } else { return false; } } - const char* value() const - { - for (const char* it = start_; *it; ++it) - { - if (*it == '/') { return nullptr; } - else if (*it == '=') { return it + 1; } + const char* value() const { + for (const char* it = start_; *it; ++it) { + if (*it == '/') { + return nullptr; + } else if (*it == '=') { + return it + 1; + } } return nullptr; } @@ -37,7 +35,7 @@ namespace Configuration bool matchesUninitialized(const char* name) override { return false; } 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, double& value) override; diff --git a/Grbl_Esp32/src/Configuration/Tokenizer.cpp b/Grbl_Esp32/src/Configuration/Tokenizer.cpp index 9ece71a0..c46608c6 100644 --- a/Grbl_Esp32/src/Configuration/Tokenizer.cpp +++ b/Grbl_Esp32/src/Configuration/Tokenizer.cpp @@ -6,7 +6,7 @@ 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 (EqualsCaseInsensitive("---")) { for (int i = 0; i < 3; ++i) { @@ -39,164 +39,158 @@ namespace Configuration { if (!Eof()) { switch (Current()) { - case '\t': - // 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."); - break; + case '\t': + // 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."); + break; - case '#': // Comment till end of line - Inc(); - while (!Eof() && !IsEndLine()) { + case '#': // Comment till end of line Inc(); - } - return; - - case '\r': - 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; + while (!Eof() && !IsEndLine()) { + Inc(); + } + return; + case '\r': + case '\n': Inc(); if (!Eof() && Current() == '\n') { Inc(); } // \r\n - } - else { - switch (Current()) { - case '"': - case '\'': { - auto delimiter = Current(); + goto parseAgain; - 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; + default: + if (!IsAlpha()) { + ParseError("Expected identifier."); } - // Skip more whitespaces + token_.keyStart_ = current_; + Inc(); + while (!Eof() && (IsAlpha() || IsDigit() || Current() == '_')) { + Inc(); + } + token_.keyEnd_ = current_; + + // Skip whitespaces: while (!Eof() && IsWhiteSpace()) { 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(); - while (!Eof() && !IsEndLine()) { - Inc(); - } } - // Should be EOL or EOF at this point. - if (!IsEndLine() && !Eof()) { - ParseError("Expected line end after key/value pair."); + token_.indent_ = indent; + if (IsEndLine()) { + 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 { - token_.kind_ = TokenKind::Eof; + } else { + token_.kind_ = TokenKind::Eof; token_.indent_ = 0; } } diff --git a/Grbl_Esp32/src/Configuration/Validator.cpp b/Grbl_Esp32/src/Configuration/Validator.cpp index b78f80d3..c380a16b 100644 --- a/Grbl_Esp32/src/Configuration/Validator.cpp +++ b/Grbl_Esp32/src/Configuration/Validator.cpp @@ -4,10 +4,9 @@ #include -namespace Configuration -{ +namespace Configuration { void Validator::handleDetail(const char* name, Configurable* value) { value->validate(); value->handle(*this); } -} \ No newline at end of file +} diff --git a/Grbl_Esp32/src/Configuration/Validator.h b/Grbl_Esp32/src/Configuration/Validator.h index cd06fa73..2d03903f 100644 --- a/Grbl_Esp32/src/Configuration/Validator.h +++ b/Grbl_Esp32/src/Configuration/Validator.h @@ -5,28 +5,26 @@ #include "../Pin.h" #include "HandlerBase.h" -namespace Configuration -{ +namespace Configuration { class Configurable; - class Validator : public HandlerBase - { + class Validator : public HandlerBase { Validator(const Validator&) = delete; Validator& operator=(const Validator&) = delete; protected: - void handleDetail(const char* name, Configurable* value) override; - bool matchesUninitialized(const char* name) override { return false; } + void handleDetail(const char* name, Configurable* value) override; + bool matchesUninitialized(const char* name) override { return false; } HandlerType handlerType() override { return HandlerType::Validator; } public: Validator() = default; - void handle(const char* name, bool& value) override { } - void handle(const char* name, int& value) override { } - void handle(const char* name, float& value) override { } - void handle(const char* name, double& value) override { } - void handle(const char* name, StringRange& value) override { } - void handle(const char* name, Pin& value) override { } + void handle(const char* name, bool& value) override {} + void handle(const char* name, int& value) override {} + void handle(const char* name, float& value) override {} + void handle(const char* name, double& value) override {} + void handle(const char* name, StringRange& value) override {} + void handle(const char* name, Pin& value) override {} }; }