Add a byte to the code being assembled. If false is returned, the code is not yet complete. If true, it is complete and ready to be acted upon and 'indent' is the number of leading white space characters.
| 73 | // Add a byte to the code being assembled. If false is returned, the code is not yet complete. |
| 74 | // If true, it is complete and ready to be acted upon and 'indent' is the number of leading white space characters. |
| 75 | bool StringParser::Put(char c) noexcept |
| 76 | { |
| 77 | if (c != 0) |
| 78 | { |
| 79 | ++commandLength; |
| 80 | } |
| 81 | |
| 82 | // We now discard CR if we are reading from file. It makes line number counting easier and it's unlikely that a pre-OSX Mac will be used with a Duet. |
| 83 | // When not reading from file we still accept CR as a line terminator, for compatibility with Putty and some other terminal emulators. |
| 84 | if (c == '\r' && gb.IsDoingFile()) |
| 85 | { |
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | if (c == 0 || c == '\n' || c == '\r') |
| 90 | { |
| 91 | return LineFinished(); |
| 92 | } |
| 93 | |
| 94 | if (c == (char)0x7Fu && gb.bufferState != GCodeBufferState::discarding) |
| 95 | { |
| 96 | // The UART receiver stores 0x7F in the buffer if an overrun or framing errors occurs. So discard the command and resync on the next newline. |
| 97 | gcodeLineEnd = 0; |
| 98 | gb.bufferState = GCodeBufferState::discarding; |
| 99 | } |
| 100 | |
| 101 | // Process the incoming character in a state machine |
| 102 | bool again; |
| 103 | do |
| 104 | { |
| 105 | again = false; |
| 106 | switch (gb.bufferState) |
| 107 | { |
| 108 | case GCodeBufferState::parseNotStarted: // we haven't started parsing yet |
| 109 | braceCount = 0; |
| 110 | switch (c) |
| 111 | { |
| 112 | case 'N': |
| 113 | case 'n': |
| 114 | hadLineNumber = true; |
| 115 | crc16.Reset(0); |
| 116 | AddToChecksum(c); |
| 117 | gb.bufferState = GCodeBufferState::parsingLineNumber; |
| 118 | receivedLineNumber = 0; |
| 119 | break; |
| 120 | |
| 121 | case ' ': |
| 122 | AddToChecksum(c); |
| 123 | ++commandIndent; |
| 124 | seenLeadingSpace = true; |
| 125 | break; |
| 126 | |
| 127 | case '\t': |
| 128 | AddToChecksum(c); |
| 129 | commandIndent = (commandIndent + 4) & ~3; // move on at least 1 to next multiple of 4 |
| 130 | seenLeadingTab = true; |
| 131 | break; |
| 132 |