[前][次][番号順一覧][スレッド一覧]

ruby-changes:1936

From: ko1@a...
Date: 11 Sep 2007 17:28:02 +0900
Subject: [ruby-changes:1936] knu - Ruby:r13427 (trunk): * lib/shellwords.rb: Add shellescape() and shelljoin().

knu	2007-09-11 17:27:48 +0900 (Tue, 11 Sep 2007)

  New Revision: 13427

  Modified files:
    trunk/ChangeLog
    trunk/lib/shellwords.rb

  Log:
    * lib/shellwords.rb: Add shellescape() and shelljoin().
    
    * lib/shellwords.rb: Rename shellwords() to shellsplit() and make
      the former an alias to the latter.
    
    * lib/shellwords.rb: Add escape(), split(), join() as class
      methods, which are aliases to their respective long names
      prefixed with `shell'.
    
    * lib/shellwords.rb: Add String#shellescape(), String#shellsplit()
      and Array#shelljoin() for convenience.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/shellwords.rb?r1=13427&r2=13426
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13427&r2=13426

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13426)
+++ ChangeLog	(revision 13427)
@@ -1,3 +1,17 @@
+Tue Sep 11 17:25:59 2007  Akinori MUSHA  <knu@i...>
+
+	* lib/shellwords.rb: Add shellescape() and shelljoin().
+
+	* lib/shellwords.rb: Rename shellwords() to shellsplit() and make
+	  the former an alias to the latter.
+
+	* lib/shellwords.rb: Add escape(), split(), join() as class
+	  methods, which are aliases to their respective long names
+	  prefixed with `shell'.
+
+	* lib/shellwords.rb: Add String#shellescape(), String#shellsplit()
+	  and Array#shelljoin() for convenience.
+
 Mon Sep 10 15:48:31 2007  Tanaka Akira  <akr@f...>
 
 	* range.c: represent initialized state using EXCL instead of FL_USER3.
Index: lib/shellwords.rb
===================================================================
--- lib/shellwords.rb	(revision 13426)
+++ lib/shellwords.rb	(revision 13427)
@@ -1,31 +1,32 @@
 #
-# shellwords.rb: Split text into an array of tokens a la UNIX shell
+# shellwords.rb: Manipulates strings a la UNIX Bourne shell
 #
 
 #
-# This module is originally a port of shellwords.pl, but modified to
-# conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
+# This module manipulates strings according to the word parsing rules
+# of the UNIX Bourne shell.
 #
-# Examples:
+# The shellwords() function was originally a port of shellwords.pl,
+# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
 #
-#   require 'shellwords'
-#   words = Shellwords.shellwords(line)
+# Authors:
+#   - Wakou Aoyama
+#   - Akinori MUSHA <knu@i...>
 #
-# or
-#
-#   require 'shellwords'
-#   include Shellwords
-#   words = shellwords(line)
-#
 module Shellwords
-
   #
-  # Split text into an array of tokens in the same way the UNIX Bourne
-  # shell does.
+  # Splits a string into an array of tokens in the same way the UNIX
+  # Bourne shell does.
   #
-  # See the +Shellwords+ module documentation for an example.
+  #   argv = Shellwords.split('here are "two words"')
+  #   argv #=> ["here", "are", "two words"]
   #
-  def shellwords(line)
+  # +String#shellsplit+ is a shorthand for this function.
+  #
+  #   argv = 'here are "two words"'.shellsplit
+  #   argv #=> ["here", "are", "two words"]
+  #
+  def shellsplit(line)
     words = []
     field = ''
     line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
@@ -40,5 +41,113 @@
     words
   end
 
-  module_function :shellwords
+  alias shellwords shellsplit
+
+  module_function :shellsplit, :shellwords
+
+  class << self
+    alias split shellsplit
+  end
+
+  #
+  # Escapes a string so that it can be safely used in a Bourne shell
+  # command line.
+  #
+  # Note that a resulted string should be used unquoted and is not
+  # intended for use in double quotes nor in single quotes.
+  #
+  #   open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
+  #     # ...
+  #   }
+  #
+  # +String#shellescape+ is a shorthand for this function.
+  #
+  #   open("| grep #{pattern.shellescape} file") { |pipe|
+  #     # ...
+  #   }
+  #
+  def shellescape(str)
+    # An empty argument will be skipped, so return empty quotes.
+    return "''" if str.empty?
+
+    str = str.dup
+
+    # Process as a single byte sequence because not all shell
+    # implementations are multibyte aware.
+    str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
+
+    # A LF cannot be escaped with a backslash because a backslash + LF
+    # combo is regarded as line continuation and simply ignored.
+    str.gsub!(/\n/, "'\n'")
+
+    return str
+  end
+
+  module_function :shellescape
+
+  class << self
+    alias escape shellsplit
+  end
+
+  #
+  # Builds a command line string from an argument list +array+ joining
+  # all elements escaped for Bourne shell and separated by a space.
+  #
+  #   open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe|
+  #     # ...
+  #   }
+  #
+  # +Array#shelljoin+ is a shorthand for this function.
+  #
+  #   open('|' + ['grep', pattern, *files].shelljoin) { |pipe|
+  #     # ...
+  #   }
+  #
+  def shelljoin(array)
+    array.map { |arg| shellescape(arg) }.join(' ')
+  end
+
+  module_function :shelljoin
+
+  class << self
+    alias join shelljoin
+  end
 end
+
+class String
+  #
+  # call-seq:
+  #   str.shellsplit => array
+  #
+  # Splits +str+ into an array of tokens in the same way the UNIX
+  # Bourne shell does.  See +Shellwords::shellsplit+ for details.
+  #
+  def shellsplit
+    Shellwords.split(self)
+  end
+
+  #
+  # call-seq:
+  #   str.shellescape => string
+  #
+  # Escapes +str+ so that it can be safely used in a Bourne shell
+  # command line.  See +Shellwords::shellescape+ for details.
+  #
+  def shellescape
+    Shellwords.escape(self)
+  end
+end
+
+class Array
+  #
+  # call-seq:
+  #   array.shelljoin => string
+  #
+  # Builds a command line string from an argument list +array+ joining
+  # all elements escaped for Bourne shell and separated by a space.
+  # See +Shellwords::shelljoin+ for details.
+  #
+  def shelljoin
+    Shellwords.join(self)
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]