diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/irb.rb | 317 | ||||
-rw-r--r-- | lib/irb/context.rb | 290 | ||||
-rw-r--r-- | lib/irb/extend-command.rb | 127 | ||||
-rw-r--r-- | lib/irb/help.rb | 33 | ||||
-rw-r--r-- | lib/irb/init.rb | 238 | ||||
-rw-r--r-- | lib/irb/lc/error.rb | 30 | ||||
-rw-r--r-- | lib/irb/lc/help-message | 34 | ||||
-rw-r--r-- | lib/irb/lc/ja/error.rb | 29 | ||||
-rw-r--r-- | lib/irb/lc/ja/help-message | 35 | ||||
-rw-r--r-- | lib/irb/locale.rb | 187 | ||||
-rw-r--r-- | lib/irb/workspace.rb | 106 | ||||
-rw-r--r-- | lib/irb/ws-for-case-2.rb | 15 |
12 files changed, 1441 insertions, 0 deletions
diff --git a/lib/irb.rb b/lib/irb.rb new file mode 100644 index 0000000000..bfeb3f8be7 --- /dev/null +++ b/lib/irb.rb @@ -0,0 +1,317 @@ +# +# irb.rb - irb main module +# $Release Version: 0.7.3 $ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +require "irb/init" +require "irb/context" +require "irb/extend-command" +require "irb/workspace" + +require "irb/ruby-lex" +require "irb/input-method" +require "irb/locale" + +STDOUT.sync = true + +module IRB + @RCS_ID='-$Id$-' + + class Abort < Exception;end + + # + @CONF = {} + + def IRB.conf + @CONF + end + + # IRB version method + def IRB.version + if v = @CONF[:VERSION] then return v end + + require "irb/version" + rv = @RELEASE_VERSION.sub(/\.0/, "") + @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE) + end + + # initialize IRB and start TOP_LEVEL irb + # (JP: IRB$B=i4|2=$H%H%C%W%l%Y%k(Birb$B5/F0(B) + def IRB.start(ap_path = nil) + $0 = File::basename(ap_path, ".rb") if ap_path + + IRB.initialize(ap_path) + IRB.parse_opts + IRB.load_modules + + if @CONF[:SCRIPT] + irb = Irb.new(nil, @CONF[:SCRIPT]) + else + irb = Irb.new + end + + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @CONF[:MAIN_CONTEXT] = irb.context + + trap("SIGINT") do + irb.signal_handle + end + + catch(:IRB_EXIT) do + irb.eval_input + end + print "\n" + end + + def IRB.irb_exit(irb, ret) + throw :IRB_EXIT, ret + end + + def IRB.irb_abort(irb, exception = Abort) + if defined? Thread + irb.context.thread.raise exception, "abort then interrupt!!" + else + raise exception, "abort then interrupt!!" + end + end + + # + # irb interpriter main routine + # (JP: irb$B%$%s%?%W%j%?K\BN(B) + # + class Irb + def initialize(workspace = nil, input_method = nil) + @context = Context.new(self, workspace, input_method) + @context.main.extend ExtendCommand + @signal_status = :IN_IRB + + @scanner = RubyLex.new + @scanner.exception_on_syntax_error = false + end + attr_reader :context + attr_accessor :scanner + + def eval_input + @scanner.set_input(@context.io) do + signal_status(:IN_INPUT) do + unless l = @context.io.gets + if @context.ignore_eof? and @context.io.readable_atfer_eof? + l = "\n" + if @context.verbose? + printf "Use \"exit\" to leave %s\n", @context.ap_name + end + end + end + l + end + end + + @scanner.set_prompt do + |ltype, indent, continue, line_no| + if ltype + f = @context.prompt_s + elsif continue + f = @context.prompt_c + else @context.prompt_i + f = @context.prompt_i + end + f = "" unless f + @context.io.prompt = p = prompt(f, ltype, indent, line_no) + if @context.auto_indent_mode + unless ltype + ind = prompt(@context.prompt_i, ltype, indent, line_no).size + + indent * 2 - p.size + ind += 2 if continue + @context.io.prompt = p + " " * ind if ind > 0 + end + end + end + + @scanner.each_top_level_statement do + |line, line_no| + signal_status(:IN_EVAL) do + begin + trace_in do + @context._ = @context.workspace.evaluate(line, + @context.irb_path, + line_no) +# @context._ = irb_eval(line, @context.bind, @context.irb_path, line_no) + end + + if @context.inspect? + printf @context.return_format, @context._.inspect + else + printf @context.return_format, @context._ + end + rescue StandardError, ScriptError, Abort + $! = RuntimeError.new("unknown exception raised") unless $! + print $!.type, ": ", $!, "\n" + if $@[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && $!.type.to_s !~ /^IRB/ + irb_bug = true + else + irb_bug = false + end + + messages = [] + lasts = [] + levels = 0 + for m in $@ + m = @context.workspace.filter_backtrace(m) unless irb_bug + if m + if messages.size < @context.back_trace_limit + messages.push "\tfrom "+m + else + lasts.push "\tfrom "+m + if lasts.size > @context.back_trace_limit + lasts.shift + levels += 1 + end + end + end + end + print messages.join("\n"), "\n" + unless lasts.empty? + printf "... %d levels...\n", levels if levels > 0 + print lasts.join("\n") + end + print "Maybe IRB bug!!\n" if irb_bug + end + end + end + end + +# def irb_eval(line, bind, path, line_no) +# id, str = catch(:IRB_TOPLEVEL_EVAL){ +# return eval(line, bind, path, line_no) +# } +# case id +# when :EVAL_TOPLEVEL +# eval(str, bind, "(irb_internal)", 1) +# when :EVAL_CONTEXT +# @context.instance_eval(str) +# else +# IRB.fail IllegalParameter +# end +# end + + def signal_handle + unless @context.ignore_sigint? + print "\nabort!!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + @scanner.initialize_input + print @context.io.prompt + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore (JP: $B2?$b$7$J$$(B.) + else + # ignore (JP: $B$=$NB>$N>l9g$b2?$b$7$J$$(B.) + end + end + + def signal_status(status) + return yield if @signal_status == :IN_LOAD + + signal_status_back = @signal_status + @signal_status = status + begin + yield + ensure + @signal_status = signal_status_back + end + end + + def trace_in + Tracer.on if @context.use_tracer? + begin + yield + ensure + Tracer.off if @context.use_tracer? + end + end + + def prompt(prompt, ltype, indent, line_no) + p = prompt.dup + p.gsub!(/%([0-9]+)?([a-zA-Z])/) do + case $2 + when "N" + @context.irb_name + when "m" + @context.main.to_s + when "M" + @context.main.inspect + when "l" + ltype + when "i" + if $1 + format("%" + $1 + "d", indent) + else + indent.to_s + end + when "n" + if $1 + format("%" + $1 + "d", line_no) + else + line_no.to_s + end + when "%" + "%" + end + end + p + end + + def inspect + ary = [] + for iv in instance_variables + case iv + when "@signal_status" + ary.push format("%s=:%s", iv, @signal_status.id2name) + when "@context" + ary.push format("%s=%s", iv, eval(iv).__to_s__) + else + ary.push format("%s=%s", iv, eval(iv)) + end + end + format("#<%s: %s>", type, ary.join(", ")) + end + end + + # Singleton method + def @CONF.inspect + IRB.version unless self[:VERSION] + + array = [] + for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name} + case k + when :MAIN_CONTEXT + next + when :PROMPT + s = v.collect{ + |kk, vv| + ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"} + format(":%s=>{%s}", kk.id2name, ss.join(", ")) + } + array.push format("CONF[:%s]={%s}", k.id2name, s.join(", ")) + else + array.push format("CONF[:%s]=%s", k.id2name, v.inspect) + end + end + array.join("\n") + end +end diff --git a/lib/irb/context.rb b/lib/irb/context.rb new file mode 100644 index 0000000000..8fa9de63ad --- /dev/null +++ b/lib/irb/context.rb @@ -0,0 +1,290 @@ +# +# irb/context.rb - irb context +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + class Context + # + # Arguments: + # input_method: nil -- stdin or readline + # String -- File + # other -- using this as InputMethod + # + def initialize(irb, workspace = nil, input_method = nil) + @irb = irb + if workspace + @workspace = workspace + else + @workspace = WorkSpace.new unless workspace + end + @thread = Thread.current if defined? Thread + @irb_level = 0 + + # copy of default configuration + # (JP: $B%G%U%)%k%H%3%s%U%#%.%e%l!<%7%g%s$N%3%T!<(B) + @ap_name = IRB.conf[:AP_NAME] + @rc = IRB.conf[:RC] + @load_modules = IRB.conf[:LOAD_MODULES] + + self.math_mode = IRB.conf[:MATH_MODE] + @use_readline = IRB.conf[:USE_READLINE] + @inspect_mode = IRB.conf[:INSPECT_MODE] + self.use_tracer = IRB.conf[:USE_TRACER] +# @use_loader = IRB.conf[:USE_LOADER] + + self.prompt_mode = IRB.conf[:PROMPT_MODE] + + @ignore_sigint = IRB.conf[:IGNORE_SIGINT] + @ignore_eof = IRB.conf[:IGNORE_EOF] + + @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] + + debug_level = IRB.conf[:DEBUG_LEVEL] + @verbose = IRB.conf[:VERBOSE] + + @tracer_initialized = false + + if IRB.conf[:SINGLE_IRB] or !defined?(JobManager) + @irb_name = IRB.conf[:IRB_NAME] + else + @irb_name = "irb#"+IRB.JobManager.n_jobs.to_s + end + @irb_path = "(" + @irb_name + ")" + + case input_method + when nil + if (use_readline.nil? && IRB.conf[:PROMPT_MODE] != :INF_RUBY || + use_readline?) + @io = ReadlineInputMethod.new + else + @io = StdioInputMethod.new + end + when String + @io = FileInputMethod.new(input_method) + @irb_name = File.basename(input_method) + @irb_path = input_method + else + @io = input_method + end + end + + def main + @workspace.main + end + + attr_accessor :workspace + attr_reader :thread + attr_accessor :io + + attr_reader :_ + + attr_accessor :irb + attr_accessor :ap_name + attr_accessor :rc + attr_accessor :load_modules + attr_accessor :irb_name + attr_accessor :irb_path + + attr_accessor :math_mode + attr_accessor :use_readline + attr_reader :inspect_mode + attr_reader :use_tracer +# attr :use_loader + + attr_reader :debug_level + attr_accessor :verbose + + attr_reader :prompt_mode + attr_accessor :prompt_i + attr_accessor :prompt_s + attr_accessor :prompt_c + attr_accessor :auto_indent_mode + attr_accessor :return_format + + attr_accessor :ignore_sigint + attr_accessor :ignore_eof + + attr_accessor :back_trace_limit + +# alias use_loader? use_loader + alias use_tracer? use_tracer + alias use_readline? use_readline + alias rc? rc + alias math? math_mode + alias verbose? verbose + alias ignore_sigint? ignore_sigint + alias ignore_eof? ignore_eof + + def _=(value) + @_ = value + @workspace.evaluate "_ = IRB.conf[:MAIN_CONTEXT]._" + end + + def irb_name + if @irb_level == 0 + @irb_name + elsif @irb_name =~ /#[0-9]*$/ + @irb_name + "." + @irb_level.to_s + else + @irb_name + "#0." + @irb_level.to_s + end + end + + def prompt_mode=(mode) + @prompt_mode = mode + pconf = IRB.conf[:PROMPT][mode] + @prompt_i = pconf[:PROMPT_I] + @prompt_s = pconf[:PROMPT_S] + @prompt_c = pconf[:PROMPT_C] + @return_format = pconf[:RETURN] + if ai = pconf.include?(:AUTO_INDENT) + @auto_indent_mode = ai + else + @auto_indent_mode = IRB.conf[:AUTO_INDENT] + end + end + + def inspect? + @inspect_mode.nil? && !@math_mode or @inspect_mode + end + + def file_input? + @io.type == FileInputMethod + end + + def use_tracer=(opt) + if opt + IRB.initialize_tracer + unless @tracer_initialized + Tracer.set_get_line_procs(@irb_path) { + |line_no| + @io.line(line_no) + } + @tracer_initialized = true + end + elsif !opt && @use_tracer + Tracer.off + end + @use_tracer=opt + end + + def use_loader + IRB.conf[:USE_LOADER] + end + + def use_loader=(opt) + IRB.conf[:USE_LOADER] = opt + if opt + IRB.initialize_loader + end + print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose? + opt + end + + def inspect_mode=(opt) + if opt + @inspect_mode = opt + else + @inspect_mode = !@inspect_mode + end + print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? + @inspect_mode + end + + def math_mode=(opt) + if @math_mode == true && opt == false + IRB.fail CantRetuenNormalMode + return + end + + @math_mode = opt + if math_mode + IRB.initialize_mathn + main.instance_eval("include Math") + print "start math mode\n" if verbose? + end + end + + def use_readline=(opt) + @use_readline = opt + print "use readline module\n" if @use_readline + end + + def debug_level=(value) + @debug_level = value + RubyLex.debug_level = value + SLex.debug_level = value + end + + def debug? + @debug_level > 0 + end + + def change_binding(*_main) + back = @workspace + @workspace = WorkSpace.new(*_main) + unless _main.empty? + begin + main.extend ExtendCommand + rescue + print "can't change binding to: ", main.inspect, "\n" + @workspace = back + return nil + end + end + @irb_level += 1 + begin + catch(:SU_EXIT) do + @irb.eval_input + end + ensure + @irb_level -= 1 + @workspace = back + end + end + alias change_workspace change_binding + + + alias __exit__ exit + def exit(ret = 0) + if @irb_level == 0 + IRB.irb_exit(@irb, ret) + else + throw :SU_EXIT, ret + end + end + + NOPRINTING_IVARS = ["@_"] + NO_INSPECTING_IVARS = ["@irb", "@io"] + IDNAME_IVARS = ["@prompt_mode"] + + alias __inspect__ inspect + def inspect + array = [] + for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} + name = ivar.sub(/^@(.*)$/){$1} + val = instance_eval(ivar) + case ivar + when *NOPRINTING_IVARS + next + when *NO_INSPECTING_IVARS + array.push format("conf.%s=%s", name, val.to_s) + when *IDNAME_IVARS + array.push format("conf.%s=:%s", name, val.id2name) + else + array.push format("conf.%s=%s", name, val.inspect) + end + end + array.join("\n") + end + alias __to_s__ to_s + alias to_s inspect + end +end diff --git a/lib/irb/extend-command.rb b/lib/irb/extend-command.rb new file mode 100644 index 0000000000..bc657520a7 --- /dev/null +++ b/lib/irb/extend-command.rb @@ -0,0 +1,127 @@ +# +# irb/extend-command.rb - irb command extend +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + # + # IRB extended command + # (JP: IRB$B3HD%%3%^%s%I(B) + # + module ExtendCommand +# include Loader + + def irb_exit(ret = 0) + irb_context.exit(ret) + end + alias irb_quit irb_exit + + def irb_fork(&block) + pid = send ExtendCommand.irb_original_method_name("fork") + unless pid + class<<self + alias_method :exit, ExtendCommand.irb_original_method_name('exit') + end + if iterator? + begin + yield + ensure + exit + end + end + end + pid + end + + def irb_change_binding(*main) + irb_context.change_binding(*main) + end + alias irb_change_workspace irb_change_binding + + def irb_source(file) + irb_context.source(file) + end + + def irb(*obj) + require "irb/multi-irb" + IRB.irb(nil, *obj) + end + + def irb_context + IRB.conf[:MAIN_CONTEXT] + end + + def irb_jobs + require "irb/multi-irb" + IRB.JobManager + end + + def irb_fg(key) + require "irb/multi-irb" + IRB.JobManager.switch(key) + end + + def irb_kill(*keys) + require "irb/multi-irb" + IRB.JobManager.kill(*keys) + end + + # extend command functions + def ExtendCommand.extend_object(obj) + super + unless (class<<obj;ancestors;end).include?(ExtendCommand) + obj.install_aliases + end + end + + OVERRIDE_NOTHING = 0 + OVERRIDE_PRIVATE_ONLY = 0x01 + OVERRIDE_ALL = 0x02 + + def install_aliases(override = OVERRIDE_NOTHING) + + install_alias_method(:exit, :irb_exit, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:quit, :irb_quit, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:fork, :irb_fork, override | OVERRIDE_PRIVATE_ONLY) + install_alias_method(:kill, :irb_kill, override | OVERRIDE_PRIVATE_ONLY) + + install_alias_method(:irb_cb, :irb_change_binding, override) + install_alias_method(:irb_ws, :irb_change_workspace, override) + install_alias_method(:source, :irb_source, override) + install_alias_method(:conf, :irb_context, override) + install_alias_method(:jobs, :irb_jobs, override) + install_alias_method(:fg, :irb_fg, override) + end + + # override = {OVERRIDE_NOTHING, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL} + def install_alias_method(to, from, override = OVERRIDE_NOTHING) + to = to.id2name unless to.kind_of?(String) + from = from.id2name unless from.kind_of?(String) + + if override == OVERRIDE_ALL or + (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or + (override == OVERRIDE_NOTHING) && !respond_to?(to, true) + target = self + (class<<self;self;end).instance_eval{ + if target.respond_to?(to, true) && + !target.respond_to?(ExtendCommand.irb_original_method_name(to), true) + alias_method(ExtendCommand.irb_original_method_name(to), to) + end + alias_method to, from + } + else + print "irb: warn: can't alias #{to} from #{from}.\n" + end + end + + def self.irb_original_method_name(method_name) + "irb_" + method_name + "_org" + end + end +end diff --git a/lib/irb/help.rb b/lib/irb/help.rb new file mode 100644 index 0000000000..0821f68d13 --- /dev/null +++ b/lib/irb/help.rb @@ -0,0 +1,33 @@ +# +# irb/help.rb - print usase module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + def IRB.print_usage + lc = IRB.conf[:LC_MESSAGES] + path = lc.find("irb/help-message") + space_line = false + File.foreach(path) do + |l| + if /^\s*$/ =~ l + lc.puts l unless space_line + space_line = true + next + end + space_line = false + + l.sub!(/#.*$/, "") + next if /^\s*$/ =~ l + lc.puts l + end + end +end + diff --git a/lib/irb/init.rb b/lib/irb/init.rb new file mode 100644 index 0000000000..abfd9cdc22 --- /dev/null +++ b/lib/irb/init.rb @@ -0,0 +1,238 @@ +# +# irb/init.rb - irb initialize module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + + # initialize config + # (JP: config$B$N=i4|2=(B) + def IRB.initialize(ap_path) + IRB.init_config(ap_path) + IRB.init_error + IRB.run_config + end + + # @CONF default setting + def IRB.init_config(ap_path) + # class instance variables + @TRACER_INITIALIZED = false + @MATHN_INITIALIZED = false + + # default configurations + # (JP: $B%G%U%)%k%H%3%s%U%#%.%e%l!<%7%g%s(B) + unless ap_path and @CONF[:AP_NAME] + ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") + end + @CONF[:AP_NAME] = File::basename(ap_path, ".rb") + + @CONF[:IRB_NAME] = "irb" + @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) + + @CONF[:RC] = true + @CONF[:LOAD_MODULES] = [] + @CONF[:IRB_RC] = nil + + @CONF[:MATH_MODE] = false + @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod) + @CONF[:INSPECT_MODE] = nil + @CONF[:USE_TRACER] = false + @CONF[:USE_LOADER] = false + @CONF[:IGNORE_SIGINT] = true + @CONF[:IGNORE_EOF] = false + + @CONF[:BACK_TRACE_LIMIT] = 16 + + @CONF[:PROMPT] = { + :NULL => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n" + }, + :DEFAULT => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" + }, + :SIMPLE => { + :PROMPT_I => ">> ", + :PROMPT_S => nil, + :PROMPT_C => "?> ", + :RETURN => "=> %s\n" + }, + :INF_RUBY => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n", + :AUTO_INDENT => true + }, + :XMP => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => " ==>%s\n" + } + } + + @CONF[:PROMPT_MODE] = :DEFAULT + @CONF[:AUTO_INDENT] = false + + @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING + @CONF[:SINGLE_IRB] = false + +# @CONF[:LC_MESSAGES] = "en" + @CONF[:LC_MESSAGES] = Locale.new + + @CONF[:DEBUG_LEVEL] = 1 + @CONF[:VERBOSE] = true + end + + def IRB.init_error + @CONF[:LC_MESSAGES].load("irb/error.rb") + end + + # option analyzing + # (JP: $B%*%W%7%g%s2r@O(B) + def IRB.parse_opts + while opt = ARGV.shift + case opt + when "-f" + opt = ARGV.shift + @CONF[:RC] = false + when "-m" + @CONF[:MATH_MODE] = true + when "-d" + $DEBUG = true + when "-r" + opt = ARGV.shift + @CONF[:LOAD_MODULES].push opt if opt + when "--inspect" + @CONF[:INSPECT_MODE] = true + when "--noinspect" + @CONF[:INSPECT_MODE] = false + when "--readline" + @CONF[:USE_READLINE] = true + when "--noreadline" + @CONF[:USE_READLINE] = false + + when "--prompt-mode", "--prompt" + prompt_mode = ARGV.shift.upcase.tr("-", "_").intern + IRB.fail(UndefinedPromptMode, + prompt_mode.id2name) unless @CONF[:PROMPT][prompt_mode] + @CONF[:PROMPT_MODE] = prompt_mode + when "--noprompt" + @CONF[:PROMPT_MODE] = :NULL + when "--inf-ruby-mode" + @CONF[:PROMPT_MODE] = :INF_RUBY + when "--sample-book-mode", "--simple-prompt" + @CONF[:PROMPT_MODE] = :SIMPLE + + when "--tracer" + @CONF[:USE_TRACER] = true + when "--back-trace-limit" + @CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i + when "--context-mode" + @CONF[:CONTEXT_MODE] = ARGV.shift.to_i + when "--single-irb" + @CONF[:SINGLE_IRB] = true + when "--irb_debug" + @CONF[:DEBUG_LEVEL] = ARGV.shift.to_i + when "-v", "--version" + print IRB.version, "\n" + exit 0 + when "-h", "--help" + require "irb/help" + IRB.print_usage + exit 0 + when /^-/ + IRB.fail UnrecognizedSwitch, opt + else + @CONF[:USE_READLINE] = false + @CONF[:SCRIPT] = opt + $0 = opt + break + end + end + end + + # running config + def IRB.run_config + if @CONF[:RC] + rcs = [] + rcs.push File.expand_path("~/.irbrc") if ENV.key?("HOME") + rcs.push ".irbrc" + rcs.push "irb.rc" + rcs.push "_irbrc" + rcs.push "$irbrc" + catch(:EXIT) do + for rc in rcs + begin + load rc + throw :EXIT + rescue LoadError, Errno::ENOENT + rescue + print "load error: #{rc}\n" + print $!.type, ": ", $!, "\n" + for err in $@[0, $@.size - 2] + print "\t", err, "\n" + end + throw :EXIT + end + end + end + end + end + + # loading modules + def IRB.load_modules + for m in @CONF[:LOAD_MODULES] + begin + require m + rescue + print $@[0], ":", $!.type, ": ", $!, "\n" + end + end + end + + # initialize tracing function + # (JP: $B%H%l!<%5=i4|@_Dj(B) + def IRB.initialize_tracer + unless @TRACER_INITIALIZED + require("tracer") + Tracer.verbose = false + Tracer.add_filter { + |event, file, line, id, binding| + File::dirname(file) != @CONF[:IRB_LIB_PATH] + } + @TRACER_INITIALIZED = true + end + end + + # initialize mathn function + # (JP: mathn$B=i4|@_Dj(B) + def IRB.initialize_mathn + unless @MATHN_INITIALIZED + require "mathn" + @MATHN_INITIALIZED = true + end + end + + # initialize loader function + # (JP: loader$B=i4|@_Dj(B) + def IRB.initialize_loader + unless @LOADER_INITIALIZED + require "irb/loader" + @LOADER_INITIALIZED = true + end + end +end diff --git a/lib/irb/lc/error.rb b/lib/irb/lc/error.rb new file mode 100644 index 0000000000..15f3cab83c --- /dev/null +++ b/lib/irb/lc/error.rb @@ -0,0 +1,30 @@ +# +# irb/lc/error.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +module IRB + + # exceptions (JP: $BNc30Dj5A(B) + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" + def_exception :NotImplementError, "Need to define `%s'" + def_exception :CantRetuenNormalMode, "Can't return normal mode." + def_exception :IllegalParameter, "Illegal parameter(%s)." + def_exception :IrbAlreadyDead, "Irb is already dead." + def_exception :IrbSwitchToCurrentThread, "Change to current thread." + def_exception :NoSuchJob, "No such job(%s)." + def_exception :CanNotGoMultiIrbMode, "Can't go multi irb mode." + def_exception :CanNotChangeBinding, "Can't change binding to (%s)." + def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)." + +end + diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message new file mode 100644 index 0000000000..8a3d63803b --- /dev/null +++ b/lib/irb/lc/help-message @@ -0,0 +1,34 @@ +# +# irb/lc/help-message.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f suppress read ~/.irbrc + -m bc mode (load mathn, fraction or matrix are available) + -d set $DEBUG to true (same as `ruby -d') + -r load-module same as `ruby -r' + --inspect uses `inspect' for output (the default except bc mode) + --noinspect doesn't uses inspect for output + --readline uses Readline extension module + --noreadline doesn't use Readline extension module + --prompt prompt-mode + --prompt-mode prompt-mode + switches prompt mode. Pre-defined prompt modes are + `defalut', `simple', `xmp' and `inf-ruby' + --inf-ruby-mode uses prompt appreciate for inf-ruby-mode on emacs. + Suppresses --readline. + --simple-prompt simple prompt mode + --noprompt no prompt + --tracer display trace for each execution of commands. + --back-trace-limit n + displayes backtrace top n and tail n. The default + value is 16. + --irb_debug n sets internal debug level to n (It shouldn't be used) + -v, --version prints the version of irb diff --git a/lib/irb/lc/ja/error.rb b/lib/irb/lc/ja/error.rb new file mode 100644 index 0000000000..1fa3ae328d --- /dev/null +++ b/lib/irb/lc/ja/error.rb @@ -0,0 +1,29 @@ +# +# irb/lc/ja/error.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +require "e2mmap" + +module IRB + # exceptions (JP: $BNc30Dj5A(B) + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, '$B%9%$%C%A(B(%s)$B$,J,$j$^$;$s(B' + def_exception :NotImplementError, '`%s\'$B$NDj5A$,I,MW$G$9(B' + def_exception :CantRetuenNormalMode, 'Normal$B%b!<%I$KLa$l$^$;$s(B.' + def_exception :IllegalParameter, '$B%Q%i%a!<%?(B(%s)$B$,4V0c$C$F$$$^$9(B.' + def_exception :IrbAlreadyDead, 'Irb$B$O4{$K;`$s$G$$$^$9(B.' + def_exception :IrbSwitchToCurrentThread, 'Change to current thread.' + def_exception :NoSuchJob, '$B$=$N$h$&$J%8%g%V(B(%s)$B$O$"$j$^$;$s(B.' + def_exception :CanNotGoMultiIrbMode, 'multi-irb mode$B$K0\$l$^$;$s(B.' + def_exception :CanNotChangeBinding, '$B%P%$%s%G%#%s%0(B(%s)$B$KJQ99$G$-$^$;$s(B.' + def_exception :UndefinedPromptMode, '$B%W%m%s%W%H%b!<%I(B(%s)$B$ODj5A$5$l$F$$$^$;$s(B.' +end + + diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message new file mode 100644 index 0000000000..59f5c7a72b --- /dev/null +++ b/lib/irb/lc/ja/help-message @@ -0,0 +1,35 @@ +# +# irb/lc/ja/help-message.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f ~/.irbrc $B$rFI$_9~$^$J$$(B. + -m bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$k(B) + -d $DEBUG $B$r(Btrue$B$K$9$k(B(ruby -d $B$HF1$8(B) + -r load-module ruby -r $B$HF1$8(B. + --inspect $B7k2L=PNO$K(Binspect$B$rMQ$$$k(B(bc$B%b!<%I0J30$O%G%U%)%k%H(B). + --noinspect $B7k2L=PNO$K(Binspect$B$rMQ$$$J$$(B. + --readline readline$B%i%$%V%i%j$rMxMQ$9$k(B. + --noreadline readline$B%i%$%V%i%j$rMxMQ$7$J$$(B. + --prompt prompt-mode/--prompt-mode prompt-mode + $B%W%m%s%W%H%b!<%I$r@ZBX$($^$9(B. $B8=:_Dj5A$5$l$F$$$k%W(B + $B%m%s%W%H%b!<%I$O(B, defalut, simple, xmp, inf-ruby$B$,(B + $BMQ0U$5$l$F$$$^$9(B. + --inf-ruby-mode emacs$B$N(Binf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $BFC(B + $B$K;XDj$,$J$$8B$j(B, readline$B%i%$%V%i%j$O;H$o$J$/$J$k(B. + --simple-prompt $BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9(B. + --noprompt $B%W%m%s%W%HI=<($r9T$J$o$J$$(B. + --tracer $B%3%^%s%I<B9T;~$K%H%l!<%9$r9T$J$&(B. + --back-trace-limit n + $B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i(B n, $B8e$m(B + $B$+$i(Bn$B$@$19T$J$&(B. $B%G%U%)%k%H$O(B16 + --irb_debug n irb$B$N%G%P%C%0%G%P%C%0%l%Y%k$r(Bn$B$K@_Dj$9$k(B($BMxMQ$7$J(B + $B$$J}$,L5Fq$G$7$g$&(B). + -v, --version irb$B$N%P!<%8%g%s$rI=<($9$k(B diff --git a/lib/irb/locale.rb b/lib/irb/locale.rb new file mode 100644 index 0000000000..ef92ea1377 --- /dev/null +++ b/lib/irb/locale.rb @@ -0,0 +1,187 @@ +# +# irb/locale.rb - internationalization module +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +require "kconv" + +module IRB + class Locale + @RCS_ID='-$Id$-' + + JPDefaultLocale = "ja" + LOCALE_DIR = "/lc/" + + LC2KCONV = { +# "ja" => Kconv::JIS, +# "ja_JP" => Kconv::JIS, + "ja_JP.ujis" => Kconv::EUC, + "ja_JP.euc" => Kconv::EUC, + "ja_JP.eucJP" => Kconv::EUC, + "ja_JP.sjis" => Kconv::SJIS, + "ja_JP.SJIS" => Kconv::SJIS, + } + + def initialize(locale = nil) + @lang = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] + @lang = "C" unless @lang + end + + attr_reader :lang + + def String(mes) + mes = super(mes) + case @lang + when /^ja/ + mes = Kconv::kconv(mes, LC2KCONV[@lang]) + else + mes + end + mes + end + + def format(*opts) + String(super(*opts)) + end + + def gets(*rs) + String(super(*rs)) + end + + def readline(*rs) + String(super(*rs)) + end + + def print(*opts) + ary = opts.collect{|opt| String(opt)} + super *ary + end + + def printf(*opts) + s = format(*opts) + print s + end + + def puts(*opts) + ary = opts.collect{|opt| String(opts)} + super *ary + end + + autoload :Tempfile, "tempfile" + + def require(file, priv = nil) + rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?") + return false if $".find{|f| f =~ rex} + + case file + when /\.rb$/ + begin + load(file, priv) + $".push file + return true + rescue LoadError + end + when /\.(so|o|sl)$/ + return super + end + + begin + load(f = file + ".rb") + $".push f #" + return true + rescue LoadError + return ruby_require(file) + end + end + + alias toplevel_load load + + def load(file, priv=nil) + dir = File.dirname(file) + dir = "" if dir == "." + base = File.basename(file) + + if /^ja(_JP)?$/ =~ @lang + back, @lang = @lang, "C" + end + begin + if dir[0] == ?/ #/ + lc_path = search_file(dir, base) + return real_load(lc_path, priv) if lc_path + end + + for path in $: + lc_path = search_file(path + "/" + dir, base) + return real_load(lc_path, priv) if lc_path + end + ensure + @lang = back if back + end + raise LoadError, "No such file to load -- #{file}" + end + + def real_load(path, priv) + tmp_base = path.tr("./:", "___") + lc_file = Tempfile.new(tmp_base) + File.foreach(path) do |line| + line = self.String(line) + lc_file.print(line) + end + lc_file.close + toplevel_load lc_file.path, priv + end + private :real_load + + def find(file , paths = $:) + dir = File.dirname(file) + dir = "" if dir == "." + base = File.basename(file) + if dir[0] == ?/ #/ + return lc_path = search_file(dir, base) + else + for path in $: + if lc_path = search_file(path + "/" + dir, base) + return lc_path + end + end + end + nil + end + + def search_file(path, file) + if File.exists?(p1 = path + lc_path(file, "C")) + if File.exists?(p2 = path + lc_path(file)) + return p2 + else + end + return p1 + else + end + nil + end + private :search_file + + def lc_path(file = "", lc = @lang) + case lc + when "C" + LOCALE_DIR + file + when /^ja/ + LOCALE_DIR + "ja/" + file + else + LOCALE_DIR + @lang + "/" + file + end + end + private :lc_path + end +end + + + + diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb new file mode 100644 index 0000000000..3550a758d0 --- /dev/null +++ b/lib/irb/workspace.rb @@ -0,0 +1,106 @@ +# +# irb/workspace-binding.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# +module IRB + class WorkSpace + # create new workspace. + # (JP: $B?7$?$J(Bworkspace$B$r:n$k(B. main$B$r(Bself$B$H$9$k(B. $B>JN,$7$?$i(B, + # TOPLEVEL_BINDING$B$N(Bmain$B$r$=$N$^$^;H$&(B. ) + def initialize(*main) + if IRB.conf[:SINGLE_IRB] + @binding = TOPLEVEL_BINDING + else + case IRB.conf[:CONTEXT_MODE] + when 0 # binding in proc on TOPLEVEL_BINDING + @binding = eval("proc{binding}.call", + TOPLEVEL_BINDING, + __FILE__, + __LINE__) + when 1 # binding in loaded file + require "tempfile" + f = Tempfile.open("irb-binding") + f.print <<EOF + $binding = binding +EOF + f.close + load f.path + @binding = $binding + + when 2 # binding in loaded file(thread use) + unless defined? BINDING_QUEUE + require "thread" + + IRB.const_set("BINDING_QUEUE", SizedQueue.new(1)) + Thread.abort_on_exception = true + Thread.start do + eval "require \"irb/ws-for-case-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__ + end + Thread.pass + end + @binding = BINDING_QUEUE.pop + + when 3 # binging in function on TOPLEVEL_BINDING(default) + @binding = eval("def irb_binding; binding; end; irb_binding", + TOPLEVEL_BINDING, + __FILE__, + __LINE__ - 3) + end + end + if main.empty? + @main = eval "self", @binding + else + @main = main[0] + IRB.conf[:__MAIN__] = @main + case @main + when Module + @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__) + else + begin + @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__) + rescue TypeError + IRB.fail CanNotChangeBinding, @main.inspect + end + end + end + eval("_=nil", @binding) + end + + attr_reader :binding + attr_reader :main + + def evaluate(statements, file = __FILE__, line = __LINE__) + eval statements, @binding, file, line + end + + # error message manupilator + def filter_backtrace(bt) + case IRB.conf[:CONTEXT_MODE] + when 0 + return nil if bt =~ /\(irb_local_binding\)/ + when 1 + if(bt =~ %r!/tmp/irb-binding! or + bt =~ %r!irb/.*\.rb! or + bt =~ /irb\.rb/) + return nil + end + when 2 + return nil if bt =~ /irb\/.*\.rb/ + when 3 + return nil if bt =~ /irb\/.*\.rb/ + bt.sub!(/:\s*in `irb_binding'/){""} + end + bt + end + + def IRB.delete_caller + end + end +end diff --git a/lib/irb/ws-for-case-2.rb b/lib/irb/ws-for-case-2.rb new file mode 100644 index 0000000000..8cfa87ae3d --- /dev/null +++ b/lib/irb/ws-for-case-2.rb @@ -0,0 +1,15 @@ +# +# irb/ws-for-case-2.rb - +# $Release Version: 0.7.3$ +# $Revision$ +# $Date$ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +while true + IRB::BINDING_QUEUE.push b = binding +end |