Edit GCode line in-place, removing whitespace and comments and converting to uppercase
| 155 | // Edit GCode line in-place, removing whitespace and comments and |
| 156 | // converting to uppercase |
| 157 | void collapseGCode(char* line) { |
| 158 | // parenPtr, if non-NULL, is the address of the character after ( |
| 159 | const char* parenPtr = NULL; |
| 160 | // outPtr is the address where newly-processed characters will be placed. |
| 161 | // outPtr is always less than or equal to inPtr. |
| 162 | char* outPtr = line; |
| 163 | char c; |
| 164 | bool hasComment = false; |
| 165 | for (char* inPtr = line; (c = *inPtr) != '\0'; inPtr++) { |
| 166 | if (isspace(c)) { |
| 167 | continue; |
| 168 | } |
| 169 | switch (c) { |
| 170 | case ')': |
| 171 | if (parenPtr) { |
| 172 | // Terminate comment by replacing ) with NUL |
| 173 | *inPtr = '\0'; |
| 174 | gcode_comment_msg(parenPtr); |
| 175 | parenPtr = NULL; |
| 176 | } |
| 177 | // Strip out ) that does not follow a ( |
| 178 | break; |
| 179 | case '(': |
| 180 | hasComment = true; |
| 181 | // Start the comment at the character after ( |
| 182 | parenPtr = inPtr + 1; |
| 183 | break; |
| 184 | case ';': |
| 185 | // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST. |
| 186 | *outPtr = '\0'; |
| 187 | return; |
| 188 | case '\r': |
| 189 | // In case one sneaks in |
| 190 | break; |
| 191 | default: |
| 192 | if (!parenPtr) { |
| 193 | *outPtr++ = toupper(c); // make upper case |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | // On loop exit, *inPtr is '\0' |
| 198 | |
| 199 | *outPtr = '\0'; |
| 200 | |
| 201 | if (parenPtr) { |
| 202 | // Handle unterminated ( comments |
| 203 | gcode_comment_msg(parenPtr); |
| 204 | } |
| 205 | if (!hasComment && strcmp(line, "%") == 0) { |
| 206 | // Per https://linuxcnc.org/docs/2.6/html/gcode/overview.html#_overview, % lines |
| 207 | // can contain spaces, so this check happens after space removal. |
| 208 | |
| 209 | // Per https://linuxcnc.org/docs/html/gcode/overview.html#gcode:file-requirements |
| 210 | // % only applies to "job" channels like files and macros, not to serial channels |
| 211 | // where the sequence of lines is potentially never-ending. A sender that handles |
| 212 | // files on the host system could apply the % semantics. |
| 213 | |
| 214 | if (Job::active()) { |
no test coverage detected