everything related to duct tape audio suite (dtas)
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: <dtas-all@nongnu.org>
Cc: Eric Wong <e@80x24.org>
Subject: [PATCH] process: implement array expansion to preserve spaces
Date: Mon, 18 May 2015 00:21:15 +0000	[thread overview]
Message-ID: <1431908475-15700-1-git-send-email-e@80x24.org> (raw)

This can make it easier to specify mcompand parameters in
socks, as those require separate levels of parameter parsing
and require quoting in shell.
---
 lib/dtas/process.rb | 39 +++++++++++++++++++++++++++++++--------
 test/test_env.rb    | 16 ++++++++++++++++
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/lib/dtas/process.rb b/lib/dtas/process.rb
index 8c5e8e9..f5f9a9e 100644
--- a/lib/dtas/process.rb
+++ b/lib/dtas/process.rb
@@ -1,6 +1,7 @@
 # Copyright (C) 2013-2015 all contributors <dtas-all@nongnu.org>
 # License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
 require 'io/wait'
+require 'shellwords'
 require_relative '../dtas'
 require_relative 'xs'
 
@@ -23,6 +24,7 @@ module DTAS::Process # :nodoc:
 
   # expand common shell constructs based on environment variables
   # this is order-dependent, but Ruby 1.9+ hashes are already order-dependent
+  # This recurses
   def env_expand(env, opts)
     env = env.dup
     if false == opts.delete(:expand)
@@ -31,19 +33,40 @@ module DTAS::Process # :nodoc:
       end
     else
       env.each do |key, val|
-        case val
-        when Numeric # stringify numeric values to simplify users' lives
-          env[key] = val.to_s
-        when /[\`\$]/ # perform variable/command expansion
-          tmp = env.dup
-          tmp.delete(key)
-          val = qx(tmp, "echo #{val}", expand: false)
-          env[key] = val.chomp
+        case val = env_expand_i(env, key, val)
+        when Array
+          val.flatten!
+          env[key] = Shellwords.join(val)
         end
       end
     end
   end
 
+  def env_expand_i(env, key, val)
+    case val
+    when Numeric # stringify numeric values to simplify users' lives
+      env[key] = val.to_s
+    when /[\`\$]/ # perform variable/command expansion
+      tmp = env.dup
+      tmp.delete(key)
+      tmp.each do |k,v|
+        # best effort, this can get wonky
+        tmp[k] = Shellwords.join(v.flatten) if Array === v
+      end
+      val = qx(tmp, "echo #{val}", expand: false)
+      env[key] = val.chomp
+    when Array
+      env[key] = env_expand_ary(env, key, val)
+    else
+      val
+    end
+  end
+
+  # warning, recursion:
+  def env_expand_ary(env, key, val)
+    val.map { |v| env_expand_i(env.dup, key, v) }
+  end
+
   # for long-running processes (sox/play/ecasound filters)
   def dtas_spawn(env, cmd, opts)
     opts = { close_others: true, pgroup: true }.merge!(opts)
diff --git a/test/test_env.rb b/test/test_env.rb
index bd7961d..6b36f32 100644
--- a/test/test_env.rb
+++ b/test/test_env.rb
@@ -52,4 +52,20 @@ class TestEnv < Testcase
     res = env_expand({"PATH"=>"$PATH"}, expand: true)
     assert_equal ENV["PATH"], res["PATH"]
   end
+
+  def test_ary
+    ENV['HELLO'] = 'HIHI'
+    ENV['PAATH'] = '/usr/local/bin:/usr/bin:/bin'
+    env = { 'BLAH' => [ '$HELLO/WORLD', '$PAATH', '$(echo hello world)' ] }
+    res = env_expand(env, expand: true)
+    exp = [ "HIHI/WORLD", ENV['PAATH'], 'hello world' ]
+    assert_equal exp, Shellwords.split(res['BLAH'])
+    env = {
+      'BLAH' => [ '$(echo hello world)' ],
+      'MOAR' => [ '$BLAH', 'OMG HALP SPACES' ]
+    }
+    res = env_expand(env, expand: true)
+    exp = ["hello\\ world", "OMG HALP SPACES"]
+    assert_equal exp, Shellwords.split(res['MOAR'])
+  end
 end
-- 
EW



                 reply	other threads:[~2015-05-18  0:21 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://80x24.org/dtas/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1431908475-15700-1-git-send-email-e@80x24.org \
    --to=e@80x24.org \
    --cc=dtas-all@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/dtas.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).