Skip to content

Instantly share code, notes, and snippets.

@antirez
Created February 28, 2014 09:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antirez/9267914 to your computer and use it in GitHub Desktop.
Save antirez/9267914 to your computer and use it in GitHub Desktop.
UNESCAPES = {
'a' => "\x07", 'b' => "\x08", 't' => "\x09",
'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
'r' => "\x0d", 'e' => "\x1b", "\\\\" => "\x5c",
"\"" => "\x22", "'" => "\x27"
}
puts UNESCAPES.keys.join
#exit
def unescape_literal(str)
# Escape all the things
str.gsub(/\\(?:([#{UNESCAPES.keys.join}])|u([\da-fA-F]{4}))|\\0?x([\da-fA-F]{2})/) {
if $1
if $1 == '\\' then '\\' else UNESCAPES[$1] end
elsif $2 # escape \u0000 unicode
["#$2".hex].pack('U*')
elsif $3 # escape \0xff or \xff
[$3].pack('H2')
end
}
end
# Parse a command line style list of arguments that can be optionally
# delimited by '' or "" quotes, and return it as an array of arguments.
#
# Strings delimited by "" are unescaped by converting escape characters
# such as \n \x.. to their value according to the unescape_literal() function.
#
# Example of line that this function can parse:
#
# "Hello World\n" other arguments 'this is a single argument'
#
# The above example will return an array of four strings.
def unescape_line(line)
argv = []
arg = ""
inquotes = false
pos = 0
while pos < line.length
char = line[pos..pos] # Current character
isspace = char =~ /\s/
# Skip empty spaces if we are between strings
if !inquotes && isspace
if arg.length != 0
argv << arg
arg = ""
end
pos += 1
next
end
# Append current char to string
arg << char
pos += 1
if arg.length == 1 && (char == '"' || char == '\'')
inquotes = char
elsif arg.length > 1 && inquotes && char == inquotes
inquotes = false
end
end
# Put the last argument into the array
argv << arg if arg.length != 0
# We need to make some post-processing.
# For strings delimited by '' we just strip initial and final '.
# For strings delimited by "" we call unescape_literal().
# This is not perfect but should be enough for redis.io interactive
# editing.
argv.map {|x|
if x[0..0] == '"'
unescape_literal(x[1..-2])
elsif x[0..0] == '\''
x[1..-2]
else
x
end
}
end
while true
print "prompt> "
STDOUT.flush
line = STDIN.gets
puts unescape_line(line).join(",")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment