lib/shell.rb


DEFINITIONS

This source file includes following functions.


   1  #
   2  #   shell.rb - 
   3  #       $Release Version: 0.6.0 $
   4  #       $Revision: 1.8 $
   5  #       $Date: 2001/03/19 09:01:11 $
   6  #       by Keiju ISHITSUKA(Nippon Rational Inc.)
   7  #
   8  # --
   9  #
  10  #   
  11  #
  12  
  13  require "e2mmap"
  14  require "thread"
  15  
  16  require "shell/error"
  17  require "shell/command-processor"
  18  require "shell/process-controller"
  19  
  20  class Shell
  21    @RCS_ID='-$Id: shell.rb,v 1.8 2001/03/19 09:01:11 keiju Exp keiju $-'
  22  
  23    include Error
  24    extend Exception2MessageMapper
  25  
  26  #  @cascade = true
  27    # debug: true -> normal debug
  28    # debug: 1    -> eval definition debug
  29    # debug: 2    -> detail inspect debug
  30    @debug = false
  31    @verbose = true
  32  
  33    class << Shell
  34      attr :cascade, true
  35      attr :debug, true
  36      attr :verbose, true
  37  
  38  #    alias cascade? cascade
  39      alias debug? debug
  40      alias verbose? verbose
  41      @verbose = true
  42  
  43      def debug=(val)
  44        @debug = val
  45        @verbose = val if val
  46      end
  47  
  48      def cd(path)
  49        sh = new
  50        sh.cd path
  51        sh
  52      end
  53  
  54      def default_system_path
  55        if @default_system_path
  56          @default_system_path
  57        else
  58          ENV["PATH"].split(":")
  59        end
  60      end
  61  
  62      def default_system_path=(path)
  63        @default_system_path = path
  64      end
  65  
  66      def default_record_separator
  67        if @default_record_separator
  68          @default_record_separator
  69        else
  70          $/
  71        end
  72      end
  73  
  74      def default_record_separator=(rs)
  75        @default_record_separator = rs
  76      end
  77    end
  78  
  79    def initialize
  80      @cwd = Dir.pwd
  81      @dir_stack = []
  82      @umask = nil
  83  
  84      @system_path = Shell.default_system_path
  85      @record_separator = Shell.default_record_separator
  86  
  87      @command_processor = CommandProcessor.new(self)
  88      @process_controller = ProcessController.new(self)
  89  
  90      @verbose = Shell.verbose
  91      @debug = Shell.debug
  92    end
  93  
  94    attr_reader :system_path
  95  
  96    def system_path=(path)
  97      @system_path = path
  98      rehash
  99    end
 100  
 101    attr :umask, true
 102    attr :record_separator, true
 103  
 104    attr :verbose, true
 105    attr :debug, true
 106  
 107    def debug=(val)
 108      @debug = val
 109      @verbose = val if val
 110    end
 111  
 112    alias verbose? verbose
 113    alias debug? debug
 114  
 115    attr_reader :command_processor
 116    attr_reader :process_controller
 117  
 118    def expand_path(path)
 119      File.expand_path(path, @cwd)
 120    end
 121  
 122    # Most Shell commands are defined via CommandProcessor
 123  
 124    #
 125    # Dir related methods
 126    #
 127    # Shell#cwd/dir/getwd/pwd
 128    # Shell#chdir/cd
 129    # Shell#pushdir/pushd
 130    # Shell#popdir/popd
 131    # Shell#mkdir
 132    # Shell#rmdir
 133  
 134    attr :cwd
 135    alias dir cwd
 136    alias getwd cwd
 137    alias pwd cwd
 138  
 139    attr :dir_stack
 140    alias dirs dir_stack
 141  
 142    # If called as iterator, it restores the current directory when the
 143    # block ends.
 144    def chdir(path = nil)
 145      if iterator?
 146        cwd_old = @cwd
 147        begin
 148          chdir(path)
 149          yield
 150        ensure
 151          chdir(cwd_old)
 152        end
 153      else
 154        path = "~" unless path
 155        @cwd = expand_path(path)
 156        notify "current dir: #{@cwd}"
 157        rehash
 158        self
 159      end
 160    end
 161    alias cd chdir
 162  
 163    def pushdir(path = nil)
 164      if iterator?
 165        pushdir(path)
 166        begin
 167          yield
 168        ensure
 169          popdir
 170        end
 171      elsif path
 172        @dir_stack.push @cwd
 173        chdir path
 174        notify "dir stack: [#{@dir_stack.join ', '}]"
 175        self
 176      else
 177        if pop = @dir_stack.pop
 178          @dir_stack.push @cwd
 179          chdir pop
 180          notify "dir stack: [#{@dir_stack.join ', '}]"
 181          self
 182        else
 183          Shell.Fail DirStackEmpty
 184        end
 185      end
 186    end
 187    alias pushd pushdir
 188  
 189    def popdir
 190      if pop = @dir_stack.pop
 191        chdir pop
 192        notify "dir stack: [#{@dir_stack.join ', '}]"
 193        self
 194      else
 195        Shell.Fail DirStackEmpty
 196      end
 197    end
 198    alias popd popdir
 199  
 200  
 201    #
 202    # process management
 203    #
 204    def jobs
 205      @process_controller.jobs
 206    end
 207  
 208    def kill(sig, command)
 209      @process_controller.kill_job(sig, command)
 210    end
 211  
 212    #
 213    # command definitions
 214    #
 215    def Shell.def_system_command(command, path = command)
 216      CommandProcessor.def_system_command(command, path)
 217    end
 218  
 219    def Shell.undef_system_command(command)
 220      CommandProcessor.undef_system_command(command)
 221    end
 222  
 223    def Shell.alias_command(ali, command, *opts, &block)
 224      CommandProcessor.alias_command(ali, command, *opts, &block)
 225    end
 226  
 227    def Shell.unalias_command(ali)
 228      CommandProcessor.unalias_command(ali)
 229    end
 230  
 231    def Shell.install_system_commands(pre = "sys_")
 232      CommandProcessor.install_system_commands(pre)
 233    end
 234  
 235    #
 236    def inspect
 237      if debug.kind_of?(Integer) && debug > 2
 238        super
 239      else
 240        to_s
 241      end
 242    end
 243  
 244    def self.notify(*opts, &block)
 245      Thread.exclusive do
 246      if opts[-1].kind_of?(String)
 247        yorn = verbose?
 248      else
 249        yorn = opts.pop
 250      end
 251      return unless yorn
 252  
 253      _head = true
 254      print opts.collect{|mes|
 255        mes = mes.dup
 256        yield mes if iterator?
 257        if _head
 258          _head = false
 259          "shell: " + mes
 260        else
 261          "       " + mes
 262        end
 263      }.join("\n")+"\n"
 264      end
 265    end
 266  
 267    CommandProcessor.initialize
 268    CommandProcessor.run_config
 269  end
 270