summaryrefslogtreecommitdiff
path: root/jni/ruby/lib/irb
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/lib/irb')
-rw-r--r--jni/ruby/lib/irb/cmd/chws.rb33
-rw-r--r--jni/ruby/lib/irb/cmd/fork.rb38
-rw-r--r--jni/ruby/lib/irb/cmd/help.rb41
-rw-r--r--jni/ruby/lib/irb/cmd/load.rb66
-rw-r--r--jni/ruby/lib/irb/cmd/nop.rb38
-rw-r--r--jni/ruby/lib/irb/cmd/pushws.rb40
-rw-r--r--jni/ruby/lib/irb/cmd/subirb.rb42
-rw-r--r--jni/ruby/lib/irb/completion.rb227
-rw-r--r--jni/ruby/lib/irb/context.rb419
-rw-r--r--jni/ruby/lib/irb/ext/change-ws.rb45
-rw-r--r--jni/ruby/lib/irb/ext/history.rb118
-rw-r--r--jni/ruby/lib/irb/ext/loader.rb128
-rw-r--r--jni/ruby/lib/irb/ext/math-mode.rb47
-rw-r--r--jni/ruby/lib/irb/ext/multi-irb.rb265
-rw-r--r--jni/ruby/lib/irb/ext/save-history.rb103
-rw-r--r--jni/ruby/lib/irb/ext/tracer.rb71
-rw-r--r--jni/ruby/lib/irb/ext/use-loader.rb73
-rw-r--r--jni/ruby/lib/irb/ext/workspaces.rb66
-rw-r--r--jni/ruby/lib/irb/extend-command.rb308
-rw-r--r--jni/ruby/lib/irb/frame.rb80
-rw-r--r--jni/ruby/lib/irb/help.rb36
-rw-r--r--jni/ruby/lib/irb/init.rb304
-rw-r--r--jni/ruby/lib/irb/input-method.rb191
-rw-r--r--jni/ruby/lib/irb/inspector.rb131
-rw-r--r--jni/ruby/lib/irb/lc/.document4
-rw-r--r--jni/ruby/lib/irb/lc/error.rb31
-rw-r--r--jni/ruby/lib/irb/lc/help-message50
-rw-r--r--jni/ruby/lib/irb/lc/ja/encoding_aliases.rb10
-rw-r--r--jni/ruby/lib/irb/lc/ja/error.rb30
-rw-r--r--jni/ruby/lib/irb/lc/ja/help-message53
-rw-r--r--jni/ruby/lib/irb/locale.rb181
-rw-r--r--jni/ruby/lib/irb/magic-file.rb37
-rw-r--r--jni/ruby/lib/irb/notifier.rb231
-rw-r--r--jni/ruby/lib/irb/output-method.rb91
-rw-r--r--jni/ruby/lib/irb/ruby-lex.rb1170
-rw-r--r--jni/ruby/lib/irb/ruby-token.rb266
-rw-r--r--jni/ruby/lib/irb/slex.rb281
-rw-r--r--jni/ruby/lib/irb/src_encoding.rb4
-rw-r--r--jni/ruby/lib/irb/version.rb15
-rw-r--r--jni/ruby/lib/irb/workspace.rb114
-rw-r--r--jni/ruby/lib/irb/ws-for-case-2.rb14
-rw-r--r--jni/ruby/lib/irb/xmp.rb169
42 files changed, 5661 insertions, 0 deletions
diff --git a/jni/ruby/lib/irb/cmd/chws.rb b/jni/ruby/lib/irb/cmd/chws.rb
new file mode 100644
index 0000000..bc39fd1
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/chws.rb
@@ -0,0 +1,33 @@
+#
+# change-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "irb/cmd/nop.rb"
+require "irb/ext/change-ws.rb"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+
+ class CurrentWorkingWorkspace<Nop
+ def execute(*obj)
+ irb_context.main
+ end
+ end
+
+ class ChangeWorkspace<Nop
+ def execute(*obj)
+ irb_context.change_workspace(*obj)
+ irb_context.main
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/cmd/fork.rb b/jni/ruby/lib/irb/cmd/fork.rb
new file mode 100644
index 0000000..4e80250
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/fork.rb
@@ -0,0 +1,38 @@
+#
+# fork.rb -
+# $Release Version: 0.9.6 $
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Fork<Nop
+ def execute
+ 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
+ end
+ end
+end
+# :startdoc:
+
+
diff --git a/jni/ruby/lib/irb/cmd/help.rb b/jni/ruby/lib/irb/cmd/help.rb
new file mode 100644
index 0000000..028cc35
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/help.rb
@@ -0,0 +1,41 @@
+#
+# help.rb - helper using ri
+# $Release Version: 0.9.6$
+# $Revision: 38358 $
+#
+# --
+#
+#
+#
+
+require 'rdoc/ri/driver'
+
+require "irb/cmd/nop.rb"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Help<Nop
+ begin
+ Ri = RDoc::RI::Driver.new
+ rescue SystemExit
+ else
+ def execute(*names)
+ if names.empty?
+ Ri.interactive
+ return
+ end
+ names.each do |name|
+ begin
+ Ri.display_name(name.to_s)
+ rescue RDoc::RI::Error
+ puts $!.message
+ end
+ end
+ nil
+ end
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/cmd/load.rb b/jni/ruby/lib/irb/cmd/load.rb
new file mode 100644
index 0000000..a3b1604
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/load.rb
@@ -0,0 +1,66 @@
+#
+# load.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47114 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "irb/cmd/nop.rb"
+require "irb/ext/loader"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Load<Nop
+ include IrbLoader
+
+ def execute(file_name, priv = nil)
+ return irb_load(file_name, priv)
+ end
+ end
+
+ class Require<Nop
+ include IrbLoader
+
+ def execute(file_name)
+
+ rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
+ return false if $".find{|f| f =~ rex}
+
+ case file_name
+ when /\.rb$/
+ begin
+ if irb_load(file_name)
+ $".push file_name
+ return true
+ end
+ rescue LoadError
+ end
+ when /\.(so|o|sl)$/
+ return ruby_require(file_name)
+ end
+
+ begin
+ irb_load(f = file_name + ".rb")
+ $".push f
+ return true
+ rescue LoadError
+ return ruby_require(file_name)
+ end
+ end
+ end
+
+ class Source<Nop
+ include IrbLoader
+ def execute(file_name)
+ source_file(file_name)
+ end
+ end
+ end
+
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/cmd/nop.rb b/jni/ruby/lib/irb/cmd/nop.rb
new file mode 100644
index 0000000..3445d79
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/nop.rb
@@ -0,0 +1,38 @@
+#
+# nop.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Nop
+
+
+ def self.execute(conf, *opts)
+ command = new(conf)
+ command.execute(*opts)
+ end
+
+ def initialize(conf)
+ @irb_context = conf
+ end
+
+ attr_reader :irb_context
+
+ def irb
+ @irb_context.irb
+ end
+
+ def execute(*opts)
+ #nop
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/cmd/pushws.rb b/jni/ruby/lib/irb/cmd/pushws.rb
new file mode 100644
index 0000000..1bda950
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/pushws.rb
@@ -0,0 +1,40 @@
+#
+# change-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "irb/cmd/nop.rb"
+require "irb/ext/workspaces.rb"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class Workspaces<Nop
+ def execute(*obj)
+ irb_context.workspaces.collect{|ws| ws.main}
+ end
+ end
+
+ class PushWorkspace<Workspaces
+ def execute(*obj)
+ irb_context.push_workspace(*obj)
+ super
+ end
+ end
+
+ class PopWorkspace<Workspaces
+ def execute(*obj)
+ irb_context.pop_workspace(*obj)
+ super
+ end
+ end
+ end
+end
+# :startdoc:
+
diff --git a/jni/ruby/lib/irb/cmd/subirb.rb b/jni/ruby/lib/irb/cmd/subirb.rb
new file mode 100644
index 0000000..342828f
--- /dev/null
+++ b/jni/ruby/lib/irb/cmd/subirb.rb
@@ -0,0 +1,42 @@
+# multi.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "irb/cmd/nop.rb"
+require "irb/ext/multi-irb"
+
+# :stopdoc:
+module IRB
+ module ExtendCommand
+ class IrbCommand<Nop
+ def execute(*obj)
+ IRB.irb(nil, *obj)
+ end
+ end
+
+ class Jobs<Nop
+ def execute
+ IRB.JobManager
+ end
+ end
+
+ class Foreground<Nop
+ def execute(key)
+ IRB.JobManager.switch(key)
+ end
+ end
+
+ class Kill<Nop
+ def execute(*keys)
+ IRB.JobManager.kill(*keys)
+ end
+ end
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/completion.rb b/jni/ruby/lib/irb/completion.rb
new file mode 100644
index 0000000..6ede82b
--- /dev/null
+++ b/jni/ruby/lib/irb/completion.rb
@@ -0,0 +1,227 @@
+#
+# irb/completor.rb -
+# $Release Version: 0.9$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ishitsuka.com)
+# From Original Idea of shugo@ruby-lang.org
+#
+
+require "readline"
+
+module IRB
+ module InputCompletor # :nodoc:
+
+
+ # Set of reserved words used by Ruby, you should not use these for
+ # constants or variables
+ ReservedWords = %w[
+ BEGIN END
+ alias and
+ begin break
+ case class
+ def defined do
+ else elsif end ensure
+ false for
+ if in
+ module
+ next nil not
+ or
+ redo rescue retry return
+ self super
+ then true
+ undef unless until
+ when while
+ yield
+ ]
+
+ CompletionProc = proc { |input|
+ bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
+
+ case input
+ when /^((["'`]).*\2)\.([^.]*)$/
+ # String
+ receiver = $1
+ message = Regexp.quote($3)
+
+ candidates = String.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates)
+
+ when /^(\/[^\/]*\/)\.([^.]*)$/
+ # Regexp
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Regexp.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates)
+
+ when /^([^\]]*\])\.([^.]*)$/
+ # Array
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Array.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates)
+
+ when /^([^\}]*\})\.([^.]*)$/
+ # Proc or Hash
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Proc.instance_methods.collect{|m| m.to_s}
+ candidates |= Hash.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates)
+
+ when /^(:[^:.]*)$/
+ # Symbol
+ if Symbol.respond_to?(:all_symbols)
+ sym = $1
+ candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
+ candidates.grep(/^#{Regexp.quote(sym)}/)
+ else
+ []
+ end
+
+ when /^::([A-Z][^:\.\(]*)$/
+ # Absolute Constant or class methods
+ receiver = $1
+ candidates = Object.constants.collect{|m| m.to_s}
+ candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
+
+ when /^([A-Z].*)::([^:.]*)$/
+ # Constant or class methods
+ receiver = $1
+ message = Regexp.quote($2)
+ begin
+ candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
+ candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
+ rescue Exception
+ candidates = []
+ end
+ select_message(receiver, message, candidates, "::")
+
+ when /^(:[^:.]+)(\.|::)([^.]*)$/
+ # Symbol
+ receiver = $1
+ sep = $2
+ message = Regexp.quote($3)
+
+ candidates = Symbol.instance_methods.collect{|m| m.to_s}
+ select_message(receiver, message, candidates, sep)
+
+ when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/
+ # Numeric
+ receiver = $1
+ sep = $5
+ message = Regexp.quote($6)
+
+ begin
+ candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
+ rescue Exception
+ candidates = []
+ end
+ select_message(receiver, message, candidates, sep)
+
+ when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
+ # Numeric(0xFFFF)
+ receiver = $1
+ sep = $2
+ message = Regexp.quote($3)
+
+ begin
+ candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
+ rescue Exception
+ candidates = []
+ end
+ select_message(receiver, message, candidates, sep)
+
+ when /^(\$[^.]*)$/
+ # global var
+ regmessage = Regexp.new(Regexp.quote($1))
+ candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
+
+ when /^([^."].*)(\.|::)([^.]*)$/
+ # variable.func or func.func
+ receiver = $1
+ sep = $2
+ message = Regexp.quote($3)
+
+ gv = eval("global_variables", bind).collect{|m| m.to_s}
+ lv = eval("local_variables", bind).collect{|m| m.to_s}
+ iv = eval("instance_variables", bind).collect{|m| m.to_s}
+ cv = eval("self.class.constants", bind).collect{|m| m.to_s}
+
+ if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
+ # foo.func and foo is var. OR
+ # foo::func and foo is var. OR
+ # foo::Const and foo is var. OR
+ # Foo::Bar.func
+ begin
+ candidates = []
+ rec = eval(receiver, bind)
+ if sep == "::" and rec.kind_of?(Module)
+ candidates = rec.constants.collect{|m| m.to_s}
+ end
+ candidates |= rec.methods.collect{|m| m.to_s}
+ rescue Exception
+ candidates = []
+ end
+ else
+ # func1.func2
+ candidates = []
+ ObjectSpace.each_object(Module){|m|
+ begin
+ name = m.name
+ rescue Exception
+ name = ""
+ end
+ begin
+ next if name != "IRB::Context" and
+ /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
+ rescue Exception
+ next
+ end
+ candidates.concat m.instance_methods(false).collect{|x| x.to_s}
+ }
+ candidates.sort!
+ candidates.uniq!
+ end
+ select_message(receiver, message, candidates, sep)
+
+ when /^\.([^.]*)$/
+ # unknown(maybe String)
+
+ receiver = ""
+ message = Regexp.quote($1)
+
+ candidates = String.instance_methods(true).collect{|m| m.to_s}
+ select_message(receiver, message, candidates)
+
+ else
+ candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s}
+
+ (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
+ end
+ }
+
+ # Set of available operators in Ruby
+ Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
+
+ def self.select_message(receiver, message, candidates, sep = ".")
+ candidates.grep(/^#{message}/).collect do |e|
+ case e
+ when /^[a-zA-Z_]/
+ receiver + sep + e
+ when /^[0-9]/
+ when *Operators
+ #receiver + " " + e
+ end
+ end
+ end
+ end
+end
+
+if Readline.respond_to?("basic_word_break_characters=")
+ Readline.basic_word_break_characters= " \t\n`><=;|&{("
+end
+Readline.completion_append_character = nil
+Readline.completion_proc = IRB::InputCompletor::CompletionProc
diff --git a/jni/ruby/lib/irb/context.rb b/jni/ruby/lib/irb/context.rb
new file mode 100644
index 0000000..0006186
--- /dev/null
+++ b/jni/ruby/lib/irb/context.rb
@@ -0,0 +1,419 @@
+#
+# irb/context.rb - irb context
+# $Release Version: 0.9.6$
+# $Revision: 47114 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require "irb/workspace"
+require "irb/inspector"
+
+module IRB
+ # A class that wraps the current state of the irb session, including the
+ # configuration of IRB.conf.
+ class Context
+ # Creates a new IRB context.
+ #
+ # The optional +input_method+ argument:
+ #
+ # +nil+:: uses stdin or Readline
+ # +String+:: uses a File
+ # +other+:: uses this as InputMethod
+ def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
+ @irb = irb
+ if workspace
+ @workspace = workspace
+ else
+ @workspace = WorkSpace.new
+ end
+ @thread = Thread.current if defined? Thread
+
+ # copy of default configuration
+ @ap_name = IRB.conf[:AP_NAME]
+ @rc = IRB.conf[:RC]
+ @load_modules = IRB.conf[:LOAD_MODULES]
+
+ @use_readline = IRB.conf[:USE_READLINE]
+ @verbose = IRB.conf[:VERBOSE]
+ @io = nil
+
+ self.inspect_mode = IRB.conf[:INSPECT_MODE]
+ self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE]
+ self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
+ self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
+ self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]
+
+ @ignore_sigint = IRB.conf[:IGNORE_SIGINT]
+ @ignore_eof = IRB.conf[:IGNORE_EOF]
+
+ @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]
+
+ self.prompt_mode = IRB.conf[:PROMPT_MODE]
+
+ if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager)
+ @irb_name = IRB.conf[:IRB_NAME]
+ else
+ @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
+ end
+ @irb_path = "(" + @irb_name + ")"
+
+ case input_method
+ when nil
+ case use_readline?
+ when nil
+ if (defined?(ReadlineInputMethod) && STDIN.tty? &&
+ IRB.conf[:PROMPT_MODE] != :INF_RUBY)
+ @io = ReadlineInputMethod.new
+ else
+ @io = StdioInputMethod.new
+ end
+ when false
+ @io = StdioInputMethod.new
+ when true
+ if defined?(ReadlineInputMethod)
+ @io = ReadlineInputMethod.new
+ else
+ @io = StdioInputMethod.new
+ end
+ end
+
+ when String
+ @io = FileInputMethod.new(input_method)
+ @irb_name = File.basename(input_method)
+ @irb_path = input_method
+ else
+ @io = input_method
+ end
+ self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
+
+ if output_method
+ @output_method = output_method
+ else
+ @output_method = StdioOutputMethod.new
+ end
+
+ @echo = IRB.conf[:ECHO]
+ if @echo.nil?
+ @echo = true
+ end
+ self.debug_level = IRB.conf[:DEBUG_LEVEL]
+ end
+
+ # The top-level workspace, see WorkSpace#main
+ def main
+ @workspace.main
+ end
+
+ # The toplevel workspace, see #home_workspace
+ attr_reader :workspace_home
+ # WorkSpace in the current context
+ attr_accessor :workspace
+ # The current thread in this context
+ attr_reader :thread
+ # The current input method
+ #
+ # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or
+ # other specified when the context is created. See ::new for more
+ # information on +input_method+.
+ attr_accessor :io
+
+ # Current irb session
+ attr_accessor :irb
+ # A copy of the default <code>IRB.conf[:AP_NAME]</code>
+ attr_accessor :ap_name
+ # A copy of the default <code>IRB.conf[:RC]</code>
+ attr_accessor :rc
+ # A copy of the default <code>IRB.conf[:LOAD_MODULES]</code>
+ attr_accessor :load_modules
+ # Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of
+ # the current job set by JobManager, such as <code>irb#2</code>
+ attr_accessor :irb_name
+ # Can be either the #irb_name surrounded by parenthesis, or the
+ # +input_method+ passed to Context.new
+ attr_accessor :irb_path
+
+ # Whether +Readline+ is enabled or not.
+ #
+ # A copy of the default <code>IRB.conf[:USE_READLINE]</code>
+ #
+ # See #use_readline= for more information.
+ attr_reader :use_readline
+ # A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
+ attr_reader :inspect_mode
+
+ # A copy of the default <code>IRB.conf[:PROMPT_MODE]</code>
+ attr_reader :prompt_mode
+ # Standard IRB prompt
+ #
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ attr_accessor :prompt_i
+ # IRB prompt for continuated strings
+ #
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ attr_accessor :prompt_s
+ # IRB prompt for continuated statement (e.g. immediately after an +if+)
+ #
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ attr_accessor :prompt_c
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ attr_accessor :prompt_n
+ # Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the
+ # mode set by #prompt_mode=
+ #
+ # To enable auto-indentation in irb:
+ #
+ # IRB.conf[:AUTO_INDENT] = true
+ #
+ # or
+ #
+ # irb_context.auto_indent_mode = true
+ #
+ # or
+ #
+ # IRB.CurrentContext.auto_indent_mode = true
+ #
+ # See IRB@Configuration for more information.
+ attr_accessor :auto_indent_mode
+ # The format of the return statement, set by #prompt_mode= using the
+ # +:RETURN+ of the +mode+ passed to set the current #prompt_mode.
+ attr_accessor :return_format
+
+ # Whether <code>^C</code> (+control-c+) will be ignored or not.
+ #
+ # If set to +false+, <code>^C</code> will quit irb.
+ #
+ # If set to +true+,
+ #
+ # * during input: cancel input then return to top level.
+ # * during execute: abandon current execution.
+ attr_accessor :ignore_sigint
+ # Whether <code>^D</code> (+control-d+) will be ignored or not.
+ #
+ # If set to +false+, <code>^D</code> will quit irb.
+ attr_accessor :ignore_eof
+ # Whether to echo the return value to output or not.
+ #
+ # Uses IRB.conf[:ECHO] if available, or defaults to +true+.
+ #
+ # puts "hello"
+ # # hello
+ # #=> nil
+ # IRB.CurrentContext.echo = false
+ # puts "omg"
+ # # omg
+ attr_accessor :echo
+ # Whether verbose messages are displayed or not.
+ #
+ # A copy of the default <code>IRB.conf[:VERBOSE]</code>
+ attr_accessor :verbose
+ # The debug level of irb
+ #
+ # See #debug_level= for more information.
+ attr_reader :debug_level
+
+ # The limit of backtrace lines displayed as top +n+ and tail +n+.
+ #
+ # The default value is 16.
+ #
+ # Can also be set using the +--back-trace-limit+ command line option.
+ #
+ # See IRB@Command+line+options for more command line options.
+ attr_accessor :back_trace_limit
+
+ # Alias for #use_readline
+ alias use_readline? use_readline
+ # Alias for #rc
+ alias rc? rc
+ alias ignore_sigint? ignore_sigint
+ alias ignore_eof? ignore_eof
+ alias echo? echo
+
+ # Returns whether messages are displayed or not.
+ def verbose?
+ if @verbose.nil?
+ if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
+ false
+ elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
+ true
+ else
+ false
+ end
+ else
+ @verbose
+ end
+ end
+
+ # Whether #verbose? is +true+, and +input_method+ is either
+ # StdioInputMethod or ReadlineInputMethod, see #io for more information.
+ def prompting?
+ verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
+ (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
+ end
+
+ # The return value of the last statement evaluated.
+ attr_reader :last_value
+
+ # Sets the return value from the last statement evaluated in this context
+ # to #last_value.
+ def set_last_value(value)
+ @last_value = value
+ @workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
+ end
+
+ # Sets the +mode+ of the prompt in this context.
+ #
+ # See IRB@Customizing+the+IRB+Prompt for more information.
+ 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]
+ @prompt_n = pconf[:PROMPT_N]
+ @return_format = pconf[:RETURN]
+ if ai = pconf.include?(:AUTO_INDENT)
+ @auto_indent_mode = ai
+ else
+ @auto_indent_mode = IRB.conf[:AUTO_INDENT]
+ end
+ end
+
+ # Whether #inspect_mode is set or not, see #inspect_mode= for more detail.
+ def inspect?
+ @inspect_mode.nil? or @inspect_mode
+ end
+
+ # Whether #io uses a File for the +input_method+ passed when creating the
+ # current context, see ::new
+ def file_input?
+ @io.class == FileInputMethod
+ end
+
+ # Specifies the inspect mode with +opt+:
+ #
+ # +true+:: display +inspect+
+ # +false+:: display +to_s+
+ # +nil+:: inspect mode in non-math mode,
+ # non-inspect mode in math mode
+ #
+ # See IRB::Inspector for more information.
+ #
+ # Can also be set using the +--inspect+ and +--noinspect+ command line
+ # options.
+ #
+ # See IRB@Command+line+options for more command line options.
+ def inspect_mode=(opt)
+
+ if i = Inspector::INSPECTORS[opt]
+ @inspect_mode = opt
+ @inspect_method = i
+ i.init
+ else
+ case opt
+ when nil
+ if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode)
+ self.inspect_mode = false
+ elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode)
+ self.inspect_mode = true
+ else
+ puts "Can't switch inspect mode."
+ return
+ end
+ when /^\s*\{.*\}\s*$/
+ begin
+ inspector = eval "proc#{opt}"
+ rescue Exception
+ puts "Can't switch inspect mode(#{opt})."
+ return
+ end
+ self.inspect_mode = inspector
+ when Proc
+ self.inspect_mode = IRB::Inspector(opt)
+ when Inspector
+ prefix = "usr%d"
+ i = 1
+ while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end
+ @inspect_mode = format(prefix, i)
+ @inspect_method = opt
+ Inspector.def_inspector(format(prefix, i), @inspect_method)
+ else
+ puts "Can't switch inspect mode(#{opt})."
+ return
+ end
+ end
+ print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose?
+ @inspect_mode
+ end
+
+ # Obsolete method.
+ #
+ # Can be set using the +--noreadline+ and +--readline+ command line
+ # options.
+ #
+ # See IRB@Command+line+options for more command line options.
+ def use_readline=(opt)
+ print "This method is obsolete."
+ print "Do nothing."
+ end
+
+ # Sets the debug level of irb
+ #
+ # Can also be set using the +--irb_debug+ command line option.
+ #
+ # See IRB@Command+line+options for more command line options.
+ def debug_level=(value)
+ @debug_level = value
+ RubyLex.debug_level = value
+ end
+
+ # Whether or not debug mode is enabled, see #debug_level=.
+ def debug?
+ @debug_level > 0
+ end
+
+ def evaluate(line, line_no) # :nodoc:
+ @line_no = line_no
+ set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
+ end
+
+ def inspect_last_value # :nodoc:
+ @inspect_method.inspect_value(@last_value)
+ end
+
+ alias __exit__ exit
+ # Exits the current session, see IRB.irb_exit
+ def exit(ret = 0)
+ IRB.irb_exit(@irb, ret)
+ end
+
+ NOPRINTING_IVARS = ["@last_value"] # :nodoc:
+ NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc:
+ IDNAME_IVARS = ["@prompt_mode"] # :nodoc:
+
+ alias __inspect__ inspect
+ def inspect # :nodoc:
+ array = []
+ for ivar in instance_variables.sort{|e1, e2| e1 <=> e2}
+ ivar = ivar.to_s
+ name = ivar.sub(/^@(.*)$/, '\1')
+ val = instance_eval(ivar)
+ case ivar
+ when *NOPRINTING_IVARS
+ array.push format("conf.%s=%s", name, "...")
+ 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/jni/ruby/lib/irb/ext/change-ws.rb b/jni/ruby/lib/irb/ext/change-ws.rb
new file mode 100644
index 0000000..866a710
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/change-ws.rb
@@ -0,0 +1,45 @@
+#
+# irb/ext/cb.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47114 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+ class Context
+
+ # Inherited from +TOPLEVEL_BINDING+.
+ def home_workspace
+ if defined? @home_workspace
+ @home_workspace
+ else
+ @home_workspace = @workspace
+ end
+ end
+
+ # Changes the current workspace to given object or binding.
+ #
+ # If the optional argument is omitted, the workspace will be
+ # #home_workspace which is inherited from +TOPLEVEL_BINDING+ or the main
+ # object, <code>IRB.conf[:MAIN_CONTEXT]</code> when irb was initialized.
+ #
+ # See IRB::WorkSpace.new for more information.
+ def change_workspace(*_main)
+ if _main.empty?
+ @workspace = home_workspace
+ return main
+ end
+
+ @workspace = WorkSpace.new(_main[0])
+
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
+ main.extend ExtendCommandBundle
+ end
+ end
+ end
+end
+
diff --git a/jni/ruby/lib/irb/ext/history.rb b/jni/ruby/lib/irb/ext/history.rb
new file mode 100644
index 0000000..f21795e
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/history.rb
@@ -0,0 +1,118 @@
+#
+# history.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+
+ class Context
+
+ NOPRINTING_IVARS.push "@eval_history_values"
+
+ # See #set_last_value
+ alias _set_last_value set_last_value
+
+ def set_last_value(value)
+ _set_last_value(value)
+
+ if @eval_history
+ @eval_history_values.push @line_no, @last_value
+ @workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
+ end
+
+ @last_value
+ end
+
+ # The command result history limit.
+ attr_reader :eval_history
+ # Sets command result history limit.
+ #
+ # +no+ is an Integer or +nil+.
+ #
+ # Returns +no+ of history items if greater than 0.
+ #
+ # If +no+ is 0, the number of history items is unlimited.
+ #
+ # If +no+ is +nil+, execution result history isn't used (default).
+ def eval_history=(no)
+ if no
+ if defined?(@eval_history) && @eval_history
+ @eval_history_values.size(no)
+ else
+ @eval_history_values = History.new(no)
+ IRB.conf[:__TMP__EHV__] = @eval_history_values
+ @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
+ IRB.conf.delete(:__TMP_EHV__)
+ end
+ else
+ @eval_history_values = nil
+ end
+ @eval_history = no
+ end
+ end
+
+ class History # :nodoc:
+
+ def initialize(size = 16)
+ @size = size
+ @contents = []
+ end
+
+ def size(size)
+ if size != 0 && size < @size
+ @contents = @contents[@size - size .. @size]
+ end
+ @size = size
+ end
+
+ def [](idx)
+ begin
+ if idx >= 0
+ @contents.find{|no, val| no == idx}[1]
+ else
+ @contents[idx][1]
+ end
+ rescue NameError
+ nil
+ end
+ end
+
+ def push(no, val)
+ @contents.push [no, val]
+ @contents.shift if @size != 0 && @contents.size > @size
+ end
+
+ alias real_inspect inspect
+
+ def inspect
+ if @contents.empty?
+ return real_inspect
+ end
+
+ unless (last = @contents.pop)[1].equal?(self)
+ @contents.push last
+ last = nil
+ end
+ str = @contents.collect{|no, val|
+ if val.equal?(self)
+ "#{no} ...self-history..."
+ else
+ "#{no} #{val.inspect}"
+ end
+ }.join("\n")
+ if str == ""
+ str = "Empty."
+ end
+ @contents.push last if last
+ str
+ end
+ end
+end
+
+
diff --git a/jni/ruby/lib/irb/ext/loader.rb b/jni/ruby/lib/irb/ext/loader.rb
new file mode 100644
index 0000000..4c6b2ba
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/loader.rb
@@ -0,0 +1,128 @@
+#
+# loader.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+
+module IRB # :nodoc:
+ # Raised in the event of an exception in a file loaded from an Irb session
+ class LoadAbort < Exception;end
+
+ # Provides a few commands for loading files within an irb session.
+ #
+ # See ExtendCommandBundle for more information.
+ module IrbLoader
+
+ alias ruby_load load
+ alias ruby_require require
+
+ # Loads the given file similarly to Kernel#load
+ def irb_load(fn, priv = nil)
+ path = search_file_from_ruby_path(fn)
+ raise LoadError, "No such file to load -- #{fn}" unless path
+
+ load_file(path, priv)
+ end
+
+ def search_file_from_ruby_path(fn) # :nodoc:
+ if /^#{Regexp.quote(File::Separator)}/ =~ fn
+ return fn if File.exist?(fn)
+ return nil
+ end
+
+ for path in $:
+ if File.exist?(f = File.join(path, fn))
+ return f
+ end
+ end
+ return nil
+ end
+
+ # Loads a given file in the current session and displays the source lines
+ #
+ # See Irb#suspend_input_method for more information.
+ def source_file(path)
+ irb.suspend_name(path, File.basename(path)) do
+ irb.suspend_input_method(FileInputMethod.new(path)) do
+ |back_io|
+ irb.signal_status(:IN_LOAD) do
+ if back_io.kind_of?(FileInputMethod)
+ irb.eval_input
+ else
+ begin
+ irb.eval_input
+ rescue LoadAbort
+ print "load abort!!\n"
+ end
+ end
+ end
+ end
+ end
+ end
+
+ # Loads the given file in the current session's context and evaluates it.
+ #
+ # See Irb#suspend_input_method for more information.
+ def load_file(path, priv = nil)
+ irb.suspend_name(path, File.basename(path)) do
+
+ if priv
+ ws = WorkSpace.new(Module.new)
+ else
+ ws = WorkSpace.new
+ end
+ irb.suspend_workspace(ws) do
+ irb.suspend_input_method(FileInputMethod.new(path)) do
+ |back_io|
+ irb.signal_status(:IN_LOAD) do
+ if back_io.kind_of?(FileInputMethod)
+ irb.eval_input
+ else
+ begin
+ irb.eval_input
+ rescue LoadAbort
+ print "load abort!!\n"
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def old # :nodoc:
+ back_io = @io
+ back_path = @irb_path
+ back_name = @irb_name
+ back_scanner = @irb.scanner
+ begin
+ @io = FileInputMethod.new(path)
+ @irb_name = File.basename(path)
+ @irb_path = path
+ @irb.signal_status(:IN_LOAD) do
+ if back_io.kind_of?(FileInputMethod)
+ @irb.eval_input
+ else
+ begin
+ @irb.eval_input
+ rescue LoadAbort
+ print "load abort!!\n"
+ end
+ end
+ end
+ ensure
+ @io = back_io
+ @irb_name = back_name
+ @irb_path = back_path
+ @irb.scanner = back_scanner
+ end
+ end
+ end
+end
+
diff --git a/jni/ruby/lib/irb/ext/math-mode.rb b/jni/ruby/lib/irb/ext/math-mode.rb
new file mode 100644
index 0000000..33e9968
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/math-mode.rb
@@ -0,0 +1,47 @@
+#
+# math-mode.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require "mathn"
+
+module IRB
+ class Context
+ # Returns whether bc mode is enabled.
+ #
+ # See #math_mode=
+ attr_reader :math_mode
+ # Alias for #math_mode
+ alias math? math_mode
+
+ # Sets bc mode, which loads +lib/mathn.rb+ so fractions or matrix are
+ # available.
+ #
+ # Also available as the +-m+ command line option.
+ #
+ # See IRB@Command+line+options and the unix manpage <code>bc(1)</code> for
+ # more information.
+ def math_mode=(opt)
+ if @math_mode == true && !opt
+ IRB.fail CantReturnToNormalMode
+ return
+ end
+
+ @math_mode = opt
+ if math_mode
+ main.extend Math
+ print "start math mode\n" if verbose?
+ end
+ end
+
+ def inspect?
+ @inspect_mode.nil? && !@math_mode or @inspect_mode
+ end
+ end
+end
+
diff --git a/jni/ruby/lib/irb/ext/multi-irb.rb b/jni/ruby/lib/irb/ext/multi-irb.rb
new file mode 100644
index 0000000..294f4e2
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/multi-irb.rb
@@ -0,0 +1,265 @@
+#
+# irb/multi-irb.rb - multiple irb module
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+IRB.fail CantShiftToMultiIrbMode unless defined?(Thread)
+require "thread"
+
+module IRB
+ class JobManager
+
+ # Creates a new JobManager object
+ def initialize
+ @jobs = []
+ @current_job = nil
+ end
+
+ # The active irb session
+ attr_accessor :current_job
+
+ # The total number of irb sessions, used to set +irb_name+ of the current
+ # Context.
+ def n_jobs
+ @jobs.size
+ end
+
+ # Returns the thread for the given +key+ object, see #search for more
+ # information.
+ def thread(key)
+ th, = search(key)
+ th
+ end
+
+ # Returns the irb session for the given +key+ object, see #search for more
+ # information.
+ def irb(key)
+ _, irb = search(key)
+ irb
+ end
+
+ # Returns the top level thread.
+ def main_thread
+ @jobs[0][0]
+ end
+
+ # Returns the top level irb session.
+ def main_irb
+ @jobs[0][1]
+ end
+
+ # Add the given +irb+ session to the jobs Array.
+ def insert(irb)
+ @jobs.push [Thread.current, irb]
+ end
+
+ # Changes the current active irb session to the given +key+ in the jobs
+ # Array.
+ #
+ # Raises an IrbAlreadyDead exception if the given +key+ is no longer alive.
+ #
+ # If the given irb session is already active, an IrbSwitchedToCurrentThread
+ # exception is raised.
+ def switch(key)
+ th, irb = search(key)
+ IRB.fail IrbAlreadyDead unless th.alive?
+ IRB.fail IrbSwitchedToCurrentThread if th == Thread.current
+ @current_job = irb
+ th.run
+ Thread.stop
+ @current_job = irb(Thread.current)
+ end
+
+ # Terminates the irb sessions specified by the given +keys+.
+ #
+ # Raises an IrbAlreadyDead exception if one of the given +keys+ is already
+ # terminated.
+ #
+ # See Thread#exit for more information.
+ def kill(*keys)
+ for key in keys
+ th, _ = search(key)
+ IRB.fail IrbAlreadyDead unless th.alive?
+ th.exit
+ end
+ end
+
+ # Returns the associated job for the given +key+.
+ #
+ # If given an Integer, it will return the +key+ index for the jobs Array.
+ #
+ # When an instance of Irb is given, it will return the irb session
+ # associated with +key+.
+ #
+ # If given an instance of Thread, it will return the associated thread
+ # +key+ using Object#=== on the jobs Array.
+ #
+ # Otherwise returns the irb session with the same top-level binding as the
+ # given +key+.
+ #
+ # Raises a NoSuchJob exception if no job can be found with the given +key+.
+ def search(key)
+ job = case key
+ when Integer
+ @jobs[key]
+ when Irb
+ @jobs.find{|k, v| v.equal?(key)}
+ when Thread
+ @jobs.assoc(key)
+ else
+ @jobs.find{|k, v| v.context.main.equal?(key)}
+ end
+ IRB.fail NoSuchJob, key if job.nil?
+ job
+ end
+
+ # Deletes the job at the given +key+.
+ def delete(key)
+ case key
+ when Integer
+ IRB.fail NoSuchJob, key unless @jobs[key]
+ @jobs[key] = nil
+ else
+ catch(:EXISTS) do
+ @jobs.each_index do
+ |i|
+ if @jobs[i] and (@jobs[i][0] == key ||
+ @jobs[i][1] == key ||
+ @jobs[i][1].context.main.equal?(key))
+ @jobs[i] = nil
+ throw :EXISTS
+ end
+ end
+ IRB.fail NoSuchJob, key
+ end
+ end
+ until assoc = @jobs.pop; end unless @jobs.empty?
+ @jobs.push assoc
+ end
+
+ # Outputs a list of jobs, see the irb command +irb_jobs+, or +jobs+.
+ def inspect
+ ary = []
+ @jobs.each_index do
+ |i|
+ th, irb = @jobs[i]
+ next if th.nil?
+
+ if th.alive?
+ if th.stop?
+ t_status = "stop"
+ else
+ t_status = "running"
+ end
+ else
+ t_status = "exited"
+ end
+ ary.push format("#%d->%s on %s (%s: %s)",
+ i,
+ irb.context.irb_name,
+ irb.context.main,
+ th,
+ t_status)
+ end
+ ary.join("\n")
+ end
+ end
+
+ @JobManager = JobManager.new
+
+ # The current JobManager in the session
+ def IRB.JobManager
+ @JobManager
+ end
+
+ # The current Context in this session
+ def IRB.CurrentContext
+ IRB.JobManager.irb(Thread.current).context
+ end
+
+ # Creates a new IRB session, see Irb.new.
+ #
+ # The optional +file+ argument is given to Context.new, along with the
+ # workspace created with the remaining arguments, see WorkSpace.new
+ def IRB.irb(file = nil, *main)
+ workspace = WorkSpace.new(*main)
+ parent_thread = Thread.current
+ Thread.start do
+ begin
+ irb = Irb.new(workspace, file)
+ rescue
+ print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
+ print "return to main irb\n"
+ Thread.pass
+ Thread.main.wakeup
+ Thread.exit
+ end
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
+ @JobManager.insert(irb)
+ @JobManager.current_job = irb
+ begin
+ system_exit = false
+ catch(:IRB_EXIT) do
+ irb.eval_input
+ end
+ rescue SystemExit
+ system_exit = true
+ raise
+ #fail
+ ensure
+ unless system_exit
+ @JobManager.delete(irb)
+ if @JobManager.current_job == irb
+ if parent_thread.alive?
+ @JobManager.current_job = @JobManager.irb(parent_thread)
+ parent_thread.run
+ else
+ @JobManager.current_job = @JobManager.main_irb
+ @JobManager.main_thread.run
+ end
+ end
+ end
+ end
+ end
+ Thread.stop
+ @JobManager.current_job = @JobManager.irb(Thread.current)
+ end
+
+ @CONF[:SINGLE_IRB_MODE] = false
+ @JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
+ @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb
+
+ class Irb
+ def signal_handle
+ unless @context.ignore_sigint?
+ print "\nabort!!\n" if @context.verbose?
+ exit
+ end
+
+ case @signal_status
+ when :IN_INPUT
+ print "^C\n"
+ IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
+ when :IN_EVAL
+ IRB.irb_abort(self)
+ when :IN_LOAD
+ IRB.irb_abort(self, LoadAbort)
+ when :IN_IRB
+ # ignore
+ else
+ # ignore other cases as well
+ end
+ end
+ end
+
+ trap("SIGINT") do
+ @JobManager.current_job.signal_handle
+ Thread.stop
+ end
+
+end
diff --git a/jni/ruby/lib/irb/ext/save-history.rb b/jni/ruby/lib/irb/ext/save-history.rb
new file mode 100644
index 0000000..575b276
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/save-history.rb
@@ -0,0 +1,103 @@
+# save-history.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "readline"
+
+module IRB
+ module HistorySavingAbility # :nodoc:
+ end
+
+ class Context
+ def init_save_history# :nodoc:
+ unless (class<<@io;self;end).include?(HistorySavingAbility)
+ @io.extend(HistorySavingAbility)
+ end
+ end
+
+ # A copy of the default <code>IRB.conf[:SAVE_HISTORY]</code>
+ def save_history
+ IRB.conf[:SAVE_HISTORY]
+ end
+
+ # Sets <code>IRB.conf[:SAVE_HISTORY]</code> to the given +val+ and calls
+ # #init_save_history with this context.
+ #
+ # Will store the number of +val+ entries of history in the #history_file
+ #
+ # Add the following to your +.irbrc+ to change the number of history
+ # entries stored to 1000:
+ #
+ # IRB.conf[:SAVE_HISTORY] = 1000
+ def save_history=(val)
+ IRB.conf[:SAVE_HISTORY] = val
+ if val
+ main_context = IRB.conf[:MAIN_CONTEXT]
+ main_context = self unless main_context
+ main_context.init_save_history
+ end
+ end
+
+ # A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
+ def history_file
+ IRB.conf[:HISTORY_FILE]
+ end
+
+ # Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
+ def history_file=(hist)
+ IRB.conf[:HISTORY_FILE] = hist
+ end
+ end
+
+ module HistorySavingAbility # :nodoc:
+ include Readline
+
+ def HistorySavingAbility.extended(obj)
+ IRB.conf[:AT_EXIT].push proc{obj.save_history}
+ obj.load_history
+ obj
+ end
+
+ def load_history
+ if history_file = IRB.conf[:HISTORY_FILE]
+ history_file = File.expand_path(history_file)
+ end
+ history_file = IRB.rc_file("_history") unless history_file
+ if File.exist?(history_file)
+ open(history_file) do |f|
+ f.each {|l| HISTORY << l.chomp}
+ end
+ end
+ end
+
+ def save_history
+ if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
+ if history_file = IRB.conf[:HISTORY_FILE]
+ history_file = File.expand_path(history_file)
+ end
+ history_file = IRB.rc_file("_history") unless history_file
+
+ # Change the permission of a file that already exists[BUG #7694]
+ begin
+ if File.stat(history_file).mode & 066 != 0
+ File.chmod(0600, history_file)
+ end
+ rescue Errno::ENOENT
+ rescue
+ raise
+ end
+
+ open(history_file, 'w', 0600 ) do |f|
+ hist = HISTORY.to_a
+ f.puts(hist[-num..-1] || hist)
+ end
+ end
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/ext/tracer.rb b/jni/ruby/lib/irb/ext/tracer.rb
new file mode 100644
index 0000000..691215a
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/tracer.rb
@@ -0,0 +1,71 @@
+#
+# irb/lib/tracer.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require "tracer"
+
+module IRB
+
+ # initialize tracing function
+ def IRB.initialize_tracer
+ Tracer.verbose = false
+ Tracer.add_filter {
+ |event, file, line, id, binding, *rests|
+ /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
+ File::basename(file) != "irb.rb"
+ }
+ end
+
+ class Context
+ # Whether Tracer is used when evaluating statements in this context.
+ #
+ # See +lib/tracer.rb+ for more information.
+ attr_reader :use_tracer
+ alias use_tracer? use_tracer
+
+ # Sets whether or not to use the Tracer library when evaluating statements
+ # in this context.
+ #
+ # See +lib/tracer.rb+ for more information.
+ def use_tracer=(opt)
+ if opt
+ Tracer.set_get_line_procs(@irb_path) {
+ |line_no, *rests|
+ @io.line(line_no)
+ }
+ elsif !opt && @use_tracer
+ Tracer.off
+ end
+ @use_tracer=opt
+ end
+ end
+
+ class WorkSpace
+ alias __evaluate__ evaluate
+ # Evaluate the context of this workspace and use the Tracer library to
+ # output the exact lines of code are being executed in chronological order.
+ #
+ # See +lib/tracer.rb+ for more information.
+ def evaluate(context, statements, file = nil, line = nil)
+ if context.use_tracer? && file != nil && line != nil
+ Tracer.on
+ begin
+ __evaluate__(context, statements, file, line)
+ ensure
+ Tracer.off
+ end
+ else
+ __evaluate__(context, statements, file || __FILE__, line || __LINE__)
+ end
+ end
+ end
+
+ IRB.initialize_tracer
+end
+
diff --git a/jni/ruby/lib/irb/ext/use-loader.rb b/jni/ruby/lib/irb/ext/use-loader.rb
new file mode 100644
index 0000000..7282995
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/use-loader.rb
@@ -0,0 +1,73 @@
+#
+# use-loader.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "irb/cmd/load"
+require "irb/ext/loader"
+
+class Object
+ alias __original__load__IRB_use_loader__ load
+ alias __original__require__IRB_use_loader__ require
+end
+
+module IRB
+ module ExtendCommandBundle
+ # Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
+ def irb_load(*opts, &b)
+ ExtendCommand::Load.execute(irb_context, *opts, &b)
+ end
+ # Loads the given file similarly to Kernel#require
+ def irb_require(*opts, &b)
+ ExtendCommand::Require.execute(irb_context, *opts, &b)
+ end
+ end
+
+ class Context
+
+ IRB.conf[:USE_LOADER] = false
+
+ # Returns whether +irb+'s own file reader method is used by
+ # +load+/+require+ or not.
+ #
+ # This mode is globally affected (irb-wide).
+ def use_loader
+ IRB.conf[:USE_LOADER]
+ end
+
+ alias use_loader? use_loader
+
+ # Sets IRB.conf[:USE_LOADER]
+ #
+ # See #use_loader for more information.
+ def use_loader=(opt)
+
+ if IRB.conf[:USE_LOADER] != opt
+ IRB.conf[:USE_LOADER] = opt
+ if opt
+ if !$".include?("irb/cmd/load")
+ end
+ (class<<@workspace.main;self;end).instance_eval {
+ alias_method :load, :irb_load
+ alias_method :require, :irb_require
+ }
+ else
+ (class<<@workspace.main;self;end).instance_eval {
+ alias_method :load, :__original__load__IRB_use_loader__
+ alias_method :require, :__original__require__IRB_use_loader__
+ }
+ end
+ end
+ print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
+ opt
+ end
+ end
+end
+
+
diff --git a/jni/ruby/lib/irb/ext/workspaces.rb b/jni/ruby/lib/irb/ext/workspaces.rb
new file mode 100644
index 0000000..a11cea3
--- /dev/null
+++ b/jni/ruby/lib/irb/ext/workspaces.rb
@@ -0,0 +1,66 @@
+#
+# push-ws.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+ class Context
+
+ # Size of the current WorkSpace stack
+ def irb_level
+ workspace_stack.size
+ end
+
+ # WorkSpaces in the current stack
+ def workspaces
+ if defined? @workspaces
+ @workspaces
+ else
+ @workspaces = []
+ end
+ end
+
+ # Creates a new workspace with the given object or binding, and appends it
+ # onto the current #workspaces stack.
+ #
+ # See IRB::Context#change_workspace and IRB::WorkSpace.new for more
+ # information.
+ def push_workspace(*_main)
+ if _main.empty?
+ if workspaces.empty?
+ print "No other workspace\n"
+ return nil
+ end
+ ws = workspaces.pop
+ workspaces.push @workspace
+ @workspace = ws
+ return workspaces
+ end
+
+ workspaces.push @workspace
+ @workspace = WorkSpace.new(@workspace.binding, _main[0])
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
+ main.extend ExtendCommandBundle
+ end
+ end
+
+ # Removes the last element from the current #workspaces stack and returns
+ # it, or +nil+ if the current workspace stack is empty.
+ #
+ # Also, see #push_workspace.
+ def pop_workspace
+ if workspaces.empty?
+ print "workspace stack empty\n"
+ return
+ end
+ @workspace = workspaces.pop
+ end
+ end
+end
+
diff --git a/jni/ruby/lib/irb/extend-command.rb b/jni/ruby/lib/irb/extend-command.rb
new file mode 100644
index 0000000..c4fdff5
--- /dev/null
+++ b/jni/ruby/lib/irb/extend-command.rb
@@ -0,0 +1,308 @@
+#
+# irb/extend-command.rb - irb extend command
+# $Release Version: 0.9.6$
+# $Revision: 47114 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+module IRB # :nodoc:
+ # Installs the default irb extensions command bundle.
+ module ExtendCommandBundle
+ EXCB = ExtendCommandBundle # :nodoc:
+
+ # See #install_alias_method.
+ NO_OVERRIDE = 0
+ # See #install_alias_method.
+ OVERRIDE_PRIVATE_ONLY = 0x01
+ # See #install_alias_method.
+ OVERRIDE_ALL = 0x02
+
+ # Quits the current irb context
+ #
+ # +ret+ is the optional signal or message to send to Context#exit
+ #
+ # Same as <code>IRB.CurrentContext.exit</code>.
+ def irb_exit(ret = 0)
+ irb_context.exit(ret)
+ end
+
+ # Displays current configuration.
+ #
+ # Modifing the configuration is achieved by sending a message to IRB.conf.
+ def irb_context
+ IRB.CurrentContext
+ end
+
+ @ALIASES = [
+ [:context, :irb_context, NO_OVERRIDE],
+ [:conf, :irb_context, NO_OVERRIDE],
+ [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],
+ ]
+
+ @EXTEND_COMMANDS = [
+ [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
+ [:irb_print_working_workspace, OVERRIDE_ALL],
+ [:irb_cwws, OVERRIDE_ALL],
+ [:irb_pwws, OVERRIDE_ALL],
+ [:cwws, NO_OVERRIDE],
+ [:pwws, NO_OVERRIDE],
+ [:irb_current_working_binding, OVERRIDE_ALL],
+ [:irb_print_working_binding, OVERRIDE_ALL],
+ [:irb_cwb, OVERRIDE_ALL],
+ [:irb_pwb, OVERRIDE_ALL],
+ ],
+ [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
+ [:irb_chws, OVERRIDE_ALL],
+ [:irb_cws, OVERRIDE_ALL],
+ [:chws, NO_OVERRIDE],
+ [:cws, NO_OVERRIDE],
+ [:irb_change_binding, OVERRIDE_ALL],
+ [:irb_cb, OVERRIDE_ALL],
+ [:cb, NO_OVERRIDE]],
+
+ [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
+ [:workspaces, NO_OVERRIDE],
+ [:irb_bindings, OVERRIDE_ALL],
+ [:bindings, NO_OVERRIDE]],
+ [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
+ [:irb_pushws, OVERRIDE_ALL],
+ [:pushws, NO_OVERRIDE],
+ [:irb_push_binding, OVERRIDE_ALL],
+ [:irb_pushb, OVERRIDE_ALL],
+ [:pushb, NO_OVERRIDE]],
+ [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
+ [:irb_popws, OVERRIDE_ALL],
+ [:popws, NO_OVERRIDE],
+ [:irb_pop_binding, OVERRIDE_ALL],
+ [:irb_popb, OVERRIDE_ALL],
+ [:popb, NO_OVERRIDE]],
+
+ [:irb_load, :Load, "irb/cmd/load"],
+ [:irb_require, :Require, "irb/cmd/load"],
+ [:irb_source, :Source, "irb/cmd/load",
+ [:source, NO_OVERRIDE]],
+
+ [:irb, :IrbCommand, "irb/cmd/subirb"],
+ [:irb_jobs, :Jobs, "irb/cmd/subirb",
+ [:jobs, NO_OVERRIDE]],
+ [:irb_fg, :Foreground, "irb/cmd/subirb",
+ [:fg, NO_OVERRIDE]],
+ [:irb_kill, :Kill, "irb/cmd/subirb",
+ [:kill, OVERRIDE_PRIVATE_ONLY]],
+
+ [:irb_help, :Help, "irb/cmd/help",
+ [:help, NO_OVERRIDE]],
+
+ ]
+
+ # Installs the default irb commands:
+ #
+ # +irb_current_working_workspace+:: Context#main
+ # +irb_change_workspace+:: Context#change_workspace
+ # +irb_workspaces+:: Context#workspaces
+ # +irb_push_workspace+:: Context#push_workspace
+ # +irb_pop_workspace+:: Context#pop_workspace
+ # +irb_load+:: #irb_load
+ # +irb_require+:: #irb_require
+ # +irb_source+:: IrbLoader#source_file
+ # +irb+:: IRB.irb
+ # +irb_jobs+:: JobManager
+ # +irb_fg+:: JobManager#switch
+ # +irb_kill+:: JobManager#kill
+ # +irb_help+:: IRB@Command+line+options
+ def self.install_extend_commands
+ for args in @EXTEND_COMMANDS
+ def_extend_command(*args)
+ end
+ end
+
+ # Evaluate the given +cmd_name+ on the given +cmd_class+ Class.
+ #
+ # Will also define any given +aliases+ for the method.
+ #
+ # The optional +load_file+ parameter will be required within the method
+ # definition.
+ def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
+ case cmd_class
+ when Symbol
+ cmd_class = cmd_class.id2name
+ when String
+ when Class
+ cmd_class = cmd_class.name
+ end
+
+ if load_file
+ line = __LINE__; eval %[
+ def #{cmd_name}(*opts, &b)
+ require "#{load_file}"
+ arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
+ args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
+ args << "*opts" if arity < 0
+ args << "&block"
+ args = args.join(", ")
+ line = __LINE__; eval %[
+ def #{cmd_name}(\#{args})
+ ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
+ end
+ ], nil, __FILE__, line
+ send :#{cmd_name}, *opts, &b
+ end
+ ], nil, __FILE__, line
+ else
+ line = __LINE__; eval %[
+ def #{cmd_name}(*opts, &b)
+ ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
+ end
+ ], nil, __FILE__, line
+ end
+
+ for ali, flag in aliases
+ @ALIASES.push [ali, cmd_name, flag]
+ end
+ end
+
+ # Installs alias methods for the default irb commands, see
+ # ::install_extend_commands.
+ def install_alias_method(to, from, override = NO_OVERRIDE)
+ 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 == NO_OVERRIDE) && !respond_to?(to, true)
+ target = self
+ (class << self; self; end).instance_eval{
+ if target.respond_to?(to, true) &&
+ !target.respond_to?(EXCB.irb_original_method_name(to), true)
+ alias_method(EXCB.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) # :nodoc:
+ "irb_" + method_name + "_org"
+ end
+
+ # Installs alias methods for the default irb commands on the given object
+ # using #install_alias_method.
+ def self.extend_object(obj)
+ unless (class << obj; ancestors; end).include?(EXCB)
+ super
+ for ali, com, flg in @ALIASES
+ obj.install_alias_method(ali, com, flg)
+ end
+ end
+ end
+
+ install_extend_commands
+ end
+
+ # Extends methods for the Context module
+ module ContextExtender
+ CE = ContextExtender # :nodoc:
+
+ @EXTEND_COMMANDS = [
+ [:eval_history=, "irb/ext/history.rb"],
+ [:use_tracer=, "irb/ext/tracer.rb"],
+ [:math_mode=, "irb/ext/math-mode.rb"],
+ [:use_loader=, "irb/ext/use-loader.rb"],
+ [:save_history=, "irb/ext/save-history.rb"],
+ ]
+
+ # Installs the default context extensions as irb commands:
+ #
+ # Context#eval_history=:: +irb/ext/history.rb+
+ # Context#use_tracer=:: +irb/ext/tracer.rb+
+ # Context#math_mode=:: +irb/ext/math-mode.rb+
+ # Context#use_loader=:: +irb/ext/use-loader.rb+
+ # Context#save_history=:: +irb/ext/save-history.rb+
+ def self.install_extend_commands
+ for args in @EXTEND_COMMANDS
+ def_extend_command(*args)
+ end
+ end
+
+ # Evaluate the given +command+ from the given +load_file+ on the Context
+ # module.
+ #
+ # Will also define any given +aliases+ for the method.
+ def self.def_extend_command(cmd_name, load_file, *aliases)
+ line = __LINE__; Context.module_eval %[
+ def #{cmd_name}(*opts, &b)
+ Context.module_eval {remove_method(:#{cmd_name})}
+ require "#{load_file}"
+ send :#{cmd_name}, *opts, &b
+ end
+ for ali in aliases
+ alias_method ali, cmd_name
+ end
+ ], __FILE__, line
+ end
+
+ CE.install_extend_commands
+ end
+
+ # A convenience module for extending Ruby methods.
+ module MethodExtender
+ # Extends the given +base_method+ with a prefix call to the given
+ # +extend_method+.
+ def def_pre_proc(base_method, extend_method)
+ base_method = base_method.to_s
+ extend_method = extend_method.to_s
+
+ alias_name = new_alias_name(base_method)
+ module_eval %[
+ alias_method alias_name, base_method
+ def #{base_method}(*opts)
+ send :#{extend_method}, *opts
+ send :#{alias_name}, *opts
+ end
+ ]
+ end
+
+ # Extends the given +base_method+ with a postfix call to the given
+ # +extend_method+.
+ def def_post_proc(base_method, extend_method)
+ base_method = base_method.to_s
+ extend_method = extend_method.to_s
+
+ alias_name = new_alias_name(base_method)
+ module_eval %[
+ alias_method alias_name, base_method
+ def #{base_method}(*opts)
+ send :#{alias_name}, *opts
+ send :#{extend_method}, *opts
+ end
+ ]
+ end
+
+ # Returns a unique method name to use as an alias for the given +name+.
+ #
+ # Usually returns <code>#{prefix}#{name}#{postfix}<num></code>, example:
+ #
+ # new_alias_name('foo') #=> __alias_of__foo__
+ # def bar; end
+ # new_alias_name('bar') #=> __alias_of__bar__2
+ def new_alias_name(name, prefix = "__alias_of__", postfix = "__")
+ base_name = "#{prefix}#{name}#{postfix}"
+ all_methods = instance_methods(true) + private_instance_methods(true)
+ same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)
+ return base_name if same_methods.empty?
+ no = same_methods.size
+ while !same_methods.include?(alias_name = base_name + no)
+ no += 1
+ end
+ alias_name
+ end
+ end
+end
+
diff --git a/jni/ruby/lib/irb/frame.rb b/jni/ruby/lib/irb/frame.rb
new file mode 100644
index 0000000..4a1d080
--- /dev/null
+++ b/jni/ruby/lib/irb/frame.rb
@@ -0,0 +1,80 @@
+#
+# frame.rb -
+# $Release Version: 0.9$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+#
+# --
+#
+#
+#
+
+require "e2mmap"
+
+module IRB
+ class Frame
+ extend Exception2MessageMapper
+ def_exception :FrameOverflow, "frame overflow"
+ def_exception :FrameUnderflow, "frame underflow"
+
+ # Default number of stack frames
+ INIT_STACK_TIMES = 3
+ # Default number of frames offset
+ CALL_STACK_OFFSET = 3
+
+ # Creates a new stack frame
+ def initialize
+ @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES
+ end
+
+ # Used by Kernel#set_trace_func to register each event in the call stack
+ def trace_func(event, file, line, id, binding)
+ case event
+ when 'call', 'class'
+ @frames.push binding
+ when 'return', 'end'
+ @frames.pop
+ end
+ end
+
+ # Returns the +n+ number of frames on the call stack from the last frame
+ # initialized.
+ #
+ # Raises FrameUnderflow if there are no frames in the given stack range.
+ def top(n = 0)
+ bind = @frames[-(n + CALL_STACK_OFFSET)]
+ Fail FrameUnderflow unless bind
+ bind
+ end
+
+ # Returns the +n+ number of frames on the call stack from the first frame
+ # initialized.
+ #
+ # Raises FrameOverflow if there are no frames in the given stack range.
+ def bottom(n = 0)
+ bind = @frames[n]
+ Fail FrameOverflow unless bind
+ bind
+ end
+
+ # Convenience method for Frame#bottom
+ def Frame.bottom(n = 0)
+ @backtrace.bottom(n)
+ end
+
+ # Convenience method for Frame#top
+ def Frame.top(n = 0)
+ @backtrace.top(n)
+ end
+
+ # Returns the binding context of the caller from the last frame initialized
+ def Frame.sender
+ eval "self", @backtrace.top
+ end
+
+ @backtrace = Frame.new
+ set_trace_func proc{|event, file, line, id, binding, klass|
+ @backtrace.trace_func(event, file, line, id, binding)
+ }
+ end
+end
diff --git a/jni/ruby/lib/irb/help.rb b/jni/ruby/lib/irb/help.rb
new file mode 100644
index 0000000..c0160f0
--- /dev/null
+++ b/jni/ruby/lib/irb/help.rb
@@ -0,0 +1,36 @@
+#
+# irb/help.rb - print usage module
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ishitsuka.com)
+#
+# --
+#
+#
+#
+
+require 'irb/magic-file'
+
+module IRB
+ # Outputs the irb help message, see IRB@Command+line+options.
+ def IRB.print_usage
+ lc = IRB.conf[:LC_MESSAGES]
+ path = lc.find("irb/help-message")
+ space_line = false
+ IRB::MagicFile.open(path){|f|
+ f.each_line 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/jni/ruby/lib/irb/init.rb b/jni/ruby/lib/irb/init.rb
new file mode 100644
index 0000000..98289b3
--- /dev/null
+++ b/jni/ruby/lib/irb/init.rb
@@ -0,0 +1,304 @@
+#
+# irb/init.rb - irb initialize module
+# $Release Version: 0.9.6$
+# $Revision: 47114 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+
+ # initialize config
+ def IRB.setup(ap_path)
+ IRB.init_config(ap_path)
+ IRB.init_error
+ IRB.parse_opts
+ IRB.run_config
+ IRB.load_modules
+
+ unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
+ IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
+ end
+ end
+
+ # @CONF default setting
+ def IRB.init_config(ap_path)
+ # class instance variables
+ @TRACER_INITIALIZED = false
+
+ # default configurations
+ 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] = true
+ @CONF[:USE_TRACER] = false
+ @CONF[:USE_LOADER] = false
+ @CONF[:IGNORE_SIGINT] = true
+ @CONF[:IGNORE_EOF] = false
+ @CONF[:ECHO] = nil
+ @CONF[:VERBOSE] = nil
+
+ @CONF[:EVAL_HISTORY] = nil
+ @CONF[:SAVE_HISTORY] = nil
+
+ @CONF[:BACK_TRACE_LIMIT] = 16
+
+ @CONF[:PROMPT] = {
+ :NULL => {
+ :PROMPT_I => nil,
+ :PROMPT_N => nil,
+ :PROMPT_S => nil,
+ :PROMPT_C => nil,
+ :RETURN => "%s\n"
+ },
+ :DEFAULT => {
+ :PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => "%N(%m):%03n:%i> ",
+ :PROMPT_S => "%N(%m):%03n:%i%l ",
+ :PROMPT_C => "%N(%m):%03n:%i* ",
+ :RETURN => "=> %s\n"
+ },
+ :CLASSIC => {
+ :PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => "%N(%m):%03n:%i> ",
+ :PROMPT_S => "%N(%m):%03n:%i%l ",
+ :PROMPT_C => "%N(%m):%03n:%i* ",
+ :RETURN => "%s\n"
+ },
+ :SIMPLE => {
+ :PROMPT_I => ">> ",
+ :PROMPT_N => ">> ",
+ :PROMPT_S => nil,
+ :PROMPT_C => "?> ",
+ :RETURN => "=> %s\n"
+ },
+ :INF_RUBY => {
+ :PROMPT_I => "%N(%m):%03n:%i> ",
+ :PROMPT_N => nil,
+ :PROMPT_S => nil,
+ :PROMPT_C => nil,
+ :RETURN => "%s\n",
+ :AUTO_INDENT => true
+ },
+ :XMP => {
+ :PROMPT_I => nil,
+ :PROMPT_N => nil,
+ :PROMPT_S => nil,
+ :PROMPT_C => nil,
+ :RETURN => " ==>%s\n"
+ }
+ }
+
+ @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
+ @CONF[:AUTO_INDENT] = false
+
+ @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
+ @CONF[:SINGLE_IRB] = false
+
+ @CONF[:LC_MESSAGES] = Locale.new
+
+ @CONF[:AT_EXIT] = []
+
+ @CONF[:DEBUG_LEVEL] = 0
+ end
+
+ def IRB.init_error
+ @CONF[:LC_MESSAGES].load("irb/error.rb")
+ end
+
+ # option analyzing
+ def IRB.parse_opts
+ load_path = []
+ while opt = ARGV.shift
+ case opt
+ when "-f"
+ @CONF[:RC] = false
+ when "-m"
+ @CONF[:MATH_MODE] = true
+ when "-d"
+ $DEBUG = true
+ $VERBOSE = true
+ when "-w"
+ $VERBOSE = true
+ when /^-W(.+)?/
+ opt = $1 || ARGV.shift
+ case opt
+ when "0"
+ $VERBOSE = nil
+ when "1"
+ $VERBOSE = false
+ else
+ $VERBOSE = true
+ end
+ when /^-r(.+)?/
+ opt = $1 || ARGV.shift
+ @CONF[:LOAD_MODULES].push opt if opt
+ when /^-I(.+)?/
+ opt = $1 || ARGV.shift
+ load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
+ when '-U'
+ set_encoding("UTF-8", "UTF-8")
+ when /^-E(.+)?/, /^--encoding(?:=(.+))?/
+ opt = $1 || ARGV.shift
+ set_encoding(*opt.split(':', 2))
+ when "--inspect"
+ if /^-/ !~ ARGV.first
+ @CONF[:INSPECT_MODE] = ARGV.shift
+ else
+ @CONF[:INSPECT_MODE] = true
+ end
+ when "--noinspect"
+ @CONF[:INSPECT_MODE] = false
+ when "--readline"
+ @CONF[:USE_READLINE] = true
+ when "--noreadline"
+ @CONF[:USE_READLINE] = false
+ when "--echo"
+ @CONF[:ECHO] = true
+ when "--noecho"
+ @CONF[:ECHO] = false
+ when "--verbose"
+ @CONF[:VERBOSE] = true
+ when "--noverbose"
+ @CONF[:VERBOSE] = false
+ when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
+ opt = $1 || ARGV.shift
+ prompt_mode = opt.upcase.tr("-", "_").intern
+ @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] = ($1 || ARGV.shift).to_i
+ when /^--context-mode(?:=(.+))?/
+ @CONF[:CONTEXT_MODE] = ($1 || ARGV.shift).to_i
+ when "--single-irb"
+ @CONF[:SINGLE_IRB] = true
+ when /^--irb_debug(?:=(.+))?/
+ @CONF[:DEBUG_LEVEL] = ($1 || 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 "--"
+ if opt = ARGV.shift
+ @CONF[:SCRIPT] = opt
+ $0 = opt
+ end
+ break
+ when /^-/
+ IRB.fail UnrecognizedSwitch, opt
+ else
+ @CONF[:SCRIPT] = opt
+ $0 = opt
+ break
+ end
+ end
+ load_path.collect! do |path|
+ /\A\.\// =~ path ? path : File.expand_path(path)
+ end
+ $LOAD_PATH.unshift(*load_path)
+
+ end
+
+ # running config
+ def IRB.run_config
+ if @CONF[:RC]
+ begin
+ load rc_file
+ rescue LoadError, Errno::ENOENT
+ rescue # StandardError, ScriptError
+ print "load error: #{rc_file}\n"
+ print $!.class, ": ", $!, "\n"
+ for err in $@[0, $@.size - 2]
+ print "\t", err, "\n"
+ end
+ end
+ end
+ end
+
+ IRBRC_EXT = "rc"
+ def IRB.rc_file(ext = IRBRC_EXT)
+ if !@CONF[:RC_NAME_GENERATOR]
+ rc_file_generators do |rcgen|
+ @CONF[:RC_NAME_GENERATOR] ||= rcgen
+ if File.exist?(rcgen.call(IRBRC_EXT))
+ @CONF[:RC_NAME_GENERATOR] = rcgen
+ break
+ end
+ end
+ end
+ case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
+ when String
+ return rc_file
+ else
+ IRB.fail IllegalRCNameGenerator
+ end
+ end
+
+ # enumerate possible rc-file base name generators
+ def IRB.rc_file_generators
+ if irbrc = ENV["IRBRC"]
+ yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
+ end
+ if home = ENV["HOME"]
+ yield proc{|rc| home+"/.irb#{rc}"}
+ end
+ home = Dir.pwd
+ yield proc{|rc| home+"/.irb#{rc}"}
+ yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
+ yield proc{|rc| home+"/_irb#{rc}"}
+ yield proc{|rc| home+"/$irb#{rc}"}
+ end
+
+ # loading modules
+ def IRB.load_modules
+ for m in @CONF[:LOAD_MODULES]
+ begin
+ require m
+ rescue LoadError => err
+ warn err.backtrace[0] << ":#{err.class}: #{err}"
+ end
+ end
+ end
+
+
+ DefaultEncodings = Struct.new(:external, :internal)
+ class << IRB
+ private
+ def set_encoding(extern, intern = nil)
+ verbose, $VERBOSE = $VERBOSE, nil
+ Encoding.default_external = extern unless extern.nil? || extern.empty?
+ Encoding.default_internal = intern unless intern.nil? || intern.empty?
+ @CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
+ [$stdin, $stdout, $stderr].each do |io|
+ io.set_encoding(extern, intern)
+ end
+ @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/input-method.rb b/jni/ruby/lib/irb/input-method.rb
new file mode 100644
index 0000000..97add92
--- /dev/null
+++ b/jni/ruby/lib/irb/input-method.rb
@@ -0,0 +1,191 @@
+#
+# irb/input-method.rb - input methods used irb
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require 'irb/src_encoding'
+require 'irb/magic-file'
+
+module IRB
+ STDIN_FILE_NAME = "(line)" # :nodoc:
+ class InputMethod
+
+ # Creates a new input method object
+ def initialize(file = STDIN_FILE_NAME)
+ @file_name = file
+ end
+ # The file name of this input method, usually given during initialization.
+ attr_reader :file_name
+
+ # The irb prompt associated with this input method
+ attr_accessor :prompt
+
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ IRB.fail NotImplementedError, "gets"
+ end
+ public :gets
+
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
+ false
+ end
+ end
+
+ class StdioInputMethod < InputMethod
+ # Creates a new input method object
+ def initialize
+ super
+ @line_no = 0
+ @line = []
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ end
+
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ print @prompt
+ line = @stdin.gets
+ @line[@line_no += 1] = line
+ end
+
+ # Whether the end of this input method has been reached, returns +true+ if
+ # there is no more data to read.
+ #
+ # See IO#eof? for more information.
+ def eof?
+ @stdin.eof?
+ end
+
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
+ true
+ end
+
+ # Returns the current line number for #io.
+ #
+ # #line counts the number of times #gets is called.
+ #
+ # See IO#lineno for more information.
+ def line(line_no)
+ @line[line_no]
+ end
+
+ # The external encoding for standard input.
+ def encoding
+ @stdin.external_encoding
+ end
+ end
+
+ # Use a File for IO with irb, see InputMethod
+ class FileInputMethod < InputMethod
+ # Creates a new input method object
+ def initialize(file)
+ super
+ @io = IRB::MagicFile.open(file)
+ end
+ # The file name of this input method, usually given during initialization.
+ attr_reader :file_name
+
+ # Whether the end of this input method has been reached, returns +true+ if
+ # there is no more data to read.
+ #
+ # See IO#eof? for more information.
+ def eof?
+ @io.eof?
+ end
+
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ print @prompt
+ l = @io.gets
+ l
+ end
+
+ # The external encoding for standard input.
+ def encoding
+ @io.external_encoding
+ end
+ end
+
+ begin
+ require "readline"
+ class ReadlineInputMethod < InputMethod
+ include Readline
+ # Creates a new input method object using Readline
+ def initialize
+ super
+
+ @line_no = 0
+ @line = []
+ @eof = false
+
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
+ end
+
+ # Reads the next line from this input method.
+ #
+ # See IO#gets for more information.
+ def gets
+ Readline.input = @stdin
+ Readline.output = @stdout
+ if l = readline(@prompt, false)
+ HISTORY.push(l) if !l.empty?
+ @line[@line_no += 1] = l + "\n"
+ else
+ @eof = true
+ l
+ end
+ end
+
+ # Whether the end of this input method has been reached, returns +true+
+ # if there is no more data to read.
+ #
+ # See IO#eof? for more information.
+ def eof?
+ @eof
+ end
+
+ # Whether this input method is still readable when there is no more data to
+ # read.
+ #
+ # See IO#eof for more information.
+ def readable_after_eof?
+ true
+ end
+
+ # Returns the current line number for #io.
+ #
+ # #line counts the number of times #gets is called.
+ #
+ # See IO#lineno for more information.
+ def line(line_no)
+ @line[line_no]
+ end
+
+ # The external encoding for standard input.
+ def encoding
+ @stdin.external_encoding
+ end
+ end
+ rescue LoadError
+ end
+end
diff --git a/jni/ruby/lib/irb/inspector.rb b/jni/ruby/lib/irb/inspector.rb
new file mode 100644
index 0000000..f09b129
--- /dev/null
+++ b/jni/ruby/lib/irb/inspector.rb
@@ -0,0 +1,131 @@
+#
+# irb/inspector.rb - inspect methods
+# $Release Version: 0.9.6$
+# $Revision: 1.19 $
+# $Date: 2002/06/11 07:51:31 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+
+
+ # Convenience method to create a new Inspector, using the given +inspect+
+ # proc, and optional +init+ proc and passes them to Inspector.new
+ #
+ # irb(main):001:0> ins = IRB::Inspector(proc{ |v| "omg! #{v}" })
+ # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
+ # irb(main):001:0> "what?" #=> omg! what?
+ #
+ def IRB::Inspector(inspect, init = nil)
+ Inspector.new(inspect, init)
+ end
+
+ # An irb inspector
+ #
+ # In order to create your own custom inspector there are two things you
+ # should be aware of:
+ #
+ # Inspector uses #inspect_value, or +inspect_proc+, for output of return values.
+ #
+ # This also allows for an optional #init+, or +init_proc+, which is called
+ # when the inspector is activated.
+ #
+ # Knowing this, you can create a rudimentary inspector as follows:
+ #
+ # irb(main):001:0> ins = IRB::Inspector.new(proc{ |v| "omg! #{v}" })
+ # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! #<IRB::Inspector:0x007f46f7ba7d28>
+ # irb(main):001:0> "what?" #=> omg! what?
+ #
+ class Inspector
+ # Default inspectors available to irb, this includes:
+ #
+ # +:pp+:: Using Kernel#pretty_inspect
+ # +:yaml+:: Using YAML.dump
+ # +:marshal+:: Using Marshal.dump
+ INSPECTORS = {}
+
+ # Determines the inspector to use where +inspector+ is one of the keys passed
+ # during inspector definition.
+ def self.keys_with_inspector(inspector)
+ INSPECTORS.select{|k,v| v == inspector}.collect{|k, v| k}
+ end
+
+ # Example
+ #
+ # Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
+ # Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
+ # Inspector.def_inspector(key, inspector)
+ # Inspector.def_inspector([key1,...], inspector)
+ def self.def_inspector(key, arg=nil, &block)
+ if block_given?
+ inspector = IRB::Inspector(block, arg)
+ else
+ inspector = arg
+ end
+
+ case key
+ when Array
+ for k in key
+ def_inspector(k, inspector)
+ end
+ when Symbol
+ INSPECTORS[key] = inspector
+ INSPECTORS[key.to_s] = inspector
+ when String
+ INSPECTORS[key] = inspector
+ INSPECTORS[key.intern] = inspector
+ else
+ INSPECTORS[key] = inspector
+ end
+ end
+
+ # Creates a new inspector object, using the given +inspect_proc+ when
+ # output return values in irb.
+ def initialize(inspect_proc, init_proc = nil)
+ @init = init_proc
+ @inspect = inspect_proc
+ end
+
+ # Proc to call when the inspector is activated, good for requiring
+ # dependent libraries.
+ def init
+ @init.call if @init
+ end
+
+ # Proc to call when the input is evaluated and output in irb.
+ def inspect_value(v)
+ @inspect.call(v)
+ end
+ end
+
+ Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
+ Inspector.def_inspector([true, :p, :inspect]){|v|
+ begin
+ v.inspect
+ rescue NoMethodError
+ puts "(Object doesn't support #inspect)"
+ end
+ }
+ Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| v.pretty_inspect.chomp}
+ Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
+ begin
+ YAML.dump(v)
+ rescue
+ puts "(can't dump yaml. use inspect)"
+ v.inspect
+ end
+ }
+
+ Inspector.def_inspector([:marshal, :Marshal, :MARSHAL, Marshal]){|v|
+ Marshal.dump(v)
+ }
+end
+
+
+
+
+
diff --git a/jni/ruby/lib/irb/lc/.document b/jni/ruby/lib/irb/lc/.document
new file mode 100644
index 0000000..524bb94
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/.document
@@ -0,0 +1,4 @@
+# hide help-message files which contain usage information
+error.rb
+ja/encoding_aliases.rb
+ja/error.rb
diff --git a/jni/ruby/lib/irb/lc/error.rb b/jni/ruby/lib/irb/lc/error.rb
new file mode 100644
index 0000000..a0d0dc8
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/error.rb
@@ -0,0 +1,31 @@
+#
+# irb/lc/error.rb -
+# $Release Version: 0.9.6$
+# $Revision: 38600 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require "e2mmap"
+
+# :stopdoc:
+module IRB
+
+ # exceptions
+ extend Exception2MessageMapper
+ def_exception :UnrecognizedSwitch, "Unrecognized switch: %s"
+ def_exception :NotImplementedError, "Need to define `%s'"
+ def_exception :CantReturnToNormalMode, "Can't return to normal mode."
+ def_exception :IllegalParameter, "Invalid parameter(%s)."
+ def_exception :IrbAlreadyDead, "Irb is already dead."
+ def_exception :IrbSwitchedToCurrentThread, "Switched to current thread."
+ def_exception :NoSuchJob, "No such job(%s)."
+ def_exception :CantShiftToMultiIrbMode, "Can't shift to multi irb mode."
+ def_exception :CantChangeBinding, "Can't change binding to (%s)."
+ def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)."
+ def_exception :IllegalRCGenerator, 'Define illegal RC_NAME_GENERATOR.'
+
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/lc/help-message b/jni/ruby/lib/irb/lc/help-message
new file mode 100644
index 0000000..7ac1b2a
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/help-message
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+#
+# irb/lc/help-message.rb -
+# $Release Version: 0.9.6$
+# $Revision: 41028 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+Usage: irb.rb [options] [programfile] [arguments]
+ -f Suppress read of ~/.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'
+ -I path Specify $LOAD_PATH directory
+ -U Same as `ruby -U`
+ -E enc Same as `ruby -E`
+ -w Same as `ruby -w`
+ -W[level=2] Same as `ruby -W`
+ --context-mode n Set n[0-3] to method to create Binding Object,
+ when new workspace was created
+ --echo Show result(default)
+ --noecho Don't show result
+ --inspect Use `inspect' for output (default except for bc mode)
+ --noinspect Don't use inspect for output
+ --readline Use Readline extension module
+ --noreadline Don't use Readline extension module
+ --prompt prompt-mode/--prompt-mode prompt-mode
+ Switch prompt mode. Pre-defined prompt modes are
+ `default', `simple', `xmp' and `inf-ruby'
+ --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
+ Suppresses --readline.
+ --sample-book-mode/--simple-prompt
+ Simple prompt mode
+ --noprompt No prompt mode
+ --single-irb Share self with sub-irb.
+ --tracer Display trace for each execution of commands.
+ --back-trace-limit n
+ Display backtrace top n and tail n. The default
+ value is 16.
+ --irb_debug n Set internal debug level to n (not for popular use)
+ --verbose Show details
+ --noverbose Don't show details
+ -v, --version Print the version of irb
+ -h, --help Print help
+ -- Separate options of irb from the list of command-line args
+
+# vim:fileencoding=utf-8
diff --git a/jni/ruby/lib/irb/lc/ja/encoding_aliases.rb b/jni/ruby/lib/irb/lc/ja/encoding_aliases.rb
new file mode 100644
index 0000000..5bef32e
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/ja/encoding_aliases.rb
@@ -0,0 +1,10 @@
+# :stopdoc:
+module IRB
+ class Locale
+ @@legacy_encoding_alias_map = {
+ 'ujis' => Encoding::EUC_JP,
+ 'euc' => Encoding::EUC_JP
+ }.freeze
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/lc/ja/error.rb b/jni/ruby/lib/irb/lc/ja/error.rb
new file mode 100644
index 0000000..6532777
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/ja/error.rb
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# irb/lc/ja/error.rb -
+# $Release Version: 0.9.6$
+# $Revision: 38600 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+require "e2mmap"
+
+# :stopdoc:
+module IRB
+ # exceptions
+ extend Exception2MessageMapper
+ def_exception :UnrecognizedSwitch, 'スイッチ(%s)が分りません'
+ def_exception :NotImplementedError, '`%s\'の定義が必要です'
+ def_exception :CantReturnToNormalMode, 'Normalモードに戻れません.'
+ def_exception :IllegalParameter, 'パラメータ(%s)が間違っています.'
+ def_exception :IrbAlreadyDead, 'Irbは既に死んでいます.'
+ def_exception :IrbSwitchedToCurrentThread, 'カレントスレッドに切り替わりました.'
+ def_exception :NoSuchJob, 'そのようなジョブ(%s)はありません.'
+ def_exception :CantShiftToMultiIrbMode, 'multi-irb modeに移れません.'
+ def_exception :CantChangeBinding, 'バインディング(%s)に変更できません.'
+ def_exception :UndefinedPromptMode, 'プロンプトモード(%s)は定義されていません.'
+ def_exception :IllegalRCNameGenerator, 'RC_NAME_GENERATORが正しく定義されていません.'
+end
+# :startdoc:
+# vim:fileencoding=utf-8
diff --git a/jni/ruby/lib/irb/lc/ja/help-message b/jni/ruby/lib/irb/lc/ja/help-message
new file mode 100644
index 0000000..1483892
--- /dev/null
+++ b/jni/ruby/lib/irb/lc/ja/help-message
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# irb/lc/ja/help-message.rb -
+# $Release Version: 0.9.6$
+# $Revision: 41071 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+Usage: irb.rb [options] [programfile] [arguments]
+ -f ~/.irbrc を読み込まない.
+ -m bcモード(分数, 行列の計算ができる)
+ -d $DEBUG をtrueにする(ruby -d と同じ)
+ -r load-module ruby -r と同じ.
+ -I path $LOAD_PATH に path を追加する.
+ -U ruby -U と同じ.
+ -E enc ruby -E と同じ.
+ -w ruby -w と同じ.
+ -W[level=2] ruby -W と同じ.
+ --context-mode n 新しいワークスペースを作成した時に関連する Binding
+ オブジェクトの作成方法を 0 から 3 のいずれかに設定する.
+ --echo 実行結果を表示する(デフォルト).
+ --noecho 実行結果を表示しない.
+ --inspect 結果出力にinspectを用いる(bcモード以外はデフォルト).
+ --noinspect 結果出力にinspectを用いない.
+ --readline readlineライブラリを利用する.
+ --noreadline readlineライブラリを利用しない.
+ --prompt prompt-mode/--prompt-mode prompt-mode
+ プロンプトモードを切替えます. 現在定義されているプ
+ ロンプトモードは, default, simple, xmp, inf-rubyが
+ 用意されています.
+ --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特
+ に指定がない限り, readlineライブラリは使わなくなる.
+ --sample-book-mode/--simple-prompt
+ 非常にシンプルなプロンプトを用いるモードです.
+ --noprompt プロンプト表示を行なわない.
+ --single-irb irb 中で self を実行して得られるオブジェクトをサ
+ ブ irb と共有する.
+ --tracer コマンド実行時にトレースを行なう.
+ --back-trace-limit n
+ バックトレース表示をバックトレースの頭から n, 後ろ
+ からnだけ行なう. デフォルトは16
+
+ --irb_debug n irbのデバッグレベルをnに設定する(非推奨).
+
+ --verbose 詳細なメッセージを出力する.
+ --noverbose 詳細なメッセージを出力しない(デフォルト).
+ -v, --version irbのバージョンを表示する.
+ -h, --help irb のヘルプを表示する.
+ -- 以降のコマンドライン引数をオプションとして扱わない.
+
+# vim:fileencoding=utf-8
diff --git a/jni/ruby/lib/irb/locale.rb b/jni/ruby/lib/irb/locale.rb
new file mode 100644
index 0000000..f3bd2d7
--- /dev/null
+++ b/jni/ruby/lib/irb/locale.rb
@@ -0,0 +1,181 @@
+#
+# irb/locale.rb - internationalization module
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+module IRB # :nodoc:
+ class Locale
+
+ LOCALE_NAME_RE = %r[
+ (?<language>[[:alpha:]]{2,3})
+ (?:_ (?<territory>[[:alpha:]]{2,3}) )?
+ (?:\. (?<codeset>[^@]+) )?
+ (?:@ (?<modifier>.*) )?
+ ]x
+ LOCALE_DIR = "/lc/"
+
+ @@legacy_encoding_alias_map = {}.freeze
+
+ def initialize(locale = nil)
+ @lang = @territory = @encoding_name = @modifier = nil
+ @locale = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C"
+ if m = LOCALE_NAME_RE.match(@locale)
+ @lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier]
+
+ if @encoding_name
+ begin load 'irb/encoding_aliases.rb'; rescue LoadError; end
+ if @encoding = @@legacy_encoding_alias_map[@encoding_name]
+ warn "%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]
+ end
+ @encoding = Encoding.find(@encoding_name) rescue nil
+ end
+ end
+ @encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT)
+ end
+
+ attr_reader :lang, :territory, :encoding, :modifier
+
+ def String(mes)
+ mes = super(mes)
+ if @encoding
+ mes.encode(@encoding, undef: :replace)
+ else
+ mes
+ end
+ 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(opt)}
+ super(*ary)
+ end
+
+ 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)
+ found = find(file)
+ if found
+ return real_load(found, priv)
+ else
+ raise LoadError, "No such file to load -- #{file}"
+ end
+ end
+
+ def find(file , paths = $:)
+ dir = File.dirname(file)
+ dir = "" if dir == "."
+ base = File.basename(file)
+
+ if dir.start_with?('/')
+ return each_localized_path(dir, base).find{|full_path| File.readable? full_path}
+ else
+ return search_file(paths, dir, base)
+ end
+ end
+
+ private
+ def real_load(path, priv)
+ src = MagicFile.open(path){|f| f.read}
+ if priv
+ eval("self", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)})
+ else
+ eval(src, TOPLEVEL_BINDING, path)
+ end
+ end
+
+ # @param paths load paths in which IRB find a localized file.
+ # @param dir directory
+ # @param file basename to be localized
+ #
+ # typically, for the parameters and a <path> in paths, it searches
+ # <path>/<dir>/<locale>/<file>
+ def search_file(lib_paths, dir, file)
+ each_localized_path(dir, file) do |lc_path|
+ lib_paths.each do |libpath|
+ full_path = File.join(libpath, lc_path)
+ return full_path if File.readable?(full_path)
+ end
+ redo if defined?(Gem) and Gem.try_activate(lc_path)
+ end
+ nil
+ end
+
+ def each_localized_path(dir, file)
+ return enum_for(:each_localized_path) unless block_given?
+ each_sublocale do |lc|
+ yield lc.nil? ? File.join(dir, LOCALE_DIR, file) : File.join(dir, LOCALE_DIR, lc, file)
+ end
+ end
+
+ def each_sublocale
+ if @lang
+ if @territory
+ if @encoding_name
+ yield "#{@lang}_#{@territory}.#{@encoding_name}@#{@modifier}" if @modifier
+ yield "#{@lang}_#{@territory}.#{@encoding_name}"
+ end
+ yield "#{@lang}_#{@territory}@#{@modifier}" if @modifier
+ yield "#{@lang}_#{@territory}"
+ end
+ if @encoding_name
+ yield "#{@lang}.#{@encoding_name}@#{@modifier}" if @modifier
+ yield "#{@lang}.#{@encoding_name}"
+ end
+ yield "#{@lang}@#{@modifier}" if @modifier
+ yield "#{@lang}"
+ end
+ yield nil
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/magic-file.rb b/jni/ruby/lib/irb/magic-file.rb
new file mode 100644
index 0000000..339ed60
--- /dev/null
+++ b/jni/ruby/lib/irb/magic-file.rb
@@ -0,0 +1,37 @@
+module IRB
+ class << (MagicFile = Object.new)
+ # see parser_magic_comment in parse.y
+ ENCODING_SPEC_RE = %r"coding\s*[=:]\s*([[:alnum:]\-_]+)"
+
+ def open(path)
+ io = File.open(path, 'rb')
+ line = io.gets
+ line = io.gets if line[0,2] == "#!"
+ encoding = detect_encoding(line)
+ internal_encoding = encoding
+ encoding ||= default_src_encoding
+ io.rewind
+ io.set_encoding(encoding, internal_encoding)
+
+ if block_given?
+ begin
+ return (yield io)
+ ensure
+ io.close
+ end
+ else
+ return io
+ end
+ end
+
+ private
+ def detect_encoding(line)
+ return unless line[0] == ?#
+ line = line[1..-1]
+ line = $1 if line[/-\*-\s*(.*?)\s*-*-$/]
+ return nil unless ENCODING_SPEC_RE =~ line
+ encoding = $1
+ return encoding.sub(/-(?:mac|dos|unix)/i, '')
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/notifier.rb b/jni/ruby/lib/irb/notifier.rb
new file mode 100644
index 0000000..b08d201
--- /dev/null
+++ b/jni/ruby/lib/irb/notifier.rb
@@ -0,0 +1,231 @@
+#
+# notifier.rb - output methods used by irb
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "e2mmap"
+require "irb/output-method"
+
+module IRB
+ # An output formatter used internally by the lexer.
+ module Notifier
+ extend Exception2MessageMapper
+ def_exception :ErrUndefinedNotifier,
+ "undefined notifier level: %d is specified"
+ def_exception :ErrUnrecognizedLevel,
+ "unrecognized notifier level: %s is specified"
+
+ # Define a new Notifier output source, returning a new CompositeNotifier
+ # with the given +prefix+ and +output_method+.
+ #
+ # The optional +prefix+ will be appended to all objects being inspected
+ # during output, using the given +output_method+ as the output source. If
+ # no +output_method+ is given, StdioOutputMethod will be used, and all
+ # expressions will be sent directly to STDOUT without any additional
+ # formatting.
+ def def_notifier(prefix = "", output_method = StdioOutputMethod.new)
+ CompositeNotifier.new(prefix, output_method)
+ end
+ module_function :def_notifier
+
+ # An abstract class, or superclass, for CompositeNotifier and
+ # LeveledNotifier to inherit. It provides several wrapper methods for the
+ # OutputMethod object used by the Notifier.
+ class AbstractNotifier
+ # Creates a new Notifier object
+ def initialize(prefix, base_notifier)
+ @prefix = prefix
+ @base_notifier = base_notifier
+ end
+
+ # The +prefix+ for this Notifier, which is appended to all objects being
+ # inspected during output.
+ attr_reader :prefix
+
+ # A wrapper method used to determine whether notifications are enabled.
+ #
+ # Defaults to +true+.
+ def notify?
+ true
+ end
+
+ # See OutputMethod#print for more detail.
+ def print(*opts)
+ @base_notifier.print prefix, *opts if notify?
+ end
+
+ # See OutputMethod#printn for more detail.
+ def printn(*opts)
+ @base_notifier.printn prefix, *opts if notify?
+ end
+
+ # See OutputMethod#printf for more detail.
+ def printf(format, *opts)
+ @base_notifier.printf(prefix + format, *opts) if notify?
+ end
+
+ # See OutputMethod#puts for more detail.
+ def puts(*objs)
+ if notify?
+ @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s})
+ end
+ end
+
+ # Same as #ppx, except it uses the #prefix given during object
+ # initialization.
+ # See OutputMethod#ppx for more detail.
+ def pp(*objs)
+ if notify?
+ @base_notifier.ppx @prefix, *objs
+ end
+ end
+
+ # Same as #pp, except it concatenates the given +prefix+ with the #prefix
+ # given during object initialization.
+ #
+ # See OutputMethod#ppx for more detail.
+ def ppx(prefix, *objs)
+ if notify?
+ @base_notifier.ppx @prefix+prefix, *objs
+ end
+ end
+
+ # Execute the given block if notifications are enabled.
+ def exec_if
+ yield(@base_notifier) if notify?
+ end
+ end
+
+ # A class that can be used to create a group of notifier objects with the
+ # intent of representing a leveled notification system for irb.
+ #
+ # This class will allow you to generate other notifiers, and assign them
+ # the appropriate level for output.
+ #
+ # The Notifier class provides a class-method Notifier.def_notifier to
+ # create a new composite notifier. Using the first composite notifier
+ # object you create, sibling notifiers can be initialized with
+ # #def_notifier.
+ class CompositeNotifier<AbstractNotifier
+ # Create a new composite notifier object with the given +prefix+, and
+ # +base_notifier+ to use for output.
+ def initialize(prefix, base_notifier)
+ super
+
+ @notifiers = [D_NOMSG]
+ @level_notifier = D_NOMSG
+ end
+
+ # List of notifiers in the group
+ attr_reader :notifiers
+
+ # Creates a new LeveledNotifier in the composite #notifiers group.
+ #
+ # The given +prefix+ will be assigned to the notifier, and +level+ will
+ # be used as the index of the #notifiers Array.
+ #
+ # This method returns the newly created instance.
+ def def_notifier(level, prefix = "")
+ notifier = LeveledNotifier.new(self, level, prefix)
+ @notifiers[level] = notifier
+ notifier
+ end
+
+ # Returns the leveled notifier for this object
+ attr_reader :level_notifier
+ alias level level_notifier
+
+ # Sets the leveled notifier for this object.
+ #
+ # When the given +value+ is an instance of AbstractNotifier,
+ # #level_notifier is set to the given object.
+ #
+ # When an Integer is given, #level_notifier is set to the notifier at the
+ # index +value+ in the #notifiers Array.
+ #
+ # If no notifier exists at the index +value+ in the #notifiers Array, an
+ # ErrUndefinedNotifier exception is raised.
+ #
+ # An ErrUnrecognizedLevel exception is raised if the given +value+ is not
+ # found in the existing #notifiers Array, or an instance of
+ # AbstractNotifier
+ def level_notifier=(value)
+ case value
+ when AbstractNotifier
+ @level_notifier = value
+ when Integer
+ l = @notifiers[value]
+ Notifier.Raise ErrUndefinedNotifier, value unless l
+ @level_notifier = l
+ else
+ Notifier.Raise ErrUnrecognizedLevel, value unless l
+ end
+ end
+
+ alias level= level_notifier=
+ end
+
+ # A leveled notifier is comparable to the composite group from
+ # CompositeNotifier#notifiers.
+ class LeveledNotifier<AbstractNotifier
+ include Comparable
+
+ # Create a new leveled notifier with the given +base+, and +prefix+ to
+ # send to AbstractNotifier.new
+ #
+ # The given +level+ is used to compare other leveled notifiers in the
+ # CompositeNotifier group to determine whether or not to output
+ # notifications.
+ def initialize(base, level, prefix)
+ super(prefix, base)
+
+ @level = level
+ end
+
+ # The current level of this notifier object
+ attr_reader :level
+
+ # Compares the level of this notifier object with the given +other+
+ # notifier.
+ #
+ # See the Comparable module for more information.
+ def <=>(other)
+ @level <=> other.level
+ end
+
+ # Whether to output messages to the output method, depending on the level
+ # of this notifier object.
+ def notify?
+ @base_notifier.level >= self
+ end
+ end
+
+ # NoMsgNotifier is a LeveledNotifier that's used as the default notifier
+ # when creating a new CompositeNotifier.
+ #
+ # This notifier is used as the +zero+ index, or level +0+, for
+ # CompositeNotifier#notifiers, and will not output messages of any sort.
+ class NoMsgNotifier<LeveledNotifier
+ # Creates a new notifier that should not be used to output messages.
+ def initialize
+ @base_notifier = nil
+ @level = 0
+ @prefix = ""
+ end
+
+ # Ensures notifications are ignored, see AbstractNotifier#notify? for
+ # more information.
+ def notify?
+ false
+ end
+ end
+
+ D_NOMSG = NoMsgNotifier.new # :nodoc:
+ end
+end
diff --git a/jni/ruby/lib/irb/output-method.rb b/jni/ruby/lib/irb/output-method.rb
new file mode 100644
index 0000000..41d397b
--- /dev/null
+++ b/jni/ruby/lib/irb/output-method.rb
@@ -0,0 +1,91 @@
+#
+# output-method.rb - output methods used by irb
+# $Release Version: 0.9.6$
+# $Revision: 47120 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "e2mmap"
+
+module IRB
+ # An abstract output class for IO in irb. This is mainly used internally by
+ # IRB::Notifier. You can define your own output method to use with Irb.new,
+ # or Context.new
+ class OutputMethod
+ extend Exception2MessageMapper
+ def_exception :NotImplementedError, "Need to define `%s'"
+
+
+ # Open this method to implement your own output method, raises a
+ # NotImplementedError if you don't define #print in your own class.
+ def print(*opts)
+ OutputMethod.Raise NotImplementedError, "print"
+ end
+
+ # Prints the given +opts+, with a newline delimiter.
+ def printn(*opts)
+ print opts.join(" "), "\n"
+ end
+
+ # Extends IO#printf to format the given +opts+ for Kernel#sprintf using
+ # #parse_printf_format
+ def printf(format, *opts)
+ if /(%*)%I/ =~ format
+ format, opts = parse_printf_format(format, opts)
+ end
+ print sprintf(format, *opts)
+ end
+
+ # Returns an array of the given +format+ and +opts+ to be used by
+ # Kernel#sprintf, if there was a successful Regexp match in the given
+ # +format+ from #printf
+ #
+ # %
+ # <flag> [#0- +]
+ # <minimum field width> (\*|\*[1-9][0-9]*\$|[1-9][0-9]*)
+ # <precision>.(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)?
+ # #<length modifier>(hh|h|l|ll|L|q|j|z|t)
+ # <conversion specifier>[diouxXeEfgGcsb%]
+ def parse_printf_format(format, opts)
+ return format, opts if $1.size % 2 == 1
+ end
+
+ # Calls #print on each element in the given +objs+, followed by a newline
+ # character.
+ def puts(*objs)
+ for obj in objs
+ print(*obj)
+ print "\n"
+ end
+ end
+
+ # Prints the given +objs+ calling Object#inspect on each.
+ #
+ # See #puts for more detail.
+ def pp(*objs)
+ puts(*objs.collect{|obj| obj.inspect})
+ end
+
+ # Prints the given +objs+ calling Object#inspect on each and appending the
+ # given +prefix+.
+ #
+ # See #puts for more detail.
+ def ppx(prefix, *objs)
+ puts(*objs.collect{|obj| prefix+obj.inspect})
+ end
+
+ end
+
+ # A standard output printer
+ class StdioOutputMethod<OutputMethod
+ # Prints the given +opts+ to standard output, see IO#print for more
+ # information.
+ def print(*opts)
+ STDOUT.print(*opts)
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/ruby-lex.rb b/jni/ruby/lib/irb/ruby-lex.rb
new file mode 100644
index 0000000..584883f
--- /dev/null
+++ b/jni/ruby/lib/irb/ruby-lex.rb
@@ -0,0 +1,1170 @@
+#
+# irb/ruby-lex.rb - ruby lexcal analyzer
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "e2mmap"
+require "irb/slex"
+require "irb/ruby-token"
+
+# :stopdoc:
+class RubyLex
+
+ extend Exception2MessageMapper
+ def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
+ def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
+ def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
+ def_exception(:TkReading2TokenDuplicateError,
+ "key duplicate(token_n='%s', key='%s')")
+ def_exception(:SyntaxError, "%s")
+
+ def_exception(:TerminateLineInput, "Terminate Line Input")
+
+ include RubyToken
+
+ class << self
+ attr_accessor :debug_level
+ def debug?
+ @debug_level > 0
+ end
+ end
+ @debug_level = 0
+
+ def initialize
+ lex_init
+ set_input(STDIN)
+
+ @seek = 0
+ @exp_line_no = @line_no = 1
+ @base_char_no = 0
+ @char_no = 0
+ @rests = []
+ @readed = []
+ @here_readed = []
+
+ @indent = 0
+ @indent_stack = []
+ @lex_state = EXPR_BEG
+ @space_seen = false
+ @here_header = false
+ @post_symbeg = false
+
+ @continue = false
+ @line = ""
+
+ @skip_space = false
+ @readed_auto_clean_up = false
+ @exception_on_syntax_error = true
+
+ @prompt = nil
+ end
+
+ attr_accessor :skip_space
+ attr_accessor :readed_auto_clean_up
+ attr_accessor :exception_on_syntax_error
+
+ attr_reader :seek
+ attr_reader :char_no
+ attr_reader :line_no
+ attr_reader :indent
+
+ # io functions
+ def set_input(io, p = nil, &block)
+ @io = io
+ if p.respond_to?(:call)
+ @input = p
+ elsif block_given?
+ @input = block
+ else
+ @input = Proc.new{@io.gets}
+ end
+ end
+
+ def get_readed
+ if idx = @readed.rindex("\n")
+ @base_char_no = @readed.size - (idx + 1)
+ else
+ @base_char_no += @readed.size
+ end
+
+ readed = @readed.join("")
+ @readed = []
+ readed
+ end
+
+ def getc
+ while @rests.empty?
+ @rests.push nil unless buf_input
+ end
+ c = @rests.shift
+ if @here_header
+ @here_readed.push c
+ else
+ @readed.push c
+ end
+ @seek += 1
+ if c == "\n"
+ @line_no += 1
+ @char_no = 0
+ else
+ @char_no += 1
+ end
+ c
+ end
+
+ def gets
+ l = ""
+ while c = getc
+ l.concat(c)
+ break if c == "\n"
+ end
+ return nil if l == "" and c.nil?
+ l
+ end
+
+ def eof?
+ @io.eof?
+ end
+
+ def getc_of_rests
+ if @rests.empty?
+ nil
+ else
+ getc
+ end
+ end
+
+ def ungetc(c = nil)
+ if @here_readed.empty?
+ c2 = @readed.pop
+ else
+ c2 = @here_readed.pop
+ end
+ c = c2 unless c
+ @rests.unshift c #c =
+ @seek -= 1
+ if c == "\n"
+ @line_no -= 1
+ if idx = @readed.rindex("\n")
+ @char_no = idx + 1
+ else
+ @char_no = @base_char_no + @readed.size
+ end
+ else
+ @char_no -= 1
+ end
+ end
+
+ def peek_equal?(str)
+ chrs = str.split(//)
+ until @rests.size >= chrs.size
+ return false unless buf_input
+ end
+ @rests[0, chrs.size] == chrs
+ end
+
+ def peek_match?(regexp)
+ while @rests.empty?
+ return false unless buf_input
+ end
+ regexp =~ @rests.join("")
+ end
+
+ def peek(i = 0)
+ while @rests.size <= i
+ return nil unless buf_input
+ end
+ @rests[i]
+ end
+
+ def buf_input
+ prompt
+ line = @input.call
+ return nil unless line
+ @rests.concat line.chars.to_a
+ true
+ end
+ private :buf_input
+
+ def set_prompt(p = nil, &block)
+ p = block if block_given?
+ if p.respond_to?(:call)
+ @prompt = p
+ else
+ @prompt = Proc.new{print p}
+ end
+ end
+
+ def prompt
+ if @prompt
+ @prompt.call(@ltype, @indent, @continue, @line_no)
+ end
+ end
+
+ def initialize_input
+ @ltype = nil
+ @quoted = nil
+ @indent = 0
+ @indent_stack = []
+ @lex_state = EXPR_BEG
+ @space_seen = false
+ @here_header = false
+
+ @continue = false
+ @post_symbeg = false
+
+ prompt
+
+ @line = ""
+ @exp_line_no = @line_no
+ end
+
+ def each_top_level_statement
+ initialize_input
+ catch(:TERM_INPUT) do
+ loop do
+ begin
+ @continue = false
+ prompt
+ unless l = lex
+ throw :TERM_INPUT if @line == ''
+ else
+ @line.concat l
+ if @ltype or @continue or @indent > 0
+ next
+ end
+ end
+ if @line != "\n"
+ @line.force_encoding(@io.encoding)
+ yield @line, @exp_line_no
+ end
+ break unless l
+ @line = ''
+ @exp_line_no = @line_no
+
+ @indent = 0
+ @indent_stack = []
+ prompt
+ rescue TerminateLineInput
+ initialize_input
+ prompt
+ get_readed
+ end
+ end
+ end
+ end
+
+ def lex
+ until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&
+ !@continue or
+ tk.nil?)
+ end
+ line = get_readed
+ if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
+ nil
+ else
+ line
+ end
+ end
+
+ def token
+ @prev_seek = @seek
+ @prev_line_no = @line_no
+ @prev_char_no = @char_no
+ begin
+ begin
+ tk = @OP.match(self)
+ @space_seen = tk.kind_of?(TkSPACE)
+ @lex_state = EXPR_END if @post_symbeg && tk.kind_of?(TkOp)
+ @post_symbeg = tk.kind_of?(TkSYMBEG)
+ rescue SyntaxError
+ raise if @exception_on_syntax_error
+ tk = TkError.new(@seek, @line_no, @char_no)
+ end
+ end while @skip_space and tk.kind_of?(TkSPACE)
+ if @readed_auto_clean_up
+ get_readed
+ end
+ tk
+ end
+
+ ENINDENT_CLAUSE = [
+ "case", "class", "def", "do", "for", "if",
+ "module", "unless", "until", "while", "begin"
+ ]
+ DEINDENT_CLAUSE = ["end"
+ ]
+
+ PERCENT_LTYPE = {
+ "q" => "\'",
+ "Q" => "\"",
+ "x" => "\`",
+ "r" => "/",
+ "w" => "]",
+ "W" => "]",
+ "i" => "]",
+ "I" => "]",
+ "s" => ":"
+ }
+
+ PERCENT_PAREN = {
+ "{" => "}",
+ "[" => "]",
+ "<" => ">",
+ "(" => ")"
+ }
+
+ Ltype2Token = {
+ "\'" => TkSTRING,
+ "\"" => TkSTRING,
+ "\`" => TkXSTRING,
+ "/" => TkREGEXP,
+ "]" => TkDSTRING,
+ ":" => TkSYMBOL
+ }
+ DLtype2Token = {
+ "\"" => TkDSTRING,
+ "\`" => TkDXSTRING,
+ "/" => TkDREGEXP,
+ }
+
+ def lex_init()
+ @OP = IRB::SLex.new
+ @OP.def_rules("\0", "\004", "\032") do |op, io|
+ Token(TkEND_OF_SCRIPT)
+ end
+
+ @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io|
+ @space_seen = true
+ while getc =~ /[ \t\f\r\13]/; end
+ ungetc
+ Token(TkSPACE)
+ end
+
+ @OP.def_rule("#") do |op, io|
+ identify_comment
+ end
+
+ @OP.def_rule("=begin",
+ proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do
+ |op, io|
+ @ltype = "="
+ until getc == "\n"; end
+ until peek_equal?("=end") && peek(4) =~ /\s/
+ until getc == "\n"; end
+ end
+ gets
+ @ltype = nil
+ Token(TkRD_COMMENT)
+ end
+
+ @OP.def_rule("\n") do |op, io|
+ print "\\n\n" if RubyLex.debug?
+ case @lex_state
+ when EXPR_BEG, EXPR_FNAME, EXPR_DOT
+ @continue = true
+ else
+ @continue = false
+ @lex_state = EXPR_BEG
+ until (@indent_stack.empty? ||
+ [TkLPAREN, TkLBRACK, TkLBRACE,
+ TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
+ @indent_stack.pop
+ end
+ end
+ @here_header = false
+ @here_readed = []
+ Token(TkNL)
+ end
+
+ @OP.def_rules("*", "**",
+ "=", "==", "===",
+ "=~", "<=>",
+ "<", "<=",
+ ">", ">=", ">>",
+ "!", "!=", "!~") do
+ |op, io|
+ case @lex_state
+ when EXPR_FNAME, EXPR_DOT
+ @lex_state = EXPR_ARG
+ else
+ @lex_state = EXPR_BEG
+ end
+ Token(op)
+ end
+
+ @OP.def_rules("<<") do
+ |op, io|
+ tk = nil
+ if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
+ (@lex_state != EXPR_ARG || @space_seen)
+ c = peek(0)
+ if /\S/ =~ c && (/["'`]/ =~ c || /\w/ =~ c || c == "-")
+ tk = identify_here_document
+ end
+ end
+ unless tk
+ tk = Token(op)
+ case @lex_state
+ when EXPR_FNAME, EXPR_DOT
+ @lex_state = EXPR_ARG
+ else
+ @lex_state = EXPR_BEG
+ end
+ end
+ tk
+ end
+
+ @OP.def_rules("'", '"') do
+ |op, io|
+ identify_string(op)
+ end
+
+ @OP.def_rules("`") do
+ |op, io|
+ if @lex_state == EXPR_FNAME
+ @lex_state = EXPR_END
+ Token(op)
+ else
+ identify_string(op)
+ end
+ end
+
+ @OP.def_rules('?') do
+ |op, io|
+ if @lex_state == EXPR_END
+ @lex_state = EXPR_BEG
+ Token(TkQUESTION)
+ else
+ ch = getc
+ if @lex_state == EXPR_ARG && ch =~ /\s/
+ ungetc
+ @lex_state = EXPR_BEG;
+ Token(TkQUESTION)
+ else
+ if (ch == '\\')
+ read_escape
+ end
+ @lex_state = EXPR_END
+ Token(TkINTEGER)
+ end
+ end
+ end
+
+ @OP.def_rules("&", "&&", "|", "||") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token(op)
+ end
+
+ @OP.def_rules("+=", "-=", "*=", "**=",
+ "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ op =~ /^(.*)=$/
+ Token(TkOPASGN, $1)
+ end
+
+ @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do
+ |op, io|
+ @lex_state = EXPR_ARG
+ Token(op)
+ end
+
+ @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do
+ |op, io|
+ @lex_state = EXPR_ARG
+ Token(op)
+ end
+
+ @OP.def_rules("+", "-") do
+ |op, io|
+ catch(:RET) do
+ if @lex_state == EXPR_ARG
+ if @space_seen and peek(0) =~ /[0-9]/
+ throw :RET, identify_number
+ else
+ @lex_state = EXPR_BEG
+ end
+ elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
+ throw :RET, identify_number
+ else
+ @lex_state = EXPR_BEG
+ end
+ Token(op)
+ end
+ end
+
+ @OP.def_rule(".") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ if peek(0) =~ /[0-9]/
+ ungetc
+ identify_number
+ else
+ # for "obj.if" etc.
+ @lex_state = EXPR_DOT
+ Token(TkDOT)
+ end
+ end
+
+ @OP.def_rules("..", "...") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token(op)
+ end
+
+ lex_int2
+ end
+
+ def lex_int2
+ @OP.def_rules("]", "}", ")") do
+ |op, io|
+ @lex_state = EXPR_END
+ @indent -= 1
+ @indent_stack.pop
+ Token(op)
+ end
+
+ @OP.def_rule(":") do
+ |op, io|
+ if @lex_state == EXPR_END || peek(0) =~ /\s/
+ @lex_state = EXPR_BEG
+ Token(TkCOLON)
+ else
+ @lex_state = EXPR_FNAME
+ Token(TkSYMBEG)
+ end
+ end
+
+ @OP.def_rule("::") do
+ |op, io|
+ if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
+ @lex_state = EXPR_BEG
+ Token(TkCOLON3)
+ else
+ @lex_state = EXPR_DOT
+ Token(TkCOLON2)
+ end
+ end
+
+ @OP.def_rule("/") do
+ |op, io|
+ if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
+ identify_string(op)
+ elsif peek(0) == '='
+ getc
+ @lex_state = EXPR_BEG
+ Token(TkOPASGN, "/") #/)
+ elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
+ identify_string(op)
+ else
+ @lex_state = EXPR_BEG
+ Token("/") #/)
+ end
+ end
+
+ @OP.def_rules("^") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token("^")
+ end
+
+ @OP.def_rules(",") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token(op)
+ end
+
+ @OP.def_rules(";") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ until (@indent_stack.empty? ||
+ [TkLPAREN, TkLBRACK, TkLBRACE,
+ TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
+ @indent_stack.pop
+ end
+ Token(op)
+ end
+
+ @OP.def_rule("~") do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token("~")
+ end
+
+ @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do
+ |op, io|
+ @lex_state = EXPR_BEG
+ Token("~")
+ end
+
+ @OP.def_rule("(") do
+ |op, io|
+ @indent += 1
+ if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
+ @lex_state = EXPR_BEG
+ tk_c = TkfLPAREN
+ else
+ @lex_state = EXPR_BEG
+ tk_c = TkLPAREN
+ end
+ @indent_stack.push tk_c
+ Token(tk_c)
+ end
+
+ @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do
+ |op, io|
+ @lex_state = EXPR_ARG
+ Token("[]")
+ end
+
+ @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do
+ |op, io|
+ @lex_state = EXPR_ARG
+ Token("[]=")
+ end
+
+ @OP.def_rule("[") do
+ |op, io|
+ @indent += 1
+ if @lex_state == EXPR_FNAME
+ tk_c = TkfLBRACK
+ else
+ if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
+ tk_c = TkLBRACK
+ elsif @lex_state == EXPR_ARG && @space_seen
+ tk_c = TkLBRACK
+ else
+ tk_c = TkfLBRACK
+ end
+ @lex_state = EXPR_BEG
+ end
+ @indent_stack.push tk_c
+ Token(tk_c)
+ end
+
+ @OP.def_rule("{") do
+ |op, io|
+ @indent += 1
+ if @lex_state != EXPR_END && @lex_state != EXPR_ARG
+ tk_c = TkLBRACE
+ else
+ tk_c = TkfLBRACE
+ end
+ @lex_state = EXPR_BEG
+ @indent_stack.push tk_c
+ Token(tk_c)
+ end
+
+ @OP.def_rule('\\') do
+ |op, io|
+ if getc == "\n"
+ @space_seen = true
+ @continue = true
+ Token(TkSPACE)
+ else
+ read_escape
+ Token("\\")
+ end
+ end
+
+ @OP.def_rule('%') do
+ |op, io|
+ if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
+ identify_quotation
+ elsif peek(0) == '='
+ getc
+ Token(TkOPASGN, :%)
+ elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
+ identify_quotation
+ else
+ @lex_state = EXPR_BEG
+ Token("%") #))
+ end
+ end
+
+ @OP.def_rule('$') do
+ |op, io|
+ identify_gvar
+ end
+
+ @OP.def_rule('@') do
+ |op, io|
+ if peek(0) =~ /[\w@]/
+ ungetc
+ identify_identifier
+ else
+ Token("@")
+ end
+ end
+
+ @OP.def_rule("") do
+ |op, io|
+ printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
+ if peek(0) =~ /[0-9]/
+ t = identify_number
+ elsif peek(0) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
+ t = identify_identifier
+ end
+ printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
+ t
+ end
+
+ p @OP if RubyLex.debug?
+ end
+
+ def identify_gvar
+ @lex_state = EXPR_END
+
+ case ch = getc
+ when /[~_*$?!@\/\\;,=:<>".]/ #"
+ Token(TkGVAR, "$" + ch)
+ when "-"
+ Token(TkGVAR, "$-" + getc)
+ when "&", "`", "'", "+"
+ Token(TkBACK_REF, "$"+ch)
+ when /[1-9]/
+ while getc =~ /[0-9]/; end
+ ungetc
+ Token(TkNTH_REF)
+ when /\w/
+ ungetc
+ ungetc
+ identify_identifier
+ else
+ ungetc
+ Token("$")
+ end
+ end
+
+ def identify_identifier
+ token = ""
+ if peek(0) =~ /[$@]/
+ token.concat(c = getc)
+ if c == "@" and peek(0) == "@"
+ token.concat getc
+ end
+ end
+
+ while (ch = getc) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
+ print ":", ch, ":" if RubyLex.debug?
+ token.concat ch
+ end
+ ungetc
+
+ if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "="
+ token.concat getc
+ end
+
+ # almost fix token
+
+ case token
+ when /^\$/
+ return Token(TkGVAR, token)
+ when /^\@\@/
+ @lex_state = EXPR_END
+ # p Token(TkCVAR, token)
+ return Token(TkCVAR, token)
+ when /^\@/
+ @lex_state = EXPR_END
+ return Token(TkIVAR, token)
+ end
+
+ if @lex_state != EXPR_DOT
+ print token, "\n" if RubyLex.debug?
+
+ token_c, *trans = TkReading2Token[token]
+ if token_c
+ # reserved word?
+
+ if (@lex_state != EXPR_BEG &&
+ @lex_state != EXPR_FNAME &&
+ trans[1])
+ # modifiers
+ token_c = TkSymbol2Token[trans[1]]
+ @lex_state = trans[0]
+ else
+ if @lex_state != EXPR_FNAME
+ if ENINDENT_CLAUSE.include?(token)
+ # check for ``class = val'' etc.
+ valid = true
+ case token
+ when "class"
+ valid = false unless peek_match?(/^\s*(<<|\w|::)/)
+ when "def"
+ valid = false if peek_match?(/^\s*(([+\-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/)
+ when "do"
+ valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&)/)
+ when *ENINDENT_CLAUSE
+ valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&|\|)/)
+ else
+ # no nothing
+ end
+ if valid
+ if token == "do"
+ if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last)
+ @indent += 1
+ @indent_stack.push token_c
+ end
+ else
+ @indent += 1
+ @indent_stack.push token_c
+ end
+ end
+
+ elsif DEINDENT_CLAUSE.include?(token)
+ @indent -= 1
+ @indent_stack.pop
+ end
+ @lex_state = trans[0]
+ else
+ @lex_state = EXPR_END
+ end
+ end
+ return Token(token_c, token)
+ end
+ end
+
+ if @lex_state == EXPR_FNAME
+ @lex_state = EXPR_END
+ if peek(0) == '='
+ token.concat getc
+ end
+ elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
+ @lex_state = EXPR_ARG
+ else
+ @lex_state = EXPR_END
+ end
+
+ if token[0, 1] =~ /[A-Z]/
+ return Token(TkCONSTANT, token)
+ elsif token[token.size - 1, 1] =~ /[!?]/
+ return Token(TkFID, token)
+ else
+ return Token(TkIDENTIFIER, token)
+ end
+ end
+
+ def identify_here_document
+ ch = getc
+ if ch == "-"
+ ch = getc
+ indent = true
+ end
+ if /['"`]/ =~ ch
+ lt = ch
+ quoted = ""
+ while (c = getc) && c != lt
+ quoted.concat c
+ end
+ else
+ lt = '"'
+ quoted = ch.dup
+ while (c = getc) && c =~ /\w/
+ quoted.concat c
+ end
+ ungetc
+ end
+
+ ltback, @ltype = @ltype, lt
+ reserve = []
+ while ch = getc
+ reserve.push ch
+ if ch == "\\"
+ reserve.push ch = getc
+ elsif ch == "\n"
+ break
+ end
+ end
+
+ @here_header = false
+
+ line = ""
+ while ch = getc
+ if ch == "\n"
+ if line == quoted
+ break
+ end
+ line = ""
+ else
+ line.concat ch unless indent && line == "" && /\s/ =~ ch
+ if @ltype != "'" && ch == "#" && peek(0) == "{"
+ identify_string_dvar
+ end
+ end
+ end
+
+ @here_header = true
+ @here_readed.concat reserve
+ while ch = reserve.pop
+ ungetc ch
+ end
+
+ @ltype = ltback
+ @lex_state = EXPR_END
+ Token(Ltype2Token[lt])
+ end
+
+ def identify_quotation
+ ch = getc
+ if lt = PERCENT_LTYPE[ch]
+ ch = getc
+ elsif ch =~ /\W/
+ lt = "\""
+ else
+ RubyLex.fail SyntaxError, "unknown type of %string"
+ end
+ @quoted = ch unless @quoted = PERCENT_PAREN[ch]
+ identify_string(lt, @quoted)
+ end
+
+ def identify_number
+ @lex_state = EXPR_END
+
+ if peek(0) == "0" && peek(1) !~ /[.eE]/
+ getc
+ case peek(0)
+ when /[xX]/
+ ch = getc
+ match = /[0-9a-fA-F_]/
+ when /[bB]/
+ ch = getc
+ match = /[01_]/
+ when /[oO]/
+ ch = getc
+ match = /[0-7_]/
+ when /[dD]/
+ ch = getc
+ match = /[0-9_]/
+ when /[0-7]/
+ match = /[0-7_]/
+ when /[89]/
+ RubyLex.fail SyntaxError, "Invalid octal digit"
+ else
+ return Token(TkINTEGER)
+ end
+
+ len0 = true
+ non_digit = false
+ while ch = getc
+ if match =~ ch
+ if ch == "_"
+ if non_digit
+ RubyLex.fail SyntaxError, "trailing `#{ch}' in number"
+ else
+ non_digit = ch
+ end
+ else
+ non_digit = false
+ len0 = false
+ end
+ else
+ ungetc
+ if len0
+ RubyLex.fail SyntaxError, "numeric literal without digits"
+ end
+ if non_digit
+ RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ end
+ break
+ end
+ end
+ return Token(TkINTEGER)
+ end
+
+ type = TkINTEGER
+ allow_point = true
+ allow_e = true
+ non_digit = false
+ while ch = getc
+ case ch
+ when /[0-9]/
+ non_digit = false
+ when "_"
+ non_digit = ch
+ when allow_point && "."
+ if non_digit
+ RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ end
+ type = TkFLOAT
+ if peek(0) !~ /[0-9]/
+ type = TkINTEGER
+ ungetc
+ break
+ end
+ allow_point = false
+ when allow_e && "e", allow_e && "E"
+ if non_digit
+ RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ end
+ type = TkFLOAT
+ if peek(0) =~ /[+-]/
+ getc
+ end
+ allow_e = false
+ allow_point = false
+ non_digit = ch
+ else
+ if non_digit
+ RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number"
+ end
+ ungetc
+ break
+ end
+ end
+ Token(type)
+ end
+
+ def identify_string(ltype, quoted = ltype)
+ @ltype = ltype
+ @quoted = quoted
+ subtype = nil
+ begin
+ nest = 0
+ while ch = getc
+ if @quoted == ch and nest == 0
+ break
+ elsif @ltype != "'" && ch == "#" && peek(0) == "{"
+ identify_string_dvar
+ elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#"
+ subtype = true
+ elsif ch == '\\' and @ltype == "'" #'
+ case ch = getc
+ when "\\", "\n", "'"
+ else
+ ungetc
+ end
+ elsif ch == '\\' #'
+ read_escape
+ end
+ if PERCENT_PAREN.values.include?(@quoted)
+ if PERCENT_PAREN[ch] == @quoted
+ nest += 1
+ elsif ch == @quoted
+ nest -= 1
+ end
+ end
+ end
+ if @ltype == "/"
+ while /[imxoesun]/ =~ peek(0)
+ getc
+ end
+ end
+ if subtype
+ Token(DLtype2Token[ltype])
+ else
+ Token(Ltype2Token[ltype])
+ end
+ ensure
+ @ltype = nil
+ @quoted = nil
+ @lex_state = EXPR_END
+ end
+ end
+
+ def identify_string_dvar
+ begin
+ getc
+
+ reserve_continue = @continue
+ reserve_ltype = @ltype
+ reserve_indent = @indent
+ reserve_indent_stack = @indent_stack
+ reserve_state = @lex_state
+ reserve_quoted = @quoted
+
+ @ltype = nil
+ @quoted = nil
+ @indent = 0
+ @indent_stack = []
+ @lex_state = EXPR_BEG
+
+ loop do
+ @continue = false
+ prompt
+ tk = token
+ if @ltype or @continue or @indent >= 0
+ next
+ end
+ break if tk.kind_of?(TkRBRACE)
+ end
+ ensure
+ @continue = reserve_continue
+ @ltype = reserve_ltype
+ @indent = reserve_indent
+ @indent_stack = reserve_indent_stack
+ @lex_state = reserve_state
+ @quoted = reserve_quoted
+ end
+ end
+
+ def identify_comment
+ @ltype = "#"
+
+ while ch = getc
+ if ch == "\n"
+ @ltype = nil
+ ungetc
+ break
+ end
+ end
+ return Token(TkCOMMENT)
+ end
+
+ def read_escape
+ case ch = getc
+ when "\n", "\r", "\f"
+ when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #"
+ when /[0-7]/
+ ungetc ch
+ 3.times do
+ case ch = getc
+ when /[0-7]/
+ when nil
+ break
+ else
+ ungetc
+ break
+ end
+ end
+
+ when "x"
+ 2.times do
+ case ch = getc
+ when /[0-9a-fA-F]/
+ when nil
+ break
+ else
+ ungetc
+ break
+ end
+ end
+
+ when "M"
+ if (ch = getc) != '-'
+ ungetc
+ else
+ if (ch = getc) == "\\" #"
+ read_escape
+ end
+ end
+
+ when "C", "c" #, "^"
+ if ch == "C" and (ch = getc) != "-"
+ ungetc
+ elsif (ch = getc) == "\\" #"
+ read_escape
+ end
+ else
+ # other characters
+ end
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/ruby-token.rb b/jni/ruby/lib/irb/ruby-token.rb
new file mode 100644
index 0000000..cb95955
--- /dev/null
+++ b/jni/ruby/lib/irb/ruby-token.rb
@@ -0,0 +1,266 @@
+#
+# irb/ruby-token.rb - ruby tokens
+# $Release Version: 0.9.6$
+# $Revision: 47298 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+# :stopdoc:
+module RubyToken
+ EXPR_BEG = :EXPR_BEG
+ EXPR_MID = :EXPR_MID
+ EXPR_END = :EXPR_END
+ EXPR_ARG = :EXPR_ARG
+ EXPR_FNAME = :EXPR_FNAME
+ EXPR_DOT = :EXPR_DOT
+ EXPR_CLASS = :EXPR_CLASS
+
+ class Token
+ def initialize(seek, line_no, char_no)
+ @seek = seek
+ @line_no = line_no
+ @char_no = char_no
+ end
+ attr_reader :seek, :line_no, :char_no
+ end
+
+ class TkNode < Token
+ def initialize(seek, line_no, char_no)
+ super
+ end
+ attr_reader :node
+ end
+
+ class TkId < Token
+ def initialize(seek, line_no, char_no, name)
+ super(seek, line_no, char_no)
+ @name = name
+ end
+ attr_reader :name
+ end
+
+ class TkVal < Token
+ def initialize(seek, line_no, char_no, value = nil)
+ super(seek, line_no, char_no)
+ @value = value
+ end
+ attr_reader :value
+ end
+
+ class TkOp < Token
+ attr_accessor :name
+ end
+
+ class TkOPASGN < TkOp
+ def initialize(seek, line_no, char_no, op)
+ super(seek, line_no, char_no)
+ op = TkReading2Token[op][0] unless op.kind_of?(Symbol)
+ @op = op
+ end
+ attr_reader :op
+ end
+
+ class TkUnknownChar < Token
+ def initialize(seek, line_no, char_no, id)
+ super(seek, line_no, char_no)
+ @name = name
+ end
+ attr_reader :name
+ end
+
+ class TkError < Token
+ end
+
+ def Token(token, value = nil)
+ case token
+ when String
+ if (tk = TkReading2Token[token]).nil?
+ IRB.fail TkReading2TokenNoKey, token
+ end
+ tk = Token(tk[0], value)
+ if tk.kind_of?(TkOp)
+ tk.name = token
+ end
+ return tk
+ when Symbol
+ if (tk = TkSymbol2Token[token]).nil?
+ IRB.fail TkSymbol2TokenNoKey, token
+ end
+ return Token(tk[0], value)
+ else
+ if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
+ token.new(@prev_seek, @prev_line_no, @prev_char_no)
+ else
+ token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
+ end
+ end
+ end
+
+ TokenDefinitions = [
+ [:TkCLASS, TkId, "class", EXPR_CLASS],
+ [:TkMODULE, TkId, "module", EXPR_BEG],
+ [:TkDEF, TkId, "def", EXPR_FNAME],
+ [:TkUNDEF, TkId, "undef", EXPR_FNAME],
+ [:TkBEGIN, TkId, "begin", EXPR_BEG],
+ [:TkRESCUE, TkId, "rescue", EXPR_MID],
+ [:TkENSURE, TkId, "ensure", EXPR_BEG],
+ [:TkEND, TkId, "end", EXPR_END],
+ [:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD],
+ [:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD],
+ [:TkTHEN, TkId, "then", EXPR_BEG],
+ [:TkELSIF, TkId, "elsif", EXPR_BEG],
+ [:TkELSE, TkId, "else", EXPR_BEG],
+ [:TkCASE, TkId, "case", EXPR_BEG],
+ [:TkWHEN, TkId, "when", EXPR_BEG],
+ [:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD],
+ [:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD],
+ [:TkFOR, TkId, "for", EXPR_BEG],
+ [:TkBREAK, TkId, "break", EXPR_END],
+ [:TkNEXT, TkId, "next", EXPR_END],
+ [:TkREDO, TkId, "redo", EXPR_END],
+ [:TkRETRY, TkId, "retry", EXPR_END],
+ [:TkIN, TkId, "in", EXPR_BEG],
+ [:TkDO, TkId, "do", EXPR_BEG],
+ [:TkRETURN, TkId, "return", EXPR_MID],
+ [:TkYIELD, TkId, "yield", EXPR_END],
+ [:TkSUPER, TkId, "super", EXPR_END],
+ [:TkSELF, TkId, "self", EXPR_END],
+ [:TkNIL, TkId, "nil", EXPR_END],
+ [:TkTRUE, TkId, "true", EXPR_END],
+ [:TkFALSE, TkId, "false", EXPR_END],
+ [:TkAND, TkId, "and", EXPR_BEG],
+ [:TkOR, TkId, "or", EXPR_BEG],
+ [:TkNOT, TkId, "not", EXPR_BEG],
+ [:TkIF_MOD, TkId],
+ [:TkUNLESS_MOD, TkId],
+ [:TkWHILE_MOD, TkId],
+ [:TkUNTIL_MOD, TkId],
+ [:TkALIAS, TkId, "alias", EXPR_FNAME],
+ [:TkDEFINED, TkId, "defined?", EXPR_END],
+ [:TklBEGIN, TkId, "BEGIN", EXPR_END],
+ [:TklEND, TkId, "END", EXPR_END],
+ [:Tk__LINE__, TkId, "__LINE__", EXPR_END],
+ [:Tk__FILE__, TkId, "__FILE__", EXPR_END],
+
+ [:TkIDENTIFIER, TkId],
+ [:TkFID, TkId],
+ [:TkGVAR, TkId],
+ [:TkCVAR, TkId],
+ [:TkIVAR, TkId],
+ [:TkCONSTANT, TkId],
+
+ [:TkINTEGER, TkVal],
+ [:TkFLOAT, TkVal],
+ [:TkSTRING, TkVal],
+ [:TkXSTRING, TkVal],
+ [:TkREGEXP, TkVal],
+ [:TkSYMBOL, TkVal],
+
+ [:TkDSTRING, TkNode],
+ [:TkDXSTRING, TkNode],
+ [:TkDREGEXP, TkNode],
+ [:TkNTH_REF, TkNode],
+ [:TkBACK_REF, TkNode],
+
+ [:TkUPLUS, TkOp, "+@"],
+ [:TkUMINUS, TkOp, "-@"],
+ [:TkPOW, TkOp, "**"],
+ [:TkCMP, TkOp, "<=>"],
+ [:TkEQ, TkOp, "=="],
+ [:TkEQQ, TkOp, "==="],
+ [:TkNEQ, TkOp, "!="],
+ [:TkGEQ, TkOp, ">="],
+ [:TkLEQ, TkOp, "<="],
+ [:TkANDOP, TkOp, "&&"],
+ [:TkOROP, TkOp, "||"],
+ [:TkMATCH, TkOp, "=~"],
+ [:TkNMATCH, TkOp, "!~"],
+ [:TkDOT2, TkOp, ".."],
+ [:TkDOT3, TkOp, "..."],
+ [:TkAREF, TkOp, "[]"],
+ [:TkASET, TkOp, "[]="],
+ [:TkLSHFT, TkOp, "<<"],
+ [:TkRSHFT, TkOp, ">>"],
+ [:TkCOLON2, TkOp],
+ [:TkCOLON3, TkOp],
+ [:TkASSOC, TkOp, "=>"],
+ [:TkQUESTION, TkOp, "?"], #?
+ [:TkCOLON, TkOp, ":"], #:
+
+ [:TkfLPAREN], # func( #
+ [:TkfLBRACK], # func[ #
+ [:TkfLBRACE], # func{ #
+ [:TkSTAR], # *arg
+ [:TkAMPER], # &arg #
+ [:TkSYMBEG], # :SYMBOL
+
+ [:TkGT, TkOp, ">"],
+ [:TkLT, TkOp, "<"],
+ [:TkPLUS, TkOp, "+"],
+ [:TkMINUS, TkOp, "-"],
+ [:TkMULT, TkOp, "*"],
+ [:TkDIV, TkOp, "/"],
+ [:TkMOD, TkOp, "%"],
+ [:TkBITOR, TkOp, "|"],
+ [:TkBITXOR, TkOp, "^"],
+ [:TkBITAND, TkOp, "&"],
+ [:TkBITNOT, TkOp, "~"],
+ [:TkNOTOP, TkOp, "!"],
+
+ [:TkBACKQUOTE, TkOp, "`"],
+
+ [:TkASSIGN, Token, "="],
+ [:TkDOT, Token, "."],
+ [:TkLPAREN, Token, "("], #(exp)
+ [:TkLBRACK, Token, "["], #[arry]
+ [:TkLBRACE, Token, "{"], #{hash}
+ [:TkRPAREN, Token, ")"],
+ [:TkRBRACK, Token, "]"],
+ [:TkRBRACE, Token, "}"],
+ [:TkCOMMA, Token, ","],
+ [:TkSEMICOLON, Token, ";"],
+
+ [:TkCOMMENT],
+ [:TkRD_COMMENT],
+ [:TkSPACE],
+ [:TkNL],
+ [:TkEND_OF_SCRIPT],
+
+ [:TkBACKSLASH, TkUnknownChar, "\\"],
+ [:TkAT, TkUnknownChar, "@"],
+ [:TkDOLLAR, TkUnknownChar, "$"],
+ ]
+
+ # {reading => token_class}
+ # {reading => [token_class, *opt]}
+ TkReading2Token = {}
+ TkSymbol2Token = {}
+
+ def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
+ token_n = token_n.id2name if token_n.kind_of?(Symbol)
+ if RubyToken.const_defined?(token_n)
+ IRB.fail AlreadyDefinedToken, token_n
+ end
+ token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
+
+ if reading
+ if TkReading2Token[reading]
+ IRB.fail TkReading2TokenDuplicateError, token_n, reading
+ end
+ if opts.empty?
+ TkReading2Token[reading] = [token_c]
+ else
+ TkReading2Token[reading] = [token_c].concat(opts)
+ end
+ end
+ TkSymbol2Token[token_n.intern] = token_c
+ end
+
+ for defs in TokenDefinitions
+ def_token(*defs)
+ end
+end
+# :startdoc:
diff --git a/jni/ruby/lib/irb/slex.rb b/jni/ruby/lib/irb/slex.rb
new file mode 100644
index 0000000..54429cf
--- /dev/null
+++ b/jni/ruby/lib/irb/slex.rb
@@ -0,0 +1,281 @@
+#
+# irb/slex.rb - simple lex analyzer
+# $Release Version: 0.9.6$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+require "e2mmap"
+require "irb/notifier"
+
+# :stopdoc:
+module IRB
+ class SLex
+
+ extend Exception2MessageMapper
+ def_exception :ErrNodeNothing, "node nothing"
+ def_exception :ErrNodeAlreadyExists, "node already exists"
+
+ DOUT = Notifier::def_notifier("SLex::")
+ D_WARN = DOUT::def_notifier(1, "Warn: ")
+ D_DEBUG = DOUT::def_notifier(2, "Debug: ")
+ D_DETAIL = DOUT::def_notifier(4, "Detail: ")
+
+ DOUT.level = Notifier::D_NOMSG
+
+ def initialize
+ @head = Node.new("")
+ end
+
+ def def_rule(token, preproc = nil, postproc = nil, &block)
+ D_DETAIL.pp token
+
+ postproc = block if block_given?
+ create(token, preproc, postproc)
+ end
+
+ def def_rules(*tokens, &block)
+ if block_given?
+ p = block
+ end
+ for token in tokens
+ def_rule(token, nil, p)
+ end
+ end
+
+ def preproc(token, proc)
+ node = search(token)
+ node.preproc=proc
+ end
+
+ #$BMW%A%'%C%/(B?
+ def postproc(token)
+ node = search(token, proc)
+ node.postproc=proc
+ end
+
+ def search(token)
+ @head.search(token.split(//))
+ end
+
+ def create(token, preproc = nil, postproc = nil)
+ @head.create_subnode(token.split(//), preproc, postproc)
+ end
+
+ def match(token)
+ case token
+ when Array
+ when String
+ return match(token.split(//))
+ else
+ return @head.match_io(token)
+ end
+ ret = @head.match(token)
+ D_DETAIL.exec_if{D_DETAIL.printf "match end: %s:%s\n", ret, token.inspect}
+ ret
+ end
+
+ def inspect
+ format("<SLex: @head = %s>", @head.inspect)
+ end
+
+ #----------------------------------------------------------------------
+ #
+ # class Node -
+ #
+ #----------------------------------------------------------------------
+ class Node
+ # if postproc is nil, this node is an abstract node.
+ # if postproc is non-nil, this node is a real node.
+ def initialize(preproc = nil, postproc = nil)
+ @Tree = {}
+ @preproc = preproc
+ @postproc = postproc
+ end
+
+ attr_accessor :preproc
+ attr_accessor :postproc
+
+ def search(chrs, opt = nil)
+ return self if chrs.empty?
+ ch = chrs.shift
+ if node = @Tree[ch]
+ node.search(chrs, opt)
+ else
+ if opt
+ chrs.unshift ch
+ self.create_subnode(chrs)
+ else
+ SLex.fail ErrNodeNothing
+ end
+ end
+ end
+
+ def create_subnode(chrs, preproc = nil, postproc = nil)
+ if chrs.empty?
+ if @postproc
+ D_DETAIL.pp node
+ SLex.fail ErrNodeAlreadyExists
+ else
+ D_DEBUG.puts "change abstract node to real node."
+ @preproc = preproc
+ @postproc = postproc
+ end
+ return self
+ end
+
+ ch = chrs.shift
+ if node = @Tree[ch]
+ if chrs.empty?
+ if node.postproc
+ DebugLogger.pp node
+ DebugLogger.pp self
+ DebugLogger.pp ch
+ DebugLogger.pp chrs
+ SLex.fail ErrNodeAlreadyExists
+ else
+ D_WARN.puts "change abstract node to real node"
+ node.preproc = preproc
+ node.postproc = postproc
+ end
+ else
+ node.create_subnode(chrs, preproc, postproc)
+ end
+ else
+ if chrs.empty?
+ node = Node.new(preproc, postproc)
+ else
+ node = Node.new
+ node.create_subnode(chrs, preproc, postproc)
+ end
+ @Tree[ch] = node
+ end
+ node
+ end
+
+ #
+ # chrs: String
+ # character array
+ # io must have getc()/ungetc(); and ungetc() must be
+ # able to be called arbitrary number of times.
+ #
+ def match(chrs, op = "")
+ D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
+ if chrs.empty?
+ if @preproc.nil? || @preproc.call(op, chrs)
+ DOUT.printf(D_DETAIL, "op1: %s\n", op)
+ @postproc.call(op, chrs)
+ else
+ nil
+ end
+ else
+ ch = chrs.shift
+ if node = @Tree[ch]
+ if ret = node.match(chrs, op+ch)
+ return ret
+ else
+ chrs.unshift ch
+ if @postproc and @preproc.nil? || @preproc.call(op, chrs)
+ DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
+ ret = @postproc.call(op, chrs)
+ return ret
+ else
+ return nil
+ end
+ end
+ else
+ chrs.unshift ch
+ if @postproc and @preproc.nil? || @preproc.call(op, chrs)
+ DOUT.printf(D_DETAIL, "op3: %s\n", op)
+ @postproc.call(op, chrs)
+ return ""
+ else
+ return nil
+ end
+ end
+ end
+ end
+
+ def match_io(io, op = "")
+ if op == ""
+ ch = io.getc
+ if ch == nil
+ return nil
+ end
+ else
+ ch = io.getc_of_rests
+ end
+ if ch.nil?
+ if @preproc.nil? || @preproc.call(op, io)
+ D_DETAIL.printf("op1: %s\n", op)
+ @postproc.call(op, io)
+ else
+ nil
+ end
+ else
+ if node = @Tree[ch]
+ if ret = node.match_io(io, op+ch)
+ ret
+ else
+ io.ungetc ch
+ if @postproc and @preproc.nil? || @preproc.call(op, io)
+ DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
+ @postproc.call(op, io)
+ else
+ nil
+ end
+ end
+ else
+ io.ungetc ch
+ if @postproc and @preproc.nil? || @preproc.call(op, io)
+ D_DETAIL.printf("op3: %s\n", op)
+ @postproc.call(op, io)
+ else
+ nil
+ end
+ end
+ end
+ end
+ end
+ end
+end
+# :startdoc:
+
+if $0 == __FILE__
+ case $1
+ when "1"
+ tr = SLex.new
+ print "0: ", tr.inspect, "\n"
+ tr.def_rule("=") {print "=\n"}
+ print "1: ", tr.inspect, "\n"
+ tr.def_rule("==") {print "==\n"}
+ print "2: ", tr.inspect, "\n"
+
+ print "case 1:\n"
+ print tr.match("="), "\n"
+ print "case 2:\n"
+ print tr.match("=="), "\n"
+ print "case 3:\n"
+ print tr.match("=>"), "\n"
+
+ when "2"
+ tr = SLex.new
+ print "0: ", tr.inspect, "\n"
+ tr.def_rule("=") {print "=\n"}
+ print "1: ", tr.inspect, "\n"
+ tr.def_rule("==", proc{false}) {print "==\n"}
+ print "2: ", tr.inspect, "\n"
+
+ print "case 1:\n"
+ print tr.match("="), "\n"
+ print "case 2:\n"
+ print tr.match("=="), "\n"
+ print "case 3:\n"
+ print tr.match("=>"), "\n"
+ end
+ exit
+end
diff --git a/jni/ruby/lib/irb/src_encoding.rb b/jni/ruby/lib/irb/src_encoding.rb
new file mode 100644
index 0000000..958cef1
--- /dev/null
+++ b/jni/ruby/lib/irb/src_encoding.rb
@@ -0,0 +1,4 @@
+# DO NOT WRITE ANY MAGIC COMMENT HERE.
+def default_src_encoding
+ return __ENCODING__
+end
diff --git a/jni/ruby/lib/irb/version.rb b/jni/ruby/lib/irb/version.rb
new file mode 100644
index 0000000..a0e556e
--- /dev/null
+++ b/jni/ruby/lib/irb/version.rb
@@ -0,0 +1,15 @@
+#
+# irb/version.rb - irb version definition file
+# $Release Version: 0.9.6$
+# $Revision: 38358 $
+# by Keiju ISHITSUKA(keiju@ishitsuka.com)
+#
+# --
+#
+#
+#
+
+module IRB # :nodoc:
+ @RELEASE_VERSION = "0.9.6"
+ @LAST_UPDATE_DATE = "09/06/30"
+end
diff --git a/jni/ruby/lib/irb/workspace.rb b/jni/ruby/lib/irb/workspace.rb
new file mode 100644
index 0000000..b7eb810
--- /dev/null
+++ b/jni/ruby/lib/irb/workspace.rb
@@ -0,0 +1,114 @@
+#
+# irb/workspace-binding.rb -
+# $Release Version: 0.9.6$
+# $Revision: 47112 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+module IRB # :nodoc:
+ class WorkSpace
+ # Creates a new workspace.
+ #
+ # set self to main if specified, otherwise
+ # inherit main from TOPLEVEL_BINDING.
+ def initialize(*main)
+ if main[0].kind_of?(Binding)
+ @binding = main.shift
+ elsif 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 # binding in function on TOPLEVEL_BINDING(default)
+ @binding = eval("def irb_binding; private; 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 CantChangeBinding, @main.inspect
+ end
+ end
+ end
+ eval("_=nil", @binding)
+ end
+
+ # The Binding of this workspace
+ attr_reader :binding
+ # The top-level workspace of this context, also available as
+ # <code>IRB.conf[:__MAIN__]</code>
+ attr_reader :main
+
+ # Evaluate the given +statements+ within the context of this workspace.
+ def evaluate(context, statements, file = __FILE__, line = __LINE__)
+ eval(statements, @binding, file, line)
+ end
+
+ # error message manipulator
+ 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/
+ return nil if bt =~ /irb\.rb/
+ when 3
+ return nil if bt =~ /irb\/.*\.rb/
+ return nil if bt =~ /irb\.rb/
+ bt = bt.sub(/:\s*in `irb_binding'/, '')
+ end
+ bt
+ end
+
+ def IRB.delete_caller
+ end
+ end
+end
diff --git a/jni/ruby/lib/irb/ws-for-case-2.rb b/jni/ruby/lib/irb/ws-for-case-2.rb
new file mode 100644
index 0000000..a70183e
--- /dev/null
+++ b/jni/ruby/lib/irb/ws-for-case-2.rb
@@ -0,0 +1,14 @@
+#
+# irb/ws-for-case-2.rb -
+# $Release Version: 0.9.6$
+# $Revision: 29726 $
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
+#
+# --
+#
+#
+#
+
+while true
+ IRB::BINDING_QUEUE.push _ = binding
+end
diff --git a/jni/ruby/lib/irb/xmp.rb b/jni/ruby/lib/irb/xmp.rb
new file mode 100644
index 0000000..395a562
--- /dev/null
+++ b/jni/ruby/lib/irb/xmp.rb
@@ -0,0 +1,169 @@
+#
+# xmp.rb - irb version of gotoken xmp
+# $Release Version: 0.9$
+# $Revision: 47266 $
+# by Keiju ISHITSUKA(Nippon Rational Inc.)
+#
+# --
+#
+#
+#
+
+require "irb"
+require "irb/frame"
+
+# An example printer for irb.
+#
+# It's much like the standard library PrettyPrint, that shows the value of each
+# expression as it runs.
+#
+# In order to use this library, you must first require it:
+#
+# require 'irb/xmp'
+#
+# Now, you can take advantage of the Object#xmp convenience method.
+#
+# xmp <<END
+# foo = "bar"
+# baz = 42
+# END
+# #=> foo = "bar"
+# #==>"bar"
+# #=> baz = 42
+# #==>42
+#
+# You can also create an XMP object, with an optional binding to print
+# expressions in the given binding:
+#
+# ctx = binding
+# x = XMP.new ctx
+# x.puts
+# #=> today = "a good day"
+# #==>"a good day"
+# ctx.eval 'today # is what?'
+# #=> "a good day"
+class XMP
+
+ # Creates a new XMP object.
+ #
+ # The top-level binding or, optional +bind+ parameter will be used when
+ # creating the workspace. See WorkSpace.new for more information.
+ #
+ # This uses the +:XMP+ prompt mode, see IRB@Customizing+the+IRB+Prompt for
+ # full detail.
+ def initialize(bind = nil)
+ IRB.init_config(nil)
+
+ IRB.conf[:PROMPT_MODE] = :XMP
+
+ bind = IRB::Frame.top(1) unless bind
+ ws = IRB::WorkSpace.new(bind)
+ @io = StringInputMethod.new
+ @irb = IRB::Irb.new(ws, @io)
+ @irb.context.ignore_sigint = false
+
+ IRB.conf[:MAIN_CONTEXT] = @irb.context
+ end
+
+ # Evaluates the given +exps+, for example:
+ #
+ # require 'irb/xmp'
+ # x = XMP.new
+ #
+ # x.puts '{:a => 1, :b => 2, :c => 3}'
+ # #=> {:a => 1, :b => 2, :c => 3}
+ # # ==>{:a=>1, :b=>2, :c=>3}
+ # x.puts 'foo = "bar"'
+ # # => foo = "bar"
+ # # ==>"bar"
+ def puts(exps)
+ @io.puts exps
+
+ if @irb.context.ignore_sigint
+ begin
+ trap_proc_b = trap("SIGINT"){@irb.signal_handle}
+ catch(:IRB_EXIT) do
+ @irb.eval_input
+ end
+ ensure
+ trap("SIGINT", trap_proc_b)
+ end
+ else
+ catch(:IRB_EXIT) do
+ @irb.eval_input
+ end
+ end
+ end
+
+ # A custom InputMethod class used by XMP for evaluating string io.
+ class StringInputMethod < IRB::InputMethod
+ # Creates a new StringInputMethod object
+ def initialize
+ super
+ @exps = []
+ end
+
+ # Whether there are any expressions left in this printer.
+ def eof?
+ @exps.empty?
+ end
+
+ # Reads the next expression from this printer.
+ #
+ # See IO#gets for more information.
+ def gets
+ while l = @exps.shift
+ next if /^\s+$/ =~ l
+ l.concat "\n"
+ print @prompt, l
+ break
+ end
+ l
+ end
+
+ # Concatenates all expressions in this printer, separated by newlines.
+ #
+ # An Encoding::CompatibilityError is raised of the given +exps+'s encoding
+ # doesn't match the previous expression evaluated.
+ def puts(exps)
+ if @encoding and exps.encoding != @encoding
+ enc = Encoding.compatible?(@exps.join("\n"), exps)
+ if enc.nil?
+ raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one"
+ else
+ @encoding = enc
+ end
+ else
+ @encoding = exps.encoding
+ end
+ @exps.concat exps.split(/\n/)
+ end
+
+ # Returns the encoding of last expression printed by #puts.
+ attr_reader :encoding
+ end
+end
+
+# A convenience method that's only available when the you require the IRB::XMP standard library.
+#
+# Creates a new XMP object, using the given expressions as the +exps+
+# parameter, and optional binding as +bind+ or uses the top-level binding. Then
+# evaluates the given expressions using the +:XMP+ prompt mode.
+#
+# For example:
+#
+# require 'irb/xmp'
+# ctx = binding
+# xmp 'foo = "bar"', ctx
+# #=> foo = "bar"
+# #==>"bar"
+# ctx.eval 'foo'
+# #=> "bar"
+#
+# See XMP.new for more information.
+def xmp(exps, bind = nil)
+ bind = IRB::Frame.top(1) unless bind
+ xmp = XMP.new(bind)
+ xmp.puts exps
+ xmp
+end