class SFL
Constants
- REDIRECTION_MAPPING
- SHELL_SPECIALS
- VERSION
Attributes
argument[R]
command[R]
environment[R]
option[R]
Public Class Methods
eval_ast(ast)
click to toggle source
# File lib/sfl.rb, line 136 def eval_ast(ast) case ast when Array if ast.size > 2 eval_ast(ast[0]).send(ast[1], *ast[2..-1].map {|i| eval_ast(i) }) else eval_ast(ast[0]).send(ast[1]) end else ast end end
new(*cmdandarg)
click to toggle source
SFL.new
('ls', '-a') becomes
@environment = {} @command = ['ls', 'ls'] @argument = ['-a'] @option = {}
# File lib/sfl.rb, line 13 def initialize(*cmdandarg) raise ArgumentError if cmdandarg.size == 0 cmdandarg = cmdandarg.dup @environment = if Hash === cmdandarg.first cmdandarg.shift else {} end @option = if Hash === cmdandarg.last cmdandarg.pop else {} end if cmdandarg.size == 1 cmdandarg = cmdandarg.first if String === cmdandarg if SHELL_SPECIALS === cmdandarg @command = cmdandarg @argument = [] else cmd, *arg = self.class.parse_command_with_arg(cmdandarg) @command = [cmd, cmd] @argument = arg end else @command = cmdandarg @argument = [] end else # 'ls', '.' -> [['ls', 'ls'], '.'] cmd = cmdandarg.shift cmd = (String === cmd) ? [cmd, cmd] : cmd @command = cmd @argument = cmdandarg end end
option_parser(hash)
click to toggle source
# File lib/sfl.rb, line 98 def option_parser(hash) result = [] # changing dir has high priority chdir = hash.delete(:chdir) if chdir result[0] = [Dir, :chdir, chdir] end # other options result += hash.map {|k, v| case k when :in, :out, :err if right = redirection_ast(v, k) [[REDIRECTION_MAPPING[k], :reopen, right]] else [[REDIRECTION_MAPPING[k], :close]] end when Array # assuming k is like [:out, :err] raise NotImplementedError if k.size > 2 left1, left2 = *k.map {|i| REDIRECTION_MAPPING[i] } if right = redirection_ast(v) [ [left1, :reopen, right], [left2, :reopen, left1], ] else [ [left1, :close], [left2, :close], ] end end }.flatten(1) result end
parse_command_with_arg(x)
click to toggle source
# File lib/sfl.rb, line 149 def parse_command_with_arg(x) in_squote = false in_dquote = false tmp = '' cmdargs = [] x.strip.split(//).each do |c| case c when '"' if in_dquote in_dquote = false else in_dquote = true end when "'" if in_squote in_squote = false else in_squote = true end when ' ' if in_dquote || in_squote tmp << ' ' else cmdargs << tmp tmp = '' end else tmp << c end end cmdargs << tmp end
redirection_ast(v, what_for = :out)
click to toggle source
# File lib/sfl.rb, line 81 def redirection_ast(v, what_for = :out) case v when Integer raise NotImplementedError, "Redirection to integer FD not yet implemented" when :close nil when :in, :out, :err REDIRECTION_MAPPING[v] when String # filename [File, :open, v, (what_for == :in ? 'r' : 'w')] when Array # filename with option [File, :open, v[0], v[1]] when IO v end end
Public Instance Methods
==(o)
click to toggle source
# File lib/sfl.rb, line 67 def ==(o) # Mostly for rspec instance_variables.all? do |i| i = i[1..-1] # '@a' -> 'a' eval "self.#{i} == o.#{i}" end end
run()
click to toggle source
# File lib/sfl.rb, line 55 def run fork { @environment.each do |k, v| ENV[k] = v end self.class.option_parser(@option).each do |ast| self.class.eval_ast ast end exec(@command, *@argument) } end