mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/shellwords.rb: refactored. [ruby-core:06581]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9519 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6ddd56a130
commit
e8201d12db
3 changed files with 60 additions and 22 deletions
|
@ -1,3 +1,7 @@
|
|||
Wed Nov 9 08:39:38 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* lib/shellwords.rb: refactored. [ruby-core:06581]
|
||||
|
||||
Tue Nov 8 17:35:53 2005 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
||||
|
||||
* intern.h, eval.c (rb_thread_signal_raise): costified.
|
||||
|
|
|
@ -28,31 +28,20 @@ module Shellwords
|
|||
def shellwords(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 = ''
|
||||
last = 0
|
||||
sep = nil
|
||||
line.scan(/\G\s*(?:([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?))(\s+|\z)?/m) do
|
||||
last = $~.end(0)
|
||||
sep = $~.begin(5)
|
||||
field << ($1 || $2 || ($3 || $4).gsub(/\\(?=.)/, ''))
|
||||
if sep
|
||||
words << field
|
||||
field = ''
|
||||
end
|
||||
words.push(field)
|
||||
end
|
||||
raise ArgumentError, "Unmatched double quote: #{line}" if line[last]
|
||||
words
|
||||
end
|
||||
|
||||
|
|
45
test/test_shellwords.rb
Normal file
45
test/test_shellwords.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
require 'test/unit'
|
||||
require 'shellwords'
|
||||
|
||||
class TestShellwords < Test::Unit::TestCase
|
||||
|
||||
include Shellwords
|
||||
|
||||
def setup
|
||||
@not_string = Class.new
|
||||
@cmd = "ruby my_prog.rb | less"
|
||||
end
|
||||
|
||||
|
||||
def test_not_string
|
||||
assert_raises ArgumentError do
|
||||
shellwords(@not_string)
|
||||
end
|
||||
end
|
||||
|
||||
def test_string
|
||||
assert_instance_of(Array, shellwords(@cmd))
|
||||
assert_equal(4, shellwords(@cmd).length)
|
||||
end
|
||||
|
||||
def test_unmatched_double_quote
|
||||
bad_cmd = 'one two "three'
|
||||
assert_raises ArgumentError do
|
||||
shellwords(bad_cmd)
|
||||
end
|
||||
end
|
||||
|
||||
def test_unmatched_single_quote
|
||||
bad_cmd = "one two 'three"
|
||||
assert_raises ArgumentError do
|
||||
shellwords(bad_cmd)
|
||||
end
|
||||
end
|
||||
|
||||
def test_unmatched_quotes
|
||||
bad_cmd = "one '"'"''""'""
|
||||
assert_raises ArgumentError do
|
||||
shellwords(bad_cmd)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue