* Populate the command line state (command_letter, codenum, subcode, and string_arg) * by parsing a single line of G-Code. 58 bytes of SRAM are used to speed up seen/value. */
| 111 | * by parsing a single line of G-Code. 58 bytes of SRAM are used to speed up seen/value. |
| 112 | */ |
| 113 | void GCodeParser::parse(char *p) { |
| 114 | |
| 115 | reset(); // No codes to report |
| 116 | |
| 117 | auto uppercase = [](char c) { |
| 118 | return TERN0(GCODE_CASE_INSENSITIVE, WITHIN(c, 'a', 'z')) ? c + 'A' - 'a' : c; |
| 119 | }; |
| 120 | |
| 121 | // Skip spaces |
| 122 | while (*p == ' ') ++p; |
| 123 | |
| 124 | // Skip N[-0-9] if included in the command line |
| 125 | if (uppercase(*p) == 'N' && NUMERIC_SIGNED(p[1])) { |
| 126 | //TERN_(FASTER_GCODE_PARSER, set('N', p + 1)); // (optional) Set the 'N' parameter value |
| 127 | p += 2; // skip N[-0-9] |
| 128 | while (NUMERIC(*p)) ++p; // skip [0-9]* |
| 129 | while (*p == ' ') ++p; // skip [ ]* |
| 130 | } |
| 131 | |
| 132 | // *p now points to the current command, which should be G, M, or T |
| 133 | command_ptr = p; |
| 134 | |
| 135 | // Get the command letter, which must be G, M, or T |
| 136 | const char letter = uppercase(*p++); |
| 137 | |
| 138 | // Nullify asterisk and trailing whitespace |
| 139 | char *starpos = strchr(p, '*'); |
| 140 | if (starpos) { |
| 141 | --starpos; // * |
| 142 | while (*starpos == ' ') --starpos; // spaces... |
| 143 | starpos[1] = '\0'; |
| 144 | } |
| 145 | |
| 146 | #if ANY(MARLIN_DEV_MODE, SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) |
| 147 | #define SIGNED_CODENUM 1 |
| 148 | #endif |
| 149 | |
| 150 | /** |
| 151 | * Screen for good command letters. |
| 152 | * With Realtime Reporting, commands S000, P000, and R000 are allowed. |
| 153 | */ |
| 154 | #if ENABLED(REALTIME_REPORTING_COMMANDS) |
| 155 | switch (letter) { |
| 156 | case 'P': case 'R' ... 'S': { |
| 157 | uint8_t digits = 0; |
| 158 | char *a = p; |
| 159 | while (*a++ == '0') digits++; // Count up '0' characters |
| 160 | if (digits == 3) { // Three '0' digits is a good command |
| 161 | codenum = 0; |
| 162 | command_letter = letter; |
| 163 | return; |
| 164 | } |
| 165 | } |
| 166 | } |
| 167 | #endif |
| 168 | |
| 169 | /** |
| 170 | * Screen for good command letters. G, M, and T are always accepted. |