diff options
26 files changed, 331 insertions, 257 deletions
diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index 099cf76c..9fb964e9 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -89,8 +89,8 @@ namespace CanInterface bool SetRemoteDriverCurrents(const CanDriversData& data, const StringRef& reply) noexcept; bool SetRemoteDriverMicrostepping(const CanDriversData& data, const StringRef& reply) noexcept; bool SetRemotePressureAdvance(const CanDriversData& data, const StringRef& reply) noexcept; - GCodeResult ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; - GCodeResult SetRemoteDriverStallParameters(const CanDriversList& drivers, GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; + GCodeResult ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; + GCodeResult SetRemoteDriverStallParameters(const CanDriversList& drivers, GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; void WakeCanSender() noexcept; // Remote handle functions diff --git a/src/CAN/CanMessageGenericConstructor.h b/src/CAN/CanMessageGenericConstructor.h index 71a8c0cf..168a980f 100644 --- a/src/CAN/CanMessageGenericConstructor.h +++ b/src/CAN/CanMessageGenericConstructor.h @@ -12,9 +12,9 @@ #if SUPPORT_CAN_EXPANSION -#include "CanMessageFormats.h" -#include "GCodes/GCodeResult.h" -#include "GCodes/GCodeBuffer/ParseException.h" +#include <CanMessageFormats.h> +#include <GCodes/GCodeResult.h> +#include <GCodes/GCodeException.h> class GCodeBuffer; @@ -24,36 +24,36 @@ public: CanMessageGenericConstructor(const ParamDescriptor *p_param) noexcept; // Populate from a GCode message. Throws if an error occurs. - void PopulateFromCommand(GCodeBuffer& gb) THROWS_PARSE_ERROR; + void PopulateFromCommand(GCodeBuffer& gb) THROWS_GCODE_EXCEPTION; // Methods to add parameters - void AddU64Param(char c, uint64_t v) THROWS_PARSE_ERROR; - void AddUParam(char c, uint32_t v) THROWS_PARSE_ERROR; - void AddIParam(char c, int32_t v) THROWS_PARSE_ERROR; - void AddFParam(char c, float v) THROWS_PARSE_ERROR; - void AddCharParam(char c, char v) THROWS_PARSE_ERROR; - void AddStringParam(char c, const char* v) THROWS_PARSE_ERROR; + void AddU64Param(char c, uint64_t v) THROWS_GCODE_EXCEPTION; + void AddUParam(char c, uint32_t v) THROWS_GCODE_EXCEPTION; + void AddIParam(char c, int32_t v) THROWS_GCODE_EXCEPTION; + void AddFParam(char c, float v) THROWS_GCODE_EXCEPTION; + void AddCharParam(char c, char v) THROWS_GCODE_EXCEPTION; + void AddStringParam(char c, const char* v) THROWS_GCODE_EXCEPTION; GCodeResult SendAndGetResponse(CanMessageType msgType, CanAddress dest, const StringRef& reply) noexcept; private: // Append a value to the data, returning true if it wouldn't fit - void StoreValue(const void *vp, size_t sz) THROWS_PARSE_ERROR; + void StoreValue(const void *vp, size_t sz) THROWS_GCODE_EXCEPTION; // Append a value to the data, returning true if it wouldn't fit - template<class T> void StoreValue(const T& val) THROWS_PARSE_ERROR { StoreValue(&val, sizeof(T)); } + template<class T> void StoreValue(const T& val) THROWS_GCODE_EXCEPTION { StoreValue(&val, sizeof(T)); } // Insert a value in the data, returning true if it wouldn't fit - void InsertValue(const void *vp, size_t sz, size_t pos) THROWS_PARSE_ERROR; + void InsertValue(const void *vp, size_t sz, size_t pos) THROWS_GCODE_EXCEPTION; - static ParseException ConstructParseException(const char *msg) noexcept + static GCodeException ConstructParseException(const char *msg) noexcept { - return ParseException(-1, -1, msg); + return GCodeException(-1, -1, msg); } - static ParseException ConstructParseException(const char *msg, uint32_t param) noexcept + static GCodeException ConstructParseException(const char *msg, uint32_t param) noexcept { - return ParseException(-1, -1, msg, param); + return GCodeException(-1, -1, msg, param); } const ParamDescriptor * const paramTable; diff --git a/src/Endstops/EndstopsManager.h b/src/Endstops/EndstopsManager.h index bc0201ea..0c8d0313 100644 --- a/src/Endstops/EndstopsManager.h +++ b/src/Endstops/EndstopsManager.h @@ -54,14 +54,14 @@ public: void GetM119report(const StringRef& reply) noexcept; // Z probe - GCodeResult HandleM558(GCodeBuffer& gb, const StringRef &reply) THROWS_PARSE_ERROR; // M558 - GCodeResult HandleG31(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; // G31 + GCodeResult HandleM558(GCodeBuffer& gb, const StringRef &reply) THROWS_GCODE_EXCEPTION; // M558 + GCodeResult HandleG31(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; // G31 ZProbe& GetCurrentZProbe() const noexcept; const size_t GetCurrentZProbeNumber() const noexcept { return currentZProbeNumber; } ZProbe *GetZProbe(size_t num) const noexcept; void SetZProbeDefaults() noexcept; - GCodeResult ProgramZProbe(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; + GCodeResult ProgramZProbe(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; #if SUPPORT_CAN_EXPANSION void HandleRemoteInputChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept; diff --git a/src/Endstops/LocalZProbe.h b/src/Endstops/LocalZProbe.h index ef497c46..ea2aa14a 100644 --- a/src/Endstops/LocalZProbe.h +++ b/src/Endstops/LocalZProbe.h @@ -23,7 +23,7 @@ public: uint16_t GetRawReading() const noexcept override; void SetProbing(bool isProbing) const noexcept override; GCodeResult AppendPinNames(const StringRef& str) const noexcept override; - GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_PARSE_ERROR override; + GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION override; GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept override; #if ALLOCATE_DEFAULT_PORTS diff --git a/src/Endstops/RemoteZProbe.h b/src/Endstops/RemoteZProbe.h index f3d3a297..560ccdb5 100644 --- a/src/Endstops/RemoteZProbe.h +++ b/src/Endstops/RemoteZProbe.h @@ -24,7 +24,7 @@ public: uint16_t GetRawReading() const noexcept override { return 0; } void SetProbing(bool isProbing) const noexcept override; GCodeResult AppendPinNames(const StringRef& str) const noexcept override; - GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_PARSE_ERROR override; + GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION override; GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept override; GCodeResult Create(const StringRef& pinNames, const StringRef& reply) noexcept; diff --git a/src/Endstops/SwitchEndstop.h b/src/Endstops/SwitchEndstop.h index 09733484..0e4c46af 100644 --- a/src/Endstops/SwitchEndstop.h +++ b/src/Endstops/SwitchEndstop.h @@ -34,7 +34,7 @@ public: void HandleRemoteInputChange(CanAddress src, uint8_t handleMinor, bool state) noexcept override; #endif - GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; + GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; GCodeResult Configure(const char *pinNames, const StringRef& reply) noexcept; private: diff --git a/src/Endstops/ZProbe.h b/src/Endstops/ZProbe.h index 2dc76f90..77c1ea08 100644 --- a/src/Endstops/ZProbe.h +++ b/src/Endstops/ZProbe.h @@ -20,7 +20,7 @@ public: virtual uint16_t GetRawReading() const noexcept = 0; virtual void SetProbing(bool isProbing) const noexcept = 0; virtual GCodeResult AppendPinNames(const StringRef& str) const noexcept = 0; - virtual GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_PARSE_ERROR; // 'seen' is an in-out parameter + virtual GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION; // 'seen' is an in-out parameter virtual GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept; EndStopHit Stopped() const noexcept override; @@ -49,7 +49,7 @@ public: int GetReading() const noexcept; int GetSecondaryValues(int& v1, int& v2) noexcept; - GCodeResult HandleG31(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; + GCodeResult HandleG31(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; void SetTriggerHeight(float height) noexcept { triggerHeight = height; } void SetSaveToConfigOverride() noexcept { misc.parts.saveToConfigOverride = true; } diff --git a/src/GCodes/GCodeBuffer/BinaryParser.cpp b/src/GCodes/GCodeBuffer/BinaryParser.cpp index 4ae48925..3993791d 100644 --- a/src/GCodes/GCodeBuffer/BinaryParser.cpp +++ b/src/GCodes/GCodeBuffer/BinaryParser.cpp @@ -639,19 +639,19 @@ void BinaryParser::WriteParameters(const StringRef& s, bool quoteStrings) const } } -ParseException BinaryParser::ConstructParseException(const char *str) const noexcept +GCodeException BinaryParser::ConstructParseException(const char *str) const noexcept { - return ParseException(lineNumber, -1, str); + return GCodeException(lineNumber, -1, str); } -ParseException BinaryParser::ConstructParseException(const char *str, const char *param) const noexcept +GCodeException BinaryParser::ConstructParseException(const char *str, const char *param) const noexcept { - return ParseException(lineNumber, -1, str, param); + return GCodeException(lineNumber, -1, str, param); } -ParseException BinaryParser::ConstructParseException(const char *str, uint32_t param) const noexcept +GCodeException BinaryParser::ConstructParseException(const char *str, uint32_t param) const noexcept { - return ParseException(lineNumber, -1, str, param); + return GCodeException(lineNumber, -1, str, param); } // End diff --git a/src/GCodes/GCodeBuffer/BinaryParser.h b/src/GCodes/GCodeBuffer/BinaryParser.h index 85e08026..29bed30f 100644 --- a/src/GCodes/GCodeBuffer/BinaryParser.h +++ b/src/GCodes/GCodeBuffer/BinaryParser.h @@ -8,10 +8,10 @@ #ifndef SRC_GCODES_GCODEBUFFER_BINARYGCODEBUFFER_H_ #define SRC_GCODES_GCODEBUFFER_BINARYGCODEBUFFER_H_ -#include "Linux/MessageFormats.h" -#include "MessageType.h" -#include "RepRapFirmware.h" -#include "ParseException.h" +#include <Linux/MessageFormats.h> +#include <MessageType.h> +#include <RepRapFirmware.h> +#include <GCodes/GCodeException.h> class GCodeBuffer; class IPAddress; @@ -29,20 +29,20 @@ public: int GetCommandNumber() const noexcept; int8_t GetCommandFraction() const noexcept; - float GetFValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get a float after a key letter - int32_t GetIValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get an integer after a key letter - uint32_t GetUIValue() THROWS_PARSE_ERROR; // Get an unsigned integer value - DriverId GetDriverId() THROWS_PARSE_ERROR; // Get a driver ID - void GetIPAddress(IPAddress& returnedIp) THROWS_PARSE_ERROR; // Get an IP address quad after a key letter - void GetMacAddress(uint8_t mac[6]) THROWS_PARSE_ERROR; // Get a MAC address sextet after a key letter - void GetUnprecedentedString(const StringRef& str, bool allowEmpty) THROWS_PARSE_ERROR; // Get a string with no preceding key letter - void GetQuotedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a quoted string - void GetPossiblyQuotedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a string which may or may not be quoted - void GetReducedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a quoted string, removing certain characters - void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR __attribute__((hot)); // Get a colon-separated list of floats after a key letter - void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of ints after a key letter - void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of unsigned ints after a key letter - void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_PARSE_ERROR; // Get a :-separated list of drivers after a key letter + float GetFValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a float after a key letter + int32_t GetIValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get an integer after a key letter + uint32_t GetUIValue() THROWS_GCODE_EXCEPTION; // Get an unsigned integer value + DriverId GetDriverId() THROWS_GCODE_EXCEPTION; // Get a driver ID + void GetIPAddress(IPAddress& returnedIp) THROWS_GCODE_EXCEPTION; // Get an IP address quad after a key letter + void GetMacAddress(uint8_t mac[6]) THROWS_GCODE_EXCEPTION; // Get a MAC address sextet after a key letter + void GetUnprecedentedString(const StringRef& str, bool allowEmpty) THROWS_GCODE_EXCEPTION; // Get a string with no preceding key letter + void GetQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string + void GetPossiblyQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a string which may or may not be quoted + void GetReducedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string, removing certain characters + void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a colon-separated list of floats after a key letter + void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of ints after a key letter + void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of unsigned ints after a key letter + void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_GCODE_EXCEPTION; // Get a :-separated list of drivers after a key letter void SetFinished() noexcept; // Set the G Code finished @@ -57,12 +57,12 @@ public: private: GCodeBuffer& gb; - ParseException ConstructParseException(const char *str) const noexcept; - ParseException ConstructParseException(const char *str, const char *param) const noexcept; - ParseException ConstructParseException(const char *str, uint32_t param) const noexcept; + GCodeException ConstructParseException(const char *str) const noexcept; + GCodeException ConstructParseException(const char *str, const char *param) const noexcept; + GCodeException ConstructParseException(const char *str, uint32_t param) const noexcept; size_t AddPadding(size_t bytesRead) const noexcept; - template<typename T> void GetArray(T arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR __attribute__((hot)); + template<typename T> void GetArray(T arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION __attribute__((hot)); void WriteParameters(const StringRef& s, bool quoteStrings) const noexcept; size_t bufferLength; diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp index 7731e4df..2d373ec6 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp @@ -9,13 +9,13 @@ #include "GCodeBuffer.h" #if HAS_MASS_STORAGE -# include "GCodes/GCodeInput.h" +# include <GCodes/GCodeInput.h> #endif #include "BinaryParser.h" #include "StringParser.h" -#include "ParseException.h" -#include "RepRap.h" -#include "Platform.h" +#include <GCodes/GCodeException.h> +#include <RepRap.h> +#include <Platform.h> // Create a default GCodeBuffer GCodeBuffer::GCodeBuffer(GCodeChannel channel, GCodeInput *normalIn, FileGCodeInput *fileIn, MessageType mt, Compatibility c) noexcept @@ -199,7 +199,7 @@ void GCodeBuffer::MustSee(char c) { if (!Seen(c)) { - throw ParseException(machineState->lineNumber, -1, "missing parameter '%c'", (uint32_t)c); + throw GCodeException(machineState->lineNumber, -1, "missing parameter '%c'", (uint32_t)c); } } diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h index d738c8db..b6e9a796 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.h +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h @@ -53,7 +53,7 @@ public: void PutAndDecode(const char *str) noexcept; // Add a null-terminated string, overwriting any existing content bool FileEnded() noexcept; // Called when we reach the end of the file we are reading from void DecodeCommand() noexcept; // Decode the command in the buffer when it is complete - bool CheckMetaCommand(const StringRef& reply) THROWS_PARSE_ERROR; // Check whether the current command is a meta command, or we are skipping a block + bool CheckMetaCommand(const StringRef& reply) THROWS_GCODE_EXCEPTION; // Check whether the current command is a meta command, or we are skipping a block char GetCommandLetter() const noexcept; bool HasCommandNumber() const noexcept; @@ -61,34 +61,34 @@ public: int8_t GetCommandFraction() const noexcept; bool Seen(char c) noexcept __attribute__((hot)); // Is a character present? - void MustSee(char c) THROWS_PARSE_ERROR; // Test for character present, throw error if not - - float GetFValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get a float after a key letter - float GetDistance() THROWS_PARSE_ERROR; // Get a distance or coordinate and convert it from inches to mm if necessary - int32_t GetIValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get an integer after a key letter - uint32_t GetUIValue() THROWS_PARSE_ERROR; // Get an unsigned integer value - void GetIPAddress(IPAddress& returnedIp) THROWS_PARSE_ERROR; // Get an IP address quad after a key letter - void GetMacAddress(uint8_t mac[6]) THROWS_PARSE_ERROR; // Get a MAC address sextet after a key letter - PwmFrequency GetPwmFrequency() THROWS_PARSE_ERROR; // Get a PWM frequency - float GetPwmValue() THROWS_PARSE_ERROR; // Get a PWM value - DriverId GetDriverId() THROWS_PARSE_ERROR; // Get a driver ID - void GetUnprecedentedString(const StringRef& str, bool allowEmpty = false) THROWS_PARSE_ERROR; // Get a string with no preceding key letter - void GetQuotedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a quoted string - void GetPossiblyQuotedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a string which may or may not be quoted - void GetReducedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a quoted string, removing certain characters - void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR __attribute__((hot)); // Get a colon-separated list of floats after a key letter - void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of ints after a key letter - void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of unsigned ints after a key letter - void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_PARSE_ERROR; // Get a :-separated list of drivers after a key letter - - bool TryGetFValue(char c, float& val, bool& seen) THROWS_PARSE_ERROR; - bool TryGetIValue(char c, int32_t& val, bool& seen) THROWS_PARSE_ERROR; - bool TryGetUIValue(char c, uint32_t& val, bool& seen) THROWS_PARSE_ERROR; - bool TryGetBValue(char c, bool& val, bool& seen) THROWS_PARSE_ERROR; - bool TryGetFloatArray(char c, size_t numVals, float vals[], const StringRef& reply, bool& seen, bool doPad = false) THROWS_PARSE_ERROR; - bool TryGetUIArray(char c, size_t numVals, uint32_t vals[], const StringRef& reply, bool& seen, bool doPad = false) THROWS_PARSE_ERROR; - bool TryGetQuotedString(char c, const StringRef& str, bool& seen) THROWS_PARSE_ERROR; - bool TryGetPossiblyQuotedString(char c, const StringRef& str, bool& seen) THROWS_PARSE_ERROR; + void MustSee(char c) THROWS_GCODE_EXCEPTION; // Test for character present, throw error if not + + float GetFValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a float after a key letter + float GetDistance() THROWS_GCODE_EXCEPTION; // Get a distance or coordinate and convert it from inches to mm if necessary + int32_t GetIValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get an integer after a key letter + uint32_t GetUIValue() THROWS_GCODE_EXCEPTION; // Get an unsigned integer value + void GetIPAddress(IPAddress& returnedIp) THROWS_GCODE_EXCEPTION; // Get an IP address quad after a key letter + void GetMacAddress(uint8_t mac[6]) THROWS_GCODE_EXCEPTION; // Get a MAC address sextet after a key letter + PwmFrequency GetPwmFrequency() THROWS_GCODE_EXCEPTION; // Get a PWM frequency + float GetPwmValue() THROWS_GCODE_EXCEPTION; // Get a PWM value + DriverId GetDriverId() THROWS_GCODE_EXCEPTION; // Get a driver ID + void GetUnprecedentedString(const StringRef& str, bool allowEmpty = false) THROWS_GCODE_EXCEPTION; // Get a string with no preceding key letter + void GetQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string + void GetPossiblyQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a string which may or may not be quoted + void GetReducedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string, removing certain characters + void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a colon-separated list of floats after a key letter + void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of ints after a key letter + void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of unsigned ints after a key letter + void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_GCODE_EXCEPTION; // Get a :-separated list of drivers after a key letter + + bool TryGetFValue(char c, float& val, bool& seen) THROWS_GCODE_EXCEPTION; + bool TryGetIValue(char c, int32_t& val, bool& seen) THROWS_GCODE_EXCEPTION; + bool TryGetUIValue(char c, uint32_t& val, bool& seen) THROWS_GCODE_EXCEPTION; + bool TryGetBValue(char c, bool& val, bool& seen) THROWS_GCODE_EXCEPTION; + bool TryGetFloatArray(char c, size_t numVals, float vals[], const StringRef& reply, bool& seen, bool doPad = false) THROWS_GCODE_EXCEPTION; + bool TryGetUIArray(char c, size_t numVals, uint32_t vals[], const StringRef& reply, bool& seen, bool doPad = false) THROWS_GCODE_EXCEPTION; + bool TryGetQuotedString(char c, const StringRef& str, bool& seen) THROWS_GCODE_EXCEPTION; + bool TryGetPossiblyQuotedString(char c, const StringRef& str, bool& seen) THROWS_GCODE_EXCEPTION; bool IsIdle() const noexcept; bool IsCompletelyIdle() const noexcept; diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp index 21280b4b..662419b3 100644 --- a/src/GCodes/GCodeBuffer/StringParser.cpp +++ b/src/GCodes/GCodeBuffer/StringParser.cpp @@ -16,6 +16,10 @@ #include <General/IP4String.h> #include <General/StringBuffer.h> +// Replace the default definition of THROW_INTERNAL_ERROR by one that gives line information +#undef THROW_INTERNAL_ERROR +#define THROW_INTERNAL_ERROR throw ConstructParseException("internal error at file " __FILE__ "(%d)", __LINE__) + #if HAS_MASS_STORAGE static constexpr char eofString[] = EOF_STRING; // What's at the end of an HTML file? #endif @@ -553,7 +557,7 @@ void StringParser::ProcessAbortCommand(const StringRef& reply) noexcept const ExpressionValue val = ParseExpression(bufRef, 0, true); AppendAsString(val, reply); } - catch (const ParseException& e) + catch (const GCodeException& e) { e.GetMessage(reply, gb); reply.Insert(0, "invalid expression after 'abort': "); @@ -2365,22 +2369,22 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff return rslt; } - return reprap.GetObjectValue(*this, 0, varName.c_str()); + return reprap.GetObjectValue(*this, varName.c_str()); } -ParseException StringParser::ConstructParseException(const char *str) const +GCodeException StringParser::ConstructParseException(const char *str) const { - return ParseException(gb.machineState->lineNumber, readPointer + commandIndent, str); + return GCodeException(gb.machineState->lineNumber, readPointer + commandIndent, str); } -ParseException StringParser::ConstructParseException(const char *str, const char *param) const +GCodeException StringParser::ConstructParseException(const char *str, const char *param) const { - return ParseException(gb.machineState->lineNumber, readPointer + commandIndent, str, param); + return GCodeException(gb.machineState->lineNumber, readPointer + commandIndent, str, param); } -ParseException StringParser::ConstructParseException(const char *str, uint32_t param) const +GCodeException StringParser::ConstructParseException(const char *str, uint32_t param) const { - return ParseException(gb.machineState->lineNumber, readPointer + commandIndent, str, param); + return GCodeException(gb.machineState->lineNumber, readPointer + commandIndent, str, param); } // End diff --git a/src/GCodes/GCodeBuffer/StringParser.h b/src/GCodes/GCodeBuffer/StringParser.h index 7feed934..0ba345ff 100644 --- a/src/GCodes/GCodeBuffer/StringParser.h +++ b/src/GCodes/GCodeBuffer/StringParser.h @@ -8,12 +8,12 @@ #ifndef SRC_GCODES_GCODEBUFFER_STRINGGCODEBUFFER_H #define SRC_GCODES_GCODEBUFFER_STRINGGCODEBUFFER_H -#include "RepRapFirmware.h" -#include "GCodes/GCodeInput.h" -#include "GCodes/GCodeMachineState.h" -#include "MessageType.h" -#include "ObjectModel/ObjectModel.h" -#include "ParseException.h" +#include <RepRapFirmware.h> +#include <GCodes/GCodeInput.h> +#include <GCodes/GCodeMachineState.h> +#include <MessageType.h> +#include <ObjectModel/ObjectModel.h> +#include <GCodes/GCodeException.h> class GCodeBuffer; class IPAddress; @@ -30,7 +30,7 @@ public: void PutAndDecode(const char *str, size_t len) noexcept; // Add an entire string, overwriting any existing content void PutAndDecode(const char *str) noexcept; // Add a null-terminated string, overwriting any existing content bool FileEnded() noexcept; // Called when we reach the end of the file we are reading from - bool CheckMetaCommand(const StringRef& reply) THROWS_PARSE_ERROR; // Check whether the current command is a meta command, or we are skipping block + bool CheckMetaCommand(const StringRef& reply) THROWS_GCODE_EXCEPTION; // Check whether the current command is a meta command, or we are skipping block // The following may be called after calling DecodeCommand char GetCommandLetter() const noexcept { return commandLetter; } @@ -39,21 +39,21 @@ public: int8_t GetCommandFraction() const noexcept { return commandFraction; } bool Seen(char c) noexcept __attribute__((hot)); // Is a character present? - float GetFValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get a float after a key letter - float GetDistance() THROWS_PARSE_ERROR; // Get a distance or coordinate and convert it from inches to mm if necessary - int32_t GetIValue() THROWS_PARSE_ERROR __attribute__((hot)); // Get an integer after a key letter - uint32_t GetUIValue() THROWS_PARSE_ERROR; // Get an unsigned integer value - DriverId GetDriverId() THROWS_PARSE_ERROR; // Get a driver ID - void GetIPAddress(IPAddress& returnedIp) THROWS_PARSE_ERROR; // Get an IP address quad after a key letter - void GetMacAddress(uint8_t mac[6]) THROWS_PARSE_ERROR; // Get a MAC address sextet after a key letter - void GetUnprecedentedString(const StringRef& str, bool allowEmpty) THROWS_PARSE_ERROR; // Get a string with no preceding key letter - void GetQuotedString(const StringRef& str, bool allowEmpty = false) THROWS_PARSE_ERROR; // Get and copy a quoted string - void GetPossiblyQuotedString(const StringRef& str, bool allowEmpty = false) THROWS_PARSE_ERROR; // Get and copy a string which may or may not be quoted - void GetReducedString(const StringRef& str) THROWS_PARSE_ERROR; // Get and copy a quoted string, removing certain characters - void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR __attribute__((hot)); // Get a colon-separated list of floats after a key letter - void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of ints after a key letter - void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_PARSE_ERROR; // Get a :-separated list of unsigned ints after a key letter - void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_PARSE_ERROR; // Get a :-separated list of drivers after a key letter + float GetFValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a float after a key letter + float GetDistance() THROWS_GCODE_EXCEPTION; // Get a distance or coordinate and convert it from inches to mm if necessary + int32_t GetIValue() THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get an integer after a key letter + uint32_t GetUIValue() THROWS_GCODE_EXCEPTION; // Get an unsigned integer value + DriverId GetDriverId() THROWS_GCODE_EXCEPTION; // Get a driver ID + void GetIPAddress(IPAddress& returnedIp) THROWS_GCODE_EXCEPTION; // Get an IP address quad after a key letter + void GetMacAddress(uint8_t mac[6]) THROWS_GCODE_EXCEPTION; // Get a MAC address sextet after a key letter + void GetUnprecedentedString(const StringRef& str, bool allowEmpty) THROWS_GCODE_EXCEPTION; // Get a string with no preceding key letter + void GetQuotedString(const StringRef& str, bool allowEmpty = false) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string + void GetPossiblyQuotedString(const StringRef& str, bool allowEmpty = false) THROWS_GCODE_EXCEPTION; // Get and copy a string which may or may not be quoted + void GetReducedString(const StringRef& str) THROWS_GCODE_EXCEPTION; // Get and copy a quoted string, removing certain characters + void GetFloatArray(float arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION __attribute__((hot)); // Get a colon-separated list of floats after a key letter + void GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of ints after a key letter + void GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS_GCODE_EXCEPTION; // Get a :-separated list of unsigned ints after a key letter + void GetDriverIdArray(DriverId arr[], size_t& length) THROWS_GCODE_EXCEPTION; // Get a :-separated list of drivers after a key letter void SetFinished() noexcept; // Set the G Code finished void SetCommsProperties(uint32_t arg) noexcept { checksumRequired = (arg & 1); } @@ -77,62 +77,62 @@ public: void PrintCommand(const StringRef& s) const noexcept; void AppendFullCommand(const StringRef &s) const noexcept; - ParseException ConstructParseException(const char *str) const; - ParseException ConstructParseException(const char *str, const char *param) const; - ParseException ConstructParseException(const char *str, uint32_t param) const; + GCodeException ConstructParseException(const char *str) const; + GCodeException ConstructParseException(const char *str, const char *param) const; + GCodeException ConstructParseException(const char *str, uint32_t param) const; private: GCodeBuffer& gb; void AddToChecksum(char c) noexcept; void StoreAndAddToChecksum(char c) noexcept; - bool LineFinished() THROWS_PARSE_ERROR; // Deal with receiving end-of-line and return true if we have a command - void InternalGetQuotedString(const StringRef& str) THROWS_PARSE_ERROR + bool LineFinished() THROWS_GCODE_EXCEPTION; // Deal with receiving end-of-line and return true if we have a command + void InternalGetQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION pre (readPointer >= 0; gb.buffer[readPointer] == '"'; str.IsEmpty()); - void InternalGetPossiblyQuotedString(const StringRef& str) THROWS_PARSE_ERROR + void InternalGetPossiblyQuotedString(const StringRef& str) THROWS_GCODE_EXCEPTION pre (readPointer >= 0); - float ReadFloatValue() THROWS_PARSE_ERROR; - uint32_t ReadUIValue() THROWS_PARSE_ERROR; - int32_t ReadIValue() THROWS_PARSE_ERROR; - DriverId ReadDriverIdValue() THROWS_PARSE_ERROR; - void AppendAsString(ExpressionValue val, const StringRef& str) THROWS_PARSE_ERROR + float ReadFloatValue() THROWS_GCODE_EXCEPTION; + uint32_t ReadUIValue() THROWS_GCODE_EXCEPTION; + int32_t ReadIValue() THROWS_GCODE_EXCEPTION; + DriverId ReadDriverIdValue() THROWS_GCODE_EXCEPTION; + void AppendAsString(ExpressionValue val, const StringRef& str) THROWS_GCODE_EXCEPTION pre (readPointer >= 0); - bool ProcessConditionalGCode(const StringRef& reply, BlockType previousBlockType, bool doingFile) THROWS_PARSE_ERROR; + bool ProcessConditionalGCode(const StringRef& reply, BlockType previousBlockType, bool doingFile) THROWS_GCODE_EXCEPTION; // Check for and process a conditional GCode language command returning true if we found one - void CreateBlocks() THROWS_PARSE_ERROR; // Create new code blocks + void CreateBlocks() THROWS_GCODE_EXCEPTION; // Create new code blocks bool EndBlocks() noexcept; // End blocks returning true if nothing more to process on this line - void ProcessIfCommand() THROWS_PARSE_ERROR; - void ProcessElseCommand(BlockType previousBlockType) THROWS_PARSE_ERROR; - void ProcessElifCommand(BlockType previousBlockType) THROWS_PARSE_ERROR; - void ProcessWhileCommand() THROWS_PARSE_ERROR; - void ProcessBreakCommand() THROWS_PARSE_ERROR; - void ProcessVarCommand() THROWS_PARSE_ERROR; - void ProcessSetCommand() THROWS_PARSE_ERROR; + void ProcessIfCommand() THROWS_GCODE_EXCEPTION; + void ProcessElseCommand(BlockType previousBlockType) THROWS_GCODE_EXCEPTION; + void ProcessElifCommand(BlockType previousBlockType) THROWS_GCODE_EXCEPTION; + void ProcessWhileCommand() THROWS_GCODE_EXCEPTION; + void ProcessBreakCommand() THROWS_GCODE_EXCEPTION; + void ProcessVarCommand() THROWS_GCODE_EXCEPTION; + void ProcessSetCommand() THROWS_GCODE_EXCEPTION; void ProcessAbortCommand(const StringRef& reply) noexcept; - void ProcessEchoCommand(const StringRef& reply) THROWS_PARSE_ERROR; + void ProcessEchoCommand(const StringRef& reply) THROWS_GCODE_EXCEPTION; - bool EvaluateCondition() THROWS_PARSE_ERROR; + bool EvaluateCondition() THROWS_GCODE_EXCEPTION; - ExpressionValue ParseBracketedExpression(StringBuffer& stringBuffer, char closingBracket, bool evaluate) THROWS_PARSE_ERROR + ExpressionValue ParseBracketedExpression(StringBuffer& stringBuffer, char closingBracket, bool evaluate) THROWS_GCODE_EXCEPTION pre (readPointer >= 0; gb.buffer[readPointer] == '{'); - ExpressionValue ParseExpression(StringBuffer& stringBuffer, uint8_t priority, bool evaluate) THROWS_PARSE_ERROR + ExpressionValue ParseExpression(StringBuffer& stringBuffer, uint8_t priority, bool evaluate) THROWS_GCODE_EXCEPTION pre (readPointer >= 0); - ExpressionValue ParseNumber() THROWS_PARSE_ERROR + ExpressionValue ParseNumber() THROWS_GCODE_EXCEPTION pre(readPointer >= 0; isdigit(gb.buffer[readPointer])); - ExpressionValue ParseIdentifierExpression(StringBuffer& stringBuffer, bool evaluate) THROWS_PARSE_ERROR + ExpressionValue ParseIdentifierExpression(StringBuffer& stringBuffer, bool evaluate) THROWS_GCODE_EXCEPTION pre(readPointer >= 0; isalpha(gb.buffer[readPointer])); - void ParseIdentifier(const StringRef& id) THROWS_PARSE_ERROR + void ParseIdentifier(const StringRef& id) THROWS_GCODE_EXCEPTION pre(readPointer >= 0); - void BalanceNumericTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) THROWS_PARSE_ERROR; - void BalanceTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) THROWS_PARSE_ERROR; - void ConvertToFloat(ExpressionValue& val, bool evaluate) THROWS_PARSE_ERROR; - void ConvertToBool(ExpressionValue& val, bool evaluate) THROWS_PARSE_ERROR; - void EnsureNumeric(ExpressionValue& val, bool evaluate) THROWS_PARSE_ERROR; - void ConvertToString(ExpressionValue& val, bool evaluate, StringBuffer& stringBuffer) THROWS_PARSE_ERROR; + void BalanceNumericTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) THROWS_GCODE_EXCEPTION; + void BalanceTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) THROWS_GCODE_EXCEPTION; + void ConvertToFloat(ExpressionValue& val, bool evaluate) THROWS_GCODE_EXCEPTION; + void ConvertToBool(ExpressionValue& val, bool evaluate) THROWS_GCODE_EXCEPTION; + void EnsureNumeric(ExpressionValue& val, bool evaluate) THROWS_GCODE_EXCEPTION; + void ConvertToString(ExpressionValue& val, bool evaluate, StringBuffer& stringBuffer) THROWS_GCODE_EXCEPTION; - const char *GetAndFix(StringBuffer& stringBuffer) THROWS_PARSE_ERROR; + const char *GetAndFix(StringBuffer& stringBuffer) THROWS_GCODE_EXCEPTION; void SkipWhiteSpace() noexcept; diff --git a/src/GCodes/GCodeBuffer/ParseException.cpp b/src/GCodes/GCodeException.cpp index fa73eb8e..80024776 100644 --- a/src/GCodes/GCodeBuffer/ParseException.cpp +++ b/src/GCodes/GCodeException.cpp @@ -5,16 +5,16 @@ * Author: David */ -#include "ParseException.h" +#include "GCodeException.h" #include <General/StringRef.h> -#include "GCodeBuffer.h" +#include <GCodes/GCodeBuffer/GCodeBuffer.h> // Construct the error message. This will be prefixed with "Error: " when it is returned to the user. -void ParseException::GetMessage(const StringRef &reply, const GCodeBuffer& gb) const +void GCodeException::GetMessage(const StringRef &reply, const GCodeBuffer& gb) const { - reply.copy((gb.IsDoingFileMacro()) ? "in file macro" : "in GCode file"); - if (line >= 0 && column >= 0) + reply.copy((gb.IsDoingFileMacro()) ? "in file macro" : (gb.IsDoingFile()) ? "in GCode file" : "while executing command"); + if (line >= 0 && column >= 0 && gb.IsDoingFile()) { reply.catf(", line %d column %d", line, column + 1); } diff --git a/src/GCodes/GCodeBuffer/ParseException.h b/src/GCodes/GCodeException.h index a7acc5ea..ad434132 100644 --- a/src/GCodes/GCodeBuffer/ParseException.h +++ b/src/GCodes/GCodeException.h @@ -5,30 +5,30 @@ * Author: David */ -#ifndef SRC_GCODES_PARSEEXCEPTION_H_ -#define SRC_GCODES_PARSEEXCEPTION_H_ +#ifndef SRC_GCODES_GCODEEXCEPTION_H_ +#define SRC_GCODES_GCODEEXCEPTION_H_ #include <cstdint> class StringRef; class GCodeBuffer; -class ParseException +class GCodeException { public: - ParseException(int lin, int col, const char *msg) : line(lin), column(col), message(msg) { } + GCodeException(int lin, int col, const char *msg) : line(lin), column(col), message(msg) { } - ParseException(int lin, int col, const char *msg, const char *sparam) : line(lin), column(col), message(msg) + GCodeException(int lin, int col, const char *msg, const char *sparam) : line(lin), column(col), message(msg) { param.s = sparam; } - ParseException(int lin, int col, const char *msg, uint32_t uparam) : line(lin), column(col), message(msg) + GCodeException(int lin, int col, const char *msg, uint32_t uparam) : line(lin), column(col), message(msg) { param.u = uparam; } - ParseException(int lin, int col, const char *msg, int32_t iparam) : line(lin), column(col), message(msg) + GCodeException(int lin, int col, const char *msg, int32_t iparam) : line(lin), column(col), message(msg) { param.i = iparam; } @@ -47,4 +47,4 @@ private: } param; }; -#endif /* SRC_GCODES_PARSEEXCEPTION_H_ */ +#endif /* SRC_GCODES_GCODEEXCEPTION_H_ */ diff --git a/src/GCodes/GCodeQueue.h b/src/GCodes/GCodeQueue.h index 322fd9ac..b6c50165 100644 --- a/src/GCodes/GCodeQueue.h +++ b/src/GCodes/GCodeQueue.h @@ -30,7 +30,7 @@ public: void Diagnostics(MessageType mtype) noexcept; - static bool ShouldQueueCode(GCodeBuffer &gb) THROWS_PARSE_ERROR; // Return true if this code should be queued + static bool ShouldQueueCode(GCodeBuffer &gb) THROWS_GCODE_EXCEPTION; // Return true if this code should be queued private: QueuedCode *freeItems; diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index c12d551c..f067a70b 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -475,7 +475,7 @@ void GCodes::StartNextGCode(GCodeBuffer& gb, const StringRef& reply) { done = gb.CheckMetaCommand(reply); } - catch (ParseException& e) + catch (GCodeException& e) { e.GetMessage(reply, gb); HandleReply(gb, GCodeResult::error, reply.c_str()); @@ -639,7 +639,7 @@ void GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply) { done = gb.CheckMetaCommand(reply); } - catch (ParseException& e) + catch (GCodeException& e) { e.GetMessage(reply, gb); HandleReply(gb, GCodeResult::error, reply.c_str()); @@ -676,7 +676,7 @@ void GCodes::DoFilePrint(GCodeBuffer& gb, const StringRef& reply) { done = gb.CheckMetaCommand(reply); } - catch (ParseException& e) + catch (GCodeException& e) { e.GetMessage(reply, gb); HandleReply(gb, GCodeResult::error, reply.c_str()); diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index aadb2da5..6614f904 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -259,7 +259,7 @@ private: GCodeResult StraightProbe(GCodeBuffer& gb, const StringRef& reply); // Deal with a G38.x GCodeResult DoDriveMapping(GCodeBuffer& gb, const StringRef& reply); // Deal with a M584 GCodeResult ProbeTool(GCodeBuffer& gb, const StringRef& reply); // Deal with a M585 - GCodeResult FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply, const bool towardsMin = true) THROWS_PARSE_ERROR; // Deal with a M675 + GCodeResult FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply, const bool towardsMin = true) THROWS_GCODE_EXCEPTION; // Deal with a M675 GCodeResult SetDateTime(GCodeBuffer& gb,const StringRef& reply); // Deal with a M905 GCodeResult SavePosition(GCodeBuffer& gb,const StringRef& reply); // Deal with G60 GCodeResult ConfigureDriver(GCodeBuffer& gb,const StringRef& reply); // Deal with M569 diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 454fb840..7b8623ba 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -10,7 +10,7 @@ #include "GCodes.h" #include "GCodeBuffer/GCodeBuffer.h" -#include "GCodeBuffer/ParseException.h" +#include "GCodeException.h" #include "GCodeQueue.h" #include "Heating/Heat.h" #include "Movement/Move.h" @@ -95,7 +95,7 @@ bool GCodes::ActOnCode(GCodeBuffer& gb, const StringRef& reply) break; } } - catch (const ParseException& e) + catch (const GCodeException& e) { e.GetMessage(reply, gb); HandleReply(gb, GCodeResult::error, reply.c_str()); @@ -2693,7 +2693,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) } else { - reprap.ReportAsJson(outBuf, 0, filter.c_str(), ObjectModel::flagsNone); + reprap.ReportAsJson(outBuf, filter.c_str(), ObjectModelReportFlags::shortForm, ObjectModelEntryFlags::none); } } break; @@ -4390,7 +4390,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) return HandleResult(gb, result, reply, outBuf); } - catch (const ParseException& e) + catch (const GCodeException& e) { OutputBuffer::ReleaseAll(outBuf); throw; diff --git a/src/Heating/Heat.h b/src/Heating/Heat.h index b683515c..22c011a1 100644 --- a/src/Heating/Heat.h +++ b/src/Heating/Heat.h @@ -75,11 +75,11 @@ public: void SuspendHeaters(bool sus) noexcept; // Suspend the heaters to conserve power or while probing GCodeResult ResetFault(int heater, const StringRef& reply) noexcept; // Reset a heater fault for a specific heater or all heaters - GCodeResult SetOrReportHeaterModel(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; - GCodeResult TuneHeater(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; - GCodeResult ConfigureSensor(GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; // Create a sensor or change the parameters for an existing sensor - GCodeResult SetPidParameters(unsigned int heater, GCodeBuffer& gb, const StringRef& reply) THROWS_PARSE_ERROR; // Set the P/I/D parameters for a heater - GCodeResult SetHeaterProtection(GCodeBuffer &gb, const StringRef &reply) THROWS_PARSE_ERROR; // Configure heater protection (M143) + GCodeResult SetOrReportHeaterModel(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; + GCodeResult TuneHeater(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; + GCodeResult ConfigureSensor(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; // Create a sensor or change the parameters for an existing sensor + GCodeResult SetPidParameters(unsigned int heater, GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; // Set the P/I/D parameters for a heater + GCodeResult SetHeaterProtection(GCodeBuffer &gb, const StringRef &reply) THROWS_GCODE_EXCEPTION; // Configure heater protection (M143) void UpdateHeaterProtection(int heaterNumber) noexcept; // Updates the PIDs and HeaterProtection items when a heater is remapped diff --git a/src/Networking/ESP8266WiFi/WiFiInterface.h b/src/Networking/ESP8266WiFi/WiFiInterface.h index e2a0d10b..68d2485b 100644 --- a/src/Networking/ESP8266WiFi/WiFiInterface.h +++ b/src/Networking/ESP8266WiFi/WiFiInterface.h @@ -66,7 +66,7 @@ public: void TerminateDataPort() noexcept override; // The remaining functions are specific to the WiFi version - GCodeResult HandleWiFiCode(int mcode, GCodeBuffer &gb, const StringRef& reply, OutputBuffer*& longReply) THROWS_PARSE_ERROR; + GCodeResult HandleWiFiCode(int mcode, GCodeBuffer &gb, const StringRef& reply, OutputBuffer*& longReply) THROWS_GCODE_EXCEPTION; WifiFirmwareUploader *GetWifiUploader() const noexcept { return uploader; } void StartWiFi() noexcept; void ResetWiFi() noexcept; diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp index 5c7655fa..f5b1a6a4 100644 --- a/src/Networking/Network.cpp +++ b/src/Networking/Network.cpp @@ -71,8 +71,8 @@ Network::Network(Platform& p) noexcept : platform(p), responders(nullptr), nextR static const ObjectModelArrayDescriptor interfaceArrayDescriptor = { - [] (const ObjectModel *self) noexcept -> size_t { return NumNetworkInterfaces; }, - [] (const ObjectModel *self, size_t n) noexcept -> ExpressionValue { return ExpressionValue(((Network*)self)->GetInterface(n)); } + [] (const ObjectModel *self, const ObjectExplorationContext& context) noexcept -> size_t { return NumNetworkInterfaces; }, + [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue(((Network*)self)->GetInterface(context.GetIndex(0))); } }; // Macro to build a standard lambda function that includes the necessary type conversions diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index 49946386..2ff93878 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -14,13 +14,40 @@ #include <cstring> #include <General/SafeStrtod.h> +void ObjectExplorationContext::AddIndex(unsigned int index) +{ + if (numIndices == MaxIndices) // should always be true + { + THROW_INTERNAL_ERROR; + } + ++numIndices; +} + +void ObjectExplorationContext::RemoveIndex() +{ + if (numIndices == 0) + { + THROW_INTERNAL_ERROR; + } + --numIndices; +} + // Constructor ObjectModel::ObjectModel() noexcept { } +unsigned int ObjectExplorationContext::GetIndex(size_t n) const +{ + if (n < numIndices) + { + return indices[numIndices - n - 1]; + } + THROW_INTERNAL_ERROR; +} + // Report this object -bool ObjectModel::ReportAsJson(OutputBuffer* buf, uint8_t tableNumber, const char* filter, ReportFlags flags) const noexcept +bool ObjectModel::ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& context, uint8_t tableNumber, const char* filter) const { buf->cat('{'); bool added = false; @@ -37,13 +64,13 @@ bool ObjectModel::ReportAsJson(OutputBuffer* buf, uint8_t tableNumber, const cha while (numEntries != 0) { - if (tbl->Matches(filter, flags)) + if (tbl->Matches(filter, context)) { if (added) { buf->cat(','); } - tbl->ReportAsJson(buf, this, GetNextElement(filter), flags); + tbl->ReportAsJson(buf, context, this, GetNextElement(filter)); added = true; } --numEntries; @@ -54,8 +81,15 @@ bool ObjectModel::ReportAsJson(OutputBuffer* buf, uint8_t tableNumber, const cha return added; } +// Construct a JSON representation of those parts of the object model requested by the user. This version is called on the root of the tree. +bool ObjectModel::ReportAsJson(OutputBuffer *buf, const char *filter, ObjectModelReportFlags rf, ObjectModelEntryFlags ff) const +{ + ObjectExplorationContext context(rf, ff); + return ReportAsJson(buf, context, 0, filter); +} + // Function to report a value or object as JSON -bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags) const noexcept +bool ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& context, ExpressionValue val, const char *filter) const { switch (val.type) { @@ -65,24 +99,26 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const ++filter; if (*filter == ']') // if reporting on [parts of] all elements in the array { - return ReportArrayAsJson(buf, val.omadVal, filter + 1, flags); + return ReportArrayAsJson(buf, context, val.omadVal, filter + 1); } const char *endptr; const long index = SafeStrtol(filter, &endptr); - if (endptr == filter || *endptr != ']' || index < 0 || (size_t)index >= val.omadVal->GetNumElements(this)) + if (endptr == filter || *endptr != ']' || index < 0 || (size_t)index >= val.omadVal->GetNumElements(this, context)) { buf->cat("[]"); // avoid returning badly-formed JSON return false; // invalid syntax, or index out of range } buf->cat('['); - const bool ret = ReportItemAsJson(val.omadVal->GetElement(this, index), buf, endptr + 1, flags); + context.AddIndex(index); + const bool ret = ReportItemAsJson(buf, context, val.omadVal->GetElement(this, context), endptr + 1); + context.RemoveIndex(); buf->cat(']'); return ret; } if (*filter == 0) // else reporting on all subparts of all elements in the array { - return ReportArrayAsJson(buf, val.omadVal, filter, flags); + return ReportArrayAsJson(buf, context, val.omadVal, filter); } return false; @@ -91,7 +127,7 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const { ++filter; } - return val.omVal->ReportAsJson(buf, val.param, filter, flags); + return val.omVal->ReportAsJson(buf, context, val.param, filter); break; case TYPE_OF(float): @@ -111,7 +147,7 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const break; case TYPE_OF(Bitmap32): - if (flags & ObjectModel::flagShortForm) + if (context.ShortFormReport()) { buf->catf("%" PRIu32, val.uVal); } @@ -131,7 +167,7 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const break; case TYPE_OF(Enum32): - if (flags & ObjectModel::flagShortForm) + if (context.ShortFormReport()) { buf->catf("%" PRIu32, val.uVal); } @@ -143,7 +179,7 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const break; case TYPE_OF(bool): - if (flags & ObjectModel::flagShortForm) + if (context.ShortFormReport()) { buf->cat((val.bVal) ? '1' : '0'); } @@ -174,18 +210,20 @@ bool ObjectModel::ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const } // Report an entire array as JSON -bool ObjectModel::ReportArrayAsJson(OutputBuffer *buf, const ObjectModelArrayDescriptor *omad, const char *filter, ReportFlags rflags) const noexcept +bool ObjectModel::ReportArrayAsJson(OutputBuffer *buf, ObjectExplorationContext& context, const ObjectModelArrayDescriptor *omad, const char *filter) const { buf->cat('['); bool ret = true; - const size_t count = omad->GetNumElements(this); + const size_t count = omad->GetNumElements(this, context); for (size_t i = 0; i < count && ret; ++i) { if (i != 0) { buf->cat(','); } - ret = ReportItemAsJson(omad->GetElement(this, i), buf, filter, rflags); + context.AddIndex(i); + ret = ReportItemAsJson(buf, context, omad->GetElement(this, context), filter); + context.RemoveIndex(); } buf->cat(']'); return ret; @@ -242,17 +280,17 @@ const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(uint8_t tabl return id; } -bool ObjectModelTableEntry::Matches(const char* filterString, ObjectModelFilterFlags filterFlags) const noexcept +bool ObjectModelTableEntry::Matches(const char* filterString, const ObjectExplorationContext& context) const noexcept { - return IdCompare(filterString) == 0 && ((uint16_t)flags & (uint16_t)filterFlags) == (uint16_t)filterFlags; + return IdCompare(filterString) == 0 && ((uint8_t)flags & (uint8_t)context.GetFilterFlags()) == (uint8_t)context.GetFilterFlags(); } // Add the value of this element to the buffer, returning true if it matched and we did -bool ObjectModelTableEntry::ReportAsJson(OutputBuffer* buf, const ObjectModel *self, const char* filter, ObjectModel::ReportFlags flags) const noexcept +bool ObjectModelTableEntry::ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& context, const ObjectModel *self, const char* filter) const noexcept { buf->cat(name); buf->cat(':'); - return self->ReportItemAsJson(func(self), buf, filter, flags); + return self->ReportItemAsJson(buf, context, func(self, context), filter); } // Compare an ID with the name of this object @@ -274,8 +312,15 @@ int ObjectModelTableEntry::IdCompare(const char *id) const noexcept : -1; } -// Get the value of an object. It must have a primitive type. -ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, uint8_t tableNumber, const char *idString) const +// Get the value of an object. This version is called on the root of the tree. +ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, const char *idString) const +{ + ObjectExplorationContext context(ObjectModelReportFlags::none, ObjectModelEntryFlags::none); + return GetObjectValue(sp, context, 0, idString); +} + +// Get the value of an object +ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, uint8_t tableNumber, const char *idString) const { const ObjectModelTableEntry *e = FindObjectModelTableEntry(tableNumber, idString); if (e == nullptr) @@ -284,7 +329,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, uint8_t tabl } idString = GetNextElement(idString); - ExpressionValue val = e->func(this); + ExpressionValue val = e->func(this, context); while (val.type == TYPE_OF(const ObjectModelArrayDescriptor*)) { if (*idString != '[') @@ -297,20 +342,22 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, uint8_t tabl { throw sp.ConstructParseException("expected ']'"); } - if (index < 0 || (size_t)index >= val.omadVal->GetNumElements(this)) + if (index < 0 || (size_t)index >= val.omadVal->GetNumElements(this, context)) { throw sp.ConstructParseException("array index out of bounds"); } idString = endptr + 1; // skip past the ']' - val = val.omadVal->GetElement(this, index); // fetch the array element + context.AddIndex(index); + val = val.omadVal->GetElement(this, context); // fetch the array element + context.RemoveIndex(); } if (val.type == TYPE_OF(const ObjectModel*)) { if (*idString == '.') { - return val.omVal->GetObjectValue(sp, val.param, idString + 1); + return val.omVal->GetObjectValue(sp, context, val.param, idString + 1); } throw sp.ConstructParseException((*idString == 0) ? "selected value has non-primitive type" : "syntax error in value selector string"); } diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index c8c40a95..9ffb5f57 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -8,14 +8,14 @@ #ifndef SRC_OBJECTMODEL_OBJECTMODEL_H_ #define SRC_OBJECTMODEL_OBJECTMODEL_H_ -#include "RepRapFirmware.h" +#include <RepRapFirmware.h> +#include <GCodes/GCodeException.h> #if SUPPORT_OBJECT_MODEL #include <General/IPAddress.h> #include <RTOSIface/RTOSIface.h> -typedef uint32_t ObjectModelFilterFlags; typedef uint8_t TypeCode; constexpr TypeCode NoType = 0; // code for an invalid or unknown type @@ -25,8 +25,8 @@ class Enum32; class ObjectModel; // forward declaration class ObjectModelArrayDescriptor; // forward declaration -// Function template used to get constexpr type IDs -// Each type must return a unique type code in the range 1 to 127 +// Function template used to get constexpr type codes +// Each type must return a unique type code in the range 1 to 127 (0 is NoType) template<class T> constexpr TypeCode TypeOf() noexcept; template<> constexpr TypeCode TypeOf<bool>() noexcept { return 1; } @@ -53,18 +53,19 @@ class ObjectModelTableEntry; class ObjectModel; class StringParser; +// Struct used to hold the expressions with polymorphic types struct ExpressionValue { - TypeCode type; - uint8_t param; + TypeCode type; // what type is stored in the union + uint8_t param; // additional parameter, e.g. number of usual displayed decimal places for a float, or table # for an ObjectModel union { bool bVal; float fVal; int32_t iVal; - uint32_t uVal; // used for enumerations, bitmaps and IP addresses (not for integers, we always use int32_t for those) + uint32_t uVal; // used for enumerations, bitmaps and IP addresses (not for integers, we always use int32_t for those) const char *sVal; - const ObjectModel *omVal; + const ObjectModel *omVal; // object of some class derived form ObkectModel const ObjectModelArrayDescriptor *omadVal; }; @@ -87,36 +88,75 @@ struct ExpressionValue void Set(const char *s) noexcept { type = TYPE_OF(const char*); sVal = s; } }; -// Entry to describe an array. These should be brace-initializable in flash memory. +enum class ObjectModelReportFlags : uint16_t +{ + none = 0, + shortForm = 1 +}; + +// Flags field of a table entry +enum class ObjectModelEntryFlags : uint8_t +{ + none = 0, // nothing special + live = 1, // fast changing data, included in common status response + canAlter = 2, // we can alter this value +}; + +// Context passed to object model functions +class ObjectExplorationContext +{ +public: + ObjectExplorationContext(ObjectModelReportFlags rf, ObjectModelEntryFlags ff) noexcept : numIndices(0), reportFlags(rf), filterFlags(ff) { } + + void AddIndex(unsigned int index) THROWS_GCODE_EXCEPTION; + void RemoveIndex() THROWS_GCODE_EXCEPTION; + unsigned int GetIndex(size_t n) const THROWS_GCODE_EXCEPTION; + size_t GetNumIndices() const noexcept { return numIndices; } + ObjectModelReportFlags GetReportFlags() const noexcept { return reportFlags; } + ObjectModelEntryFlags GetFilterFlags() const noexcept { return filterFlags; } + bool ShortFormReport() const noexcept { return ((uint16_t)reportFlags & (uint16_t)ObjectModelReportFlags::shortForm) != 0; } + +private: + static constexpr size_t MaxIndices = 4; // max depth of array nesting + + size_t numIndices; // the number of indices stored + unsigned int indices[MaxIndices]; + ObjectModelReportFlags reportFlags; + ObjectModelEntryFlags filterFlags; +}; + +// Entry to describe an array of objects or values. These must be brace-initializable into flash memory. class ObjectModelArrayDescriptor { public: - size_t (*GetNumElements)(const ObjectModel*) noexcept; - ExpressionValue (*GetElement)(const ObjectModel*, size_t) noexcept; + size_t (*GetNumElements)(const ObjectModel*, const ObjectExplorationContext&) noexcept; + ExpressionValue (*GetElement)(const ObjectModel*, ObjectExplorationContext&) noexcept; }; +// Class from which other classes that represent part of the object model are derived class ObjectModel { public: - enum ReportFlags : uint16_t - { - flagsNone, - flagShortForm = 1 - }; - ObjectModel() noexcept; - // Construct a JSON representation of those parts of the object model requested by the user - bool ReportAsJson(OutputBuffer *buf, uint8_t tableNumber, const char *filter, ReportFlags rflags) const noexcept; + // Construct a JSON representation of those parts of the object model requested by the user. This version is called on the root of the tree. + bool ReportAsJson(OutputBuffer *buf, const char *filter, ObjectModelReportFlags rf, ObjectModelEntryFlags ff) const THROWS_GCODE_EXCEPTION; - // Report an entire array as JSON - bool ReportArrayAsJson(OutputBuffer *buf, const ObjectModelArrayDescriptor *omad, const char *filter, ReportFlags rflags) const noexcept; + // Get the value of an object. This version is called on the root of the tree. + ExpressionValue GetObjectValue(const StringParser& sp, const char *idString) const THROWS_GCODE_EXCEPTION; // Function to report a value or object as JSON - bool ReportItemAsJson(ExpressionValue val, OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags) const noexcept; + bool ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& context, ExpressionValue val, const char *filter) const THROWS_GCODE_EXCEPTION; + +protected: + // Construct a JSON representation of those parts of the object model requested by the user + bool ReportAsJson(OutputBuffer *buf, ObjectExplorationContext& context, uint8_t tableNumber, const char *filter) const THROWS_GCODE_EXCEPTION; + + // Report an entire array as JSON + bool ReportArrayAsJson(OutputBuffer *buf, ObjectExplorationContext& context, const ObjectModelArrayDescriptor *omad, const char *filter) const THROWS_GCODE_EXCEPTION; - // Get the value of an object when we don't know what its type is - ExpressionValue GetObjectValue(const StringParser& sp, uint8_t tableNumber, const char *idString) const THROWS_PARSE_ERROR; + // Get the value of an object + ExpressionValue GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, uint8_t tableNumber, const char *idString) const THROWS_GCODE_EXCEPTION; // Get the object model table entry for the current level object in the query const ObjectModelTableEntry *FindObjectModelTableEntry(uint8_t tableNumber, const char *idString) const noexcept; @@ -124,24 +164,7 @@ public: // Skip the current element in the ID or filter string static const char* GetNextElement(const char *id) noexcept; -protected: virtual const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept = 0; - -private: - // Get pointers to various types from the object model, returning null if failed -// template<class T> T* GetObjectPointer(const char* idString) noexcept; - -// const char **GetStringObjectPointer(const char *idString) noexcept; -// uint32_t *GetShortEnumObjectPointer(const char *idString) noexcept; -// uint32_t *GetBitmapObjectPointer(const char *idString) noexcept; -}; - -// Flags field of a table entry -enum class ObjectModelEntryFlags : uint8_t -{ - none = 0, // nothing special - live = 1, // fast changing data, included in common status response - canAlter = 2, // we can alter this value }; // Object model table entry @@ -152,7 +175,7 @@ class ObjectModelTableEntry public: // Type declarations // Type of the function pointer in the table entry, that returns the data - typedef ExpressionValue(*DataFetchPtr_t)(const ObjectModel*) noexcept; + typedef ExpressionValue(*DataFetchPtr_t)(const ObjectModel*, ObjectExplorationContext&) noexcept; // Member data. This must be public so that we can brace-initialise table entries. const char * name; // name of this field @@ -162,10 +185,10 @@ public: // Member functions. These must all be 'const'. // Return true if this object table entry matches a filter or query - bool Matches(const char *filter, ObjectModelFilterFlags flags) const noexcept; + bool Matches(const char *filter, const ObjectExplorationContext& context) const noexcept; // See whether we should add the value of this element to the buffer, returning true if it matched the filter and we did add it - bool ReportAsJson(OutputBuffer* buf, const ObjectModel *self, const char* filter, ObjectModel::ReportFlags flags) const noexcept; + bool ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& context, const ObjectModel *self, const char* filter) const noexcept; // Return the name of this field const char* GetName() const noexcept { return name; } @@ -193,8 +216,8 @@ public: return objectModelTable; \ } -#define OBJECT_MODEL_FUNC_BODY(_class,...) [] (const ObjectModel* arg) noexcept { const _class * const self = static_cast<const _class*>(arg); return ExpressionValue(__VA_ARGS__); } -#define OBJECT_MODEL_FUNC_NOSELF(...) [] (const ObjectModel* arg) noexcept { return ExpressionValue(__VA_ARGS__); } +#define OBJECT_MODEL_FUNC_BODY(_class,...) [] (const ObjectModel* arg, ObjectExplorationContext& context) noexcept { const _class * const self = static_cast<const _class*>(arg); return ExpressionValue(__VA_ARGS__); } +#define OBJECT_MODEL_FUNC_NOSELF(...) [] (const ObjectModel* arg, ObjectExplorationContext& context) noexcept { return ExpressionValue(__VA_ARGS__); } #else diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h index 9be957e6..e6e11349 100644 --- a/src/RepRapFirmware.h +++ b/src/RepRapFirmware.h @@ -98,8 +98,8 @@ static_assert(NumNamedPins <= 255 || sizeof(LogicalPin) > 1, "Need 16-bit logica #include "General/SafeStrtod.h" #include "General/SafeVsnprintf.h" -#define THROWS_PARSE_ERROR // we tag this on to function declarations to indicate that they may throw parse errors, which must be caught -#define THROW_INTERNAL_ERROR throw ConstructParseException("internal error at file " __FILE__ "(%d)", __LINE__) +#define THROWS_GCODE_EXCEPTION // we tag this on to function declarations to indicate that they may throw a GCodeException, which must be caught +#define THROW_INTERNAL_ERROR throw GCodeException(-1, -1, "internal error at file " __FILE__ "(%d)", (int32_t)__LINE__) // Type of a driver identifier struct DriverId diff --git a/src/Version.h b/src/Version.h index 05458643..0982d50b 100644 --- a/src/Version.h +++ b/src/Version.h @@ -20,7 +20,7 @@ #endif #ifndef DATE -# define DATE "2020-01-07b1" +# define DATE "2020-01-07b2" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |