Skip to content

Commit

Permalink
gcode: Improve handling of extended g-code commands with '*;#' charac…
Browse files Browse the repository at this point in the history
…ters

The g-code command parser did not allow three characters to be passed
as parameters to commands (asterisk, semicolon, pound sign).  Rework
the parsing code to better leverage the python shlex package so that
these characters can be supported.

In particular, this should allow better support for printing g-code
files that have unusual characters in the filename.

Signed-off-by: Kevin O'Connor <[email protected]>
  • Loading branch information
KevinOConnor committed Nov 26, 2024
1 parent f2e69a3 commit 19e3f4e
Showing 1 changed file with 19 additions and 15 deletions.
34 changes: 19 additions & 15 deletions klippy/gcode.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Parse gcode commands
#
# Copyright (C) 2016-2021 Kevin O'Connor <[email protected]>
# Copyright (C) 2016-2024 Kevin O'Connor <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, re, logging, collections, shlex
Expand Down Expand Up @@ -251,26 +251,30 @@ def _respond_error(self, msg):
def _respond_state(self, state):
self.respond_info("Klipper state: %s" % (state,), log=False)
# Parameter parsing helpers
extended_r = re.compile(
r'^\s*(?:N[0-9]+\s*)?'
r'(?P<cmd>[a-zA-Z_][a-zA-Z0-9_]+)(?:\s+|$)'
r'(?P<args>[^#*;]*?)'
r'\s*(?:[#*;].*)?$')
linenum_r = re.compile(r'^(?:[nN][0-9]+)(?P<cmdline>.*?)(?:[*][0-9]+)?$')
def _get_extended_params(self, gcmd):
m = self.extended_r.match(gcmd.get_commandline())
if m is None:
raise self.error("Malformed command '%s'"
% (gcmd.get_commandline(),))
eargs = m.group('args')
line = gcmd.get_commandline()
# Check if g-code "line numbers" were added and remove if so
m = self.linenum_r.match(line)
if m is not None:
line = m.group('cmdline').strip()
# Extract args while allowing shell style quoting
s = shlex.shlex(line, posix=True)
s.whitespace_split = True
s.commenters = '#;'
try:
eparams = [earg.split('=', 1) for earg in shlex.split(eargs)]
args = list(s)
if args[0].upper() != gcmd.get_command():
raise ValueError("Command mismatch")
eparams = [earg.split('=', 1) for earg in args[1:]]
eparams = { k.upper(): v for k, v in eparams }
gcmd._params.clear()
gcmd._params.update(eparams)
return gcmd
except ValueError as e:
raise self.error("Malformed command '%s'"
% (gcmd.get_commandline(),))
# Update gcmd with new parameters
gcmd._params.clear()
gcmd._params.update(eparams)
return gcmd
# G-Code special command handlers
def cmd_default(self, gcmd):
cmd = gcmd.get_command()
Expand Down

0 comments on commit 19e3f4e

Please sign in to comment.