import re
import shlex
__all__ = ['encode', 'decode']
def encode(command):
def needs_quote(word):
reserved = {' ', '$', '%', '&', '(', ')', '[', ']', '{', '}', '*', '|',
'<', '>', '@', '?', '!'}
state = 0
for current in word:
if state == 0 and current in reserved:
return True
elif state == 0 and current == '\\':
state = 1
elif state == 1 and current in reserved | {'\\'}:
state = 0
elif state == 0 and current == '"':
state = 2
elif state == 2 and current == '"':
state = 0
elif state == 0 and current == "'":
state = 3
elif state == 3 and current == "'":
state = 0
return state != 0
def escape(word):
table = {'\\': '\\\\', '"': '\\"'}
escaped = ''.join([table.get(c, c) for c in word])
return '"' + escaped + '"' if needs_quote(word) else escaped
return " ".join([escape(arg) for arg in command])
def decode(string):
def unescape(arg):
if len(arg) >= 2 and arg[0] == arg[-1] and arg[0] == '"':
arg = arg[1:-1]
return re.sub(r'\\(["\\])', r'\1', arg)
return re.sub(r'\\([\\ $%&\(\)\[\]\{\}\*|<>@?!])', r'\1', arg)
return [unescape(arg) for arg in shlex.split(string)]