lib/rubysl/shellwords/shellwords.rb in rubysl-shellwords-1.0.1 vs lib/rubysl/shellwords/shellwords.rb in rubysl-shellwords-2.0.0
- old
+ new
@@ -28,35 +28,19 @@
#
# argv = 'here are "two words"'.shellsplit
# argv #=> ["here", "are", "two words"]
#
def shellsplit(line)
- line = String.new(line) rescue
- raise(ArgumentError, "Argument must be a string")
- line.lstrip!
words = []
- until line.empty?
- field = ''
- loop do
- if line.sub!(/\A"(([^"\\]|\\.)*)"/, '') then
- snippet = $1.gsub(/\\(.)/, '\1')
- elsif line =~ /\A"/ then
- raise ArgumentError, "Unmatched double quote: #{line}"
- elsif line.sub!(/\A'([^']*)'/, '') then
- snippet = $1
- elsif line =~ /\A'/ then
- raise ArgumentError, "Unmatched single quote: #{line}"
- elsif line.sub!(/\A\\(.)?/, '') then
- snippet = $1 || '\\'
- elsif line.sub!(/\A([^\s\\'"]+)/, '') then
- snippet = $1
- else
- line.lstrip!
- break
- end
- field.concat(snippet)
+ field = ''
+ line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
+ |word, sq, dq, esc, garbage, sep|
+ raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
+ field << (word || sq || (dq || esc).gsub(/\\(?=.)/, ''))
+ if sep
+ words << field
+ field = ''
end
- words.push(field)
end
words
end
alias shellwords shellsplit