diff options
-rw-r--r-- | src/GCodes/GCodeBuffer/StringParser.cpp | 31 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 35 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 11 | ||||
-rw-r--r-- | src/Version.h | 2 |
4 files changed, 51 insertions, 28 deletions
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp index c21042f4..5c82b1cc 100644 --- a/src/GCodes/GCodeBuffer/StringParser.cpp +++ b/src/GCodes/GCodeBuffer/StringParser.cpp @@ -706,13 +706,13 @@ void StringParser::DecodeCommand() noexcept } } - // Find where the end of the command is. We assume that a G or M preceded by a space and not inside quotes is the start of a new command. + // Find where the end of the command is. We assume that a G or M preceded by a space and not inside quotes or { } is the start of a new command. bool inQuotes = false; + unsigned int braceCount = 0; bool primed = false; for (commandEnd = parameterStart; commandEnd < gcodeLineEnd; ++commandEnd) { const char c = gb.buffer[commandEnd]; - char c2; if (c == '"') { inQuotes = !inQuotes; @@ -720,11 +720,28 @@ void StringParser::DecodeCommand() noexcept } else if (!inQuotes) { - if (primed && ((c2 = toupper(c)) == 'G' || c2 == 'M')) + char c2; + if (c == '{') + { + ++braceCount; + primed = false; + } + else if (c == '}') + { + if (braceCount != 0) + { + --braceCount; + } + primed = false; + } + else if (primed && ((c2 = toupper(c)) == 'G' || c2 == 'M')) { break; } - primed = (c == ' ' || c == '\t'); + else if (braceCount == 0) + { + primed = (c == ' ' || c == '\t'); + } } } } @@ -1872,8 +1889,6 @@ ExpressionValue StringParser::ParseExpression(StringBuffer& stringBuffer, uint8_ ++readPointer; } - SkipWhiteSpace(); - // Handle operators that do not always evaluate their second operand switch (opChar) { @@ -2310,7 +2325,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff } String<MaxVariableNameLength> id; - ObjectExplorationContext context("v", 99, applyLengthOperator); + ObjectExplorationContext context("v", applyLengthOperator, 99, gb.machineState->lineNumber, readPointer); // Loop parsing identifiers and index expressions // When we come across an index expression, evaluate it, add it to the context, and place a marker in the identifier string. @@ -2583,7 +2598,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff return rslt; } - return reprap.GetObjectValue(*this, context, id.c_str()); + return reprap.GetObjectValue(context, id.c_str()); } GCodeException StringParser::ConstructParseException(const char *str) const diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index 8e3d4f72..d12195b1 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -10,7 +10,6 @@ #if SUPPORT_OBJECT_MODEL #include <OutputMemory.h> -#include <GCodes/GCodeBuffer/StringParser.h> #include <cstring> #include <General/SafeStrtod.h> @@ -63,8 +62,9 @@ ObjectModel::ObjectModel() noexcept // ObjectExplorationContext members -ObjectExplorationContext::ObjectExplorationContext(const char *reportFlags, unsigned int initialMaxDepth, bool wal) noexcept +ObjectExplorationContext::ObjectExplorationContext(const char *reportFlags, bool wal, unsigned int initialMaxDepth, int p_line, int p_col) noexcept : maxDepth(initialMaxDepth), currentDepth(0), numIndicesProvided(0), numIndicesCounted(0), + line(p_line), column(p_col), shortForm(false), onlyLive(false), includeVerbose(false), wantArrayLength(wal), includeNulls(false) { while (true) @@ -127,6 +127,11 @@ bool ObjectExplorationContext::ShouldReport(const ObjectModelEntryFlags f) const && (includeVerbose || ((uint8_t)f & (uint8_t)ObjectModelEntryFlags::verbose) == 0); } +GCodeException ObjectExplorationContext::ConstructParseException(const char *msg) const noexcept +{ + return GCodeException(line, column, msg); +} + // Report this object void ObjectModel::ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& context, uint8_t tableNumber, const char* filter) const { @@ -177,7 +182,7 @@ void ObjectModel::ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& cont void ObjectModel::ReportAsJson(OutputBuffer *buf, const char *filter, const char *reportFlags, bool wantArrayLength) const { const unsigned int defaultMaxDepth = (wantArrayLength) ? 99 : (filter[0] == 0) ? 1 : 99; - ObjectExplorationContext context(reportFlags, defaultMaxDepth, wantArrayLength); + ObjectExplorationContext context(reportFlags, wantArrayLength, defaultMaxDepth); ReportAsJson(buf, context, 0, filter); } @@ -557,20 +562,20 @@ int ObjectModelTableEntry::IdCompare(const char *id) const noexcept } // Get the value of an object -ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, const char *idString, uint8_t tableNumber) const +ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, const char *idString, uint8_t tableNumber) const { const ObjectModelTableEntry *const e = FindObjectModelTableEntry(tableNumber, idString); if (e == nullptr) { - throw sp.ConstructParseException("unknown value %s", idString); + throw context.ConstructParseException("unknown value"); // idString will have gone out of scope by the time the exception is caught } idString = GetNextElement(idString); ExpressionValue val = e->func(this, context); - return GetObjectValue(sp, context, val, idString); + return GetObjectValue(context, val, idString); } -ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, ExpressionValue val, const char *idString) const +ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, ExpressionValue val, const char *idString) const { switch (val.type) { @@ -583,7 +588,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplor } if (*idString != '^') { - throw sp.ConstructParseException("missing array index"); + throw context.ConstructParseException("missing array index"); } context.AddIndex(); @@ -591,19 +596,19 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplor if (context.GetLastIndex() < 0 || (size_t)context.GetLastIndex() >= val.omadVal->GetNumElements(this, context)) { - throw sp.ConstructParseException("array index out of bounds"); + throw context.ConstructParseException("array index out of bounds"); } const ExpressionValue arrayElement = val.omadVal->GetElement(this, context); - return GetObjectValue(sp, context, arrayElement, idString + 1); + return GetObjectValue(context, arrayElement, idString + 1); } case TYPE_OF(const ObjectModel*): if (*idString == '.') { - return val.omVal->GetObjectValue(sp, context, idString + 1, val.param); + return val.omVal->GetObjectValue(context, idString + 1, val.param); } - throw sp.ConstructParseException((*idString == 0) ? "selected value has non-primitive type" : "syntax error in value selector string"); + throw context.ConstructParseException((*idString == 0) ? "selected value has non-primitive type" : "syntax error in value selector string"); case TYPE_OF(Bitmap<uint16_t>): case TYPE_OF(Bitmap<uint32_t>): @@ -632,7 +637,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplor } if (val.uVal > 0x7FFFFFFF) { - throw sp.ConstructParseException("bitmap too large to convert to integer"); + throw context.ConstructParseException("bitmap too large to convert to integer"); } return ExpressionValue((int32_t)val.uVal); @@ -662,7 +667,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplor } if (val.Get56BitValue() > 0x7FFFFFFF) { - throw sp.ConstructParseException("bitmap too large to convert to integer"); + throw context.ConstructParseException("bitmap too large to convert to integer"); } return ExpressionValue((int32_t)val.uVal); @@ -687,7 +692,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, ObjectExplor break; } - throw sp.ConstructParseException("reached primitive type before end of selector string"); + throw context.ConstructParseException("reached primitive type before end of selector string"); } #endif diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index 54d007b6..b076026b 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -62,7 +62,6 @@ template<> constexpr TypeCode TypeOf<MacAddress> () noexcept { return 16; } // Forward declarations class ObjectModelTableEntry; class ObjectModel; -class StringParser; // Struct used to hold the expressions with polymorphic types struct ExpressionValue @@ -131,7 +130,7 @@ enum class ObjectModelEntryFlags : uint8_t class ObjectExplorationContext { public: - ObjectExplorationContext(const char *reportFlags, unsigned int initialMaxDepth, bool wal) noexcept; + ObjectExplorationContext(const char *reportFlags, bool wal, unsigned int initialMaxDepth, int p_line = -1, int p_col = -1) noexcept; void SetMaxDepth(unsigned int d) noexcept { maxDepth = d; } bool IncreaseDepth() noexcept { if (currentDepth < maxDepth) { ++currentDepth; return true; } return false; } @@ -148,6 +147,8 @@ public: bool WantArrayLength() const noexcept { return wantArrayLength; } bool ShouldIncludeNulls() const noexcept { return includeNulls; } + GCodeException ConstructParseException(const char *msg) const noexcept; + private: static constexpr size_t MaxIndices = 4; // max depth of array nesting @@ -156,6 +157,8 @@ private: size_t numIndicesProvided; // the number of indices provided, when we are doing a value lookup size_t numIndicesCounted; // the number of indices passed in the search string int32_t indices[MaxIndices]; + int line; + int column; bool shortForm; bool onlyLive; bool includeVerbose; @@ -183,7 +186,7 @@ public: void ReportAsJson(OutputBuffer *buf, const char *filter, const char *reportFlags, bool wantArrayLength) const THROWS_GCODE_EXCEPTION; // Get the value of an object via the table - ExpressionValue GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, const char *idString, uint8_t tableNumber = 0) const THROWS_GCODE_EXCEPTION; + ExpressionValue GetObjectValue(ObjectExplorationContext& context, const char *idString, uint8_t tableNumber = 0) const THROWS_GCODE_EXCEPTION; // Function to report a value or object as JSON void ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& context, ExpressionValue val, const char *filter) const THROWS_GCODE_EXCEPTION; @@ -199,7 +202,7 @@ protected: void ReportArrayAsJson(OutputBuffer *buf, ObjectExplorationContext& context, const ObjectModelArrayDescriptor *omad, const char *filter) const THROWS_GCODE_EXCEPTION; // Get the value of an object that we hold - ExpressionValue GetObjectValue(const StringParser& sp, ObjectExplorationContext& context, ExpressionValue val, const char *idString) const THROWS_GCODE_EXCEPTION; + ExpressionValue GetObjectValue(ObjectExplorationContext& context, ExpressionValue val, 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; diff --git a/src/Version.h b/src/Version.h index a729174c..6733d863 100644 --- a/src/Version.h +++ b/src/Version.h @@ -20,7 +20,7 @@ #endif #ifndef DATE -# define DATE "2020-01-26b1" +# define DATE "2020-01-27b1" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |