diff --git a/Grbl_Esp32.sln b/Grbl_Esp32.sln index 338503ed..01d2fa27 100644 --- a/Grbl_Esp32.sln +++ b/Grbl_Esp32.sln @@ -16,7 +16,6 @@ Global EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.ActiveCfg = Debug|x64 - {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x64.Build.0 = Debug|x64 {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.ActiveCfg = Debug|Win32 {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Debug|x86.Build.0 = Debug|Win32 {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x64.ActiveCfg = Release|x64 @@ -24,6 +23,7 @@ Global {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.ActiveCfg = Release|Win32 {11C8A44F-A303-4885-B5AD-5B65F7FE41C0}.Release|x86.Build.0 = Release|Win32 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x64.ActiveCfg = Debug|Win32 + {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x64.Build.0 = Debug|Win32 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x86.ActiveCfg = Debug|Win32 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Debug|x86.Build.0 = Debug|Win32 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Release|x64.ActiveCfg = Release|x64 diff --git a/Grbl_Esp32/src/Configuration/Parser.h b/Grbl_Esp32/src/Configuration/Parser.h index 862767c1..e3b8e845 100644 --- a/Grbl_Esp32/src/Configuration/Parser.h +++ b/Grbl_Esp32/src/Configuration/Parser.h @@ -25,6 +25,7 @@ #include #include +#include namespace Configuration { class Parser : public Tokenizer { diff --git a/Grbl_Esp32/src/Configuration/Tokenizer.h b/Grbl_Esp32/src/Configuration/Tokenizer.h index b24d50d3..c2f7aeaa 100644 --- a/Grbl_Esp32/src/Configuration/Tokenizer.h +++ b/Grbl_Esp32/src/Configuration/Tokenizer.h @@ -80,11 +80,9 @@ namespace Configuration { int indent_; TokenKind kind_; - union { - struct { - const char* sValueStart_; - const char* sValueEnd_; - }; + struct { + const char* sValueStart_; + const char* sValueEnd_; }; } token_; diff --git a/Grbl_Esp32/src/StringRange.h b/Grbl_Esp32/src/StringRange.h index 3c094261..00c1578a 100644 --- a/Grbl_Esp32/src/StringRange.h +++ b/Grbl_Esp32/src/StringRange.h @@ -20,11 +20,7 @@ #include -#ifndef ESP32 -# include -#else -# include "WString.h" -#endif +#include "WString.h" class StringRange { const char* start_; @@ -104,7 +100,7 @@ public: inline bool isFloat(float& floatval) { char* floatEnd; - floatval = strtod(start_, &floatEnd); + floatval = float(strtod(start_, &floatEnd)); return floatEnd == end_; } }; diff --git a/Grbl_Esp32/test/Configuration/YamlParser.cpp b/Grbl_Esp32/test/Configuration/YamlParser.cpp new file mode 100644 index 00000000..08379404 --- /dev/null +++ b/Grbl_Esp32/test/Configuration/YamlParser.cpp @@ -0,0 +1,56 @@ +#include "../TestFramework.h" + +#include +#include + +namespace Configuration { + Test(YamlParser, BasicProperties) { + const char* config = + "a: aap\n" + "b: banaan\n" + "\n" + "c: chocolade"; + + Parser p(config, config + strlen(config)); + { + Assert(p.key().equals("a"), "Expected 'a'"); + Assert(p.stringValue().equals("aap"), "Expected 'aap'"); + } + + Assert(p.moveNext(), "Move next failed."); + { + Assert(p.key().equals("b"), "Expected 'b'"); + Assert(p.stringValue().equals("banaan"), "Expected 'banaan'"); + } + + Assert(p.moveNext(), "Move next failed."); + { + Assert(p.key().equals("c"), "Expected 'c'"); + Assert(p.stringValue().equals("chocolade"), "Expected 'chocolade'"); + } + Assert(!p.moveNext(), "Move next failed."); + } + + Test(YamlParser, SimpleSection) { + const char* config = "a: aap\nb: banaan\n\nc: chocolade"; + Parser p(config, config + strlen(config)); + { + Assert(p.key().equals("a"), "Expected 'a'"); + Assert(p.stringValue().equals("aap"), "Expected 'aap'"); + } + + Assert(p.moveNext(), "Move next failed."); + { + Assert(p.key().equals("b"), "Expected 'b'"); + Assert(p.stringValue().equals("banaan"), "Expected 'banaan'"); + } + + Assert(p.moveNext(), "Move next failed."); + { + Assert(p.key().equals("c"), "Expected 'c'"); + Assert(p.stringValue().equals("chocolade"), "Expected 'chocolade'"); + } + Assert(!p.moveNext(), "Move next failed."); + } + +} diff --git a/UnitTests.vcxproj b/UnitTests.vcxproj index 33a6fd33..f909fe72 100644 --- a/UnitTests.vcxproj +++ b/UnitTests.vcxproj @@ -33,12 +33,17 @@ + + + + + @@ -53,10 +58,13 @@ + + + @@ -68,6 +76,7 @@ + diff --git a/UnitTests.vcxproj.filters b/UnitTests.vcxproj.filters index de261aff..3f8c4fdd 100644 --- a/UnitTests.vcxproj.filters +++ b/UnitTests.vcxproj.filters @@ -19,6 +19,12 @@ {a166a529-634f-48dc-b368-6c03f6f0a36f} + + {6ae3ae24-fdcd-49f4-9797-a0b0f973c2dc} + + + {2b406c50-ba04-4c6d-a21e-0daedeeda9d9} + @@ -72,6 +78,21 @@ src\Pins + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + X86TestSupport + @@ -140,6 +161,15 @@ src\Pins + + test\Configuration + + + src\Configuration + + + src\Configuration + @@ -149,5 +179,8 @@ src\StackTrace + + src\Configuration + \ No newline at end of file diff --git a/X86TestSupport/IPAddress.h b/X86TestSupport/IPAddress.h new file mode 100644 index 00000000..6cc0862a --- /dev/null +++ b/X86TestSupport/IPAddress.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include "WString.h" + +class IPAddress { +private: + union { + uint8_t bytes[4]; // IPv4 address + uint32_t dword; + } _address; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _address.bytes; } + +public: + // Constructors + IPAddress() { _address.dword = 0; } + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { + _address.bytes[0] = first_octet; + _address.bytes[1] = second_octet; + _address.bytes[2] = third_octet; + _address.bytes[3] = fourth_octet; + } + IPAddress(uint32_t address) { _address.dword = address; } + IPAddress(const uint8_t* address) { memcpy(_address.bytes, address, 4); } + virtual ~IPAddress() {} + + bool fromString(const char* address) { throw "not implemented"; } + bool fromString(const String& address) { return fromString(address.c_str()); } + + // Overloaded cast operator to allow IPAddress objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() const { return _address.dword; } + bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; } + bool operator==(const uint8_t* addr) const { return (*this) == IPAddress(addr); } + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { return _address.bytes[index]; } + uint8_t& operator[](int index) { return _address.bytes[index]; } + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + IPAddress& operator=(const uint8_t* address) { memcpy(_address.bytes, address, 4); } + IPAddress& operator=(uint32_t address) { _address.dword = address; } + + String toString() const { throw "not implemented"; } +}; + +const IPAddress INADDR_NONE(0, 0, 0, 0);