1#
2#   irb/init.rb - irb initialize module
3#   	$Release Version: 0.9.6$
4#   	$Revision: 38620 $
5#   	by Keiju ISHITSUKA(keiju@ruby-lang.org)
6#
7# --
8#
9#
10#
11
12module IRB # :nodoc:
13
14  # initialize config
15  def IRB.setup(ap_path)
16    IRB.init_config(ap_path)
17    IRB.init_error
18    IRB.parse_opts
19    IRB.run_config
20    IRB.load_modules
21
22    unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
23      IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
24    end
25  end
26
27  # @CONF default setting
28  def IRB.init_config(ap_path)
29    # class instance variables
30    @TRACER_INITIALIZED = false
31
32    # default configurations
33    unless ap_path and @CONF[:AP_NAME]
34      ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
35    end
36    @CONF[:AP_NAME] = File::basename(ap_path, ".rb")
37
38    @CONF[:IRB_NAME] = "irb"
39    @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)
40
41    @CONF[:RC] = true
42    @CONF[:LOAD_MODULES] = []
43    @CONF[:IRB_RC] = nil
44
45    @CONF[:MATH_MODE] = false
46    @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
47    @CONF[:INSPECT_MODE] = true
48    @CONF[:USE_TRACER] = false
49    @CONF[:USE_LOADER] = false
50    @CONF[:IGNORE_SIGINT] = true
51    @CONF[:IGNORE_EOF] = false
52    @CONF[:ECHO] = nil
53    @CONF[:VERBOSE] = nil
54
55    @CONF[:EVAL_HISTORY] = nil
56    @CONF[:SAVE_HISTORY] = nil
57
58    @CONF[:BACK_TRACE_LIMIT] = 16
59
60    @CONF[:PROMPT] = {
61      :NULL => {
62	:PROMPT_I => nil,
63	:PROMPT_N => nil,
64	:PROMPT_S => nil,
65	:PROMPT_C => nil,
66	:RETURN => "%s\n"
67      },
68      :DEFAULT => {
69	:PROMPT_I => "%N(%m):%03n:%i> ",
70	:PROMPT_N => "%N(%m):%03n:%i> ",
71	:PROMPT_S => "%N(%m):%03n:%i%l ",
72	:PROMPT_C => "%N(%m):%03n:%i* ",
73	:RETURN => "=> %s\n"
74      },
75      :CLASSIC => {
76	:PROMPT_I => "%N(%m):%03n:%i> ",
77	:PROMPT_N => "%N(%m):%03n:%i> ",
78	:PROMPT_S => "%N(%m):%03n:%i%l ",
79	:PROMPT_C => "%N(%m):%03n:%i* ",
80	:RETURN => "%s\n"
81      },
82      :SIMPLE => {
83	:PROMPT_I => ">> ",
84	:PROMPT_N => ">> ",
85	:PROMPT_S => nil,
86	:PROMPT_C => "?> ",
87	:RETURN => "=> %s\n"
88      },
89      :INF_RUBY => {
90	:PROMPT_I => "%N(%m):%03n:%i> ",
91#	:PROMPT_N => "%N(%m):%03n:%i> ",
92	:PROMPT_N => nil,
93	:PROMPT_S => nil,
94	:PROMPT_C => nil,
95	:RETURN => "%s\n",
96	:AUTO_INDENT => true
97      },
98      :XMP => {
99	:PROMPT_I => nil,
100	:PROMPT_N => nil,
101	:PROMPT_S => nil,
102	:PROMPT_C => nil,
103	:RETURN => "    ==>%s\n"
104      }
105    }
106
107    @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
108    @CONF[:AUTO_INDENT] = false
109
110    @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
111    @CONF[:SINGLE_IRB] = false
112
113#    @CONF[:LC_MESSAGES] = "en"
114    @CONF[:LC_MESSAGES] = Locale.new
115
116    @CONF[:AT_EXIT] = []
117
118    @CONF[:DEBUG_LEVEL] = 0
119  end
120
121  def IRB.init_error
122    @CONF[:LC_MESSAGES].load("irb/error.rb")
123  end
124
125  FEATURE_IOPT_CHANGE_VERSION = "1.9.0"
126
127  # option analyzing
128  def IRB.parse_opts
129    load_path = []
130    while opt = ARGV.shift
131      case opt
132      when "-f"
133	@CONF[:RC] = false
134      when "-m"
135	@CONF[:MATH_MODE] = true
136      when "-d"
137	$DEBUG = true
138	$VERBOSE = true
139      when "-w"
140	$VERBOSE = true
141      when /^-W(.+)?/
142	opt = $1 || ARGV.shift
143	case opt
144	when "0"
145	  $VERBOSE = nil
146	when "1"
147	  $VERBOSE = false
148	else
149	  $VERBOSE = true
150	end
151      when /^-r(.+)?/
152	opt = $1 || ARGV.shift
153	@CONF[:LOAD_MODULES].push opt if opt
154      when /^-I(.+)?/
155        opt = $1 || ARGV.shift
156	load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
157      when '-U'
158	set_encoding("UTF-8", "UTF-8")
159      when /^-E(.+)?/, /^--encoding(?:=(.+))?/
160	opt = $1 || ARGV.shift
161	set_encoding(*opt.split(':', 2))
162      when "--inspect"
163	if /^-/ !~ ARGV.first
164	  @CONF[:INSPECT_MODE] = ARGV.shift
165	else
166	  @CONF[:INSPECT_MODE] = true
167	end
168      when "--noinspect"
169	@CONF[:INSPECT_MODE] = false
170      when "--readline"
171	@CONF[:USE_READLINE] = true
172      when "--noreadline"
173	@CONF[:USE_READLINE] = false
174      when "--echo"
175	@CONF[:ECHO] = true
176      when "--noecho"
177	@CONF[:ECHO] = false
178      when "--verbose"
179	@CONF[:VERBOSE] = true
180      when "--noverbose"
181	@CONF[:VERBOSE] = false
182      when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
183	opt = $1 || ARGV.shift
184	prompt_mode = opt.upcase.tr("-", "_").intern
185	@CONF[:PROMPT_MODE] = prompt_mode
186      when "--noprompt"
187	@CONF[:PROMPT_MODE] = :NULL
188      when "--inf-ruby-mode"
189	@CONF[:PROMPT_MODE] = :INF_RUBY
190      when "--sample-book-mode", "--simple-prompt"
191	@CONF[:PROMPT_MODE] = :SIMPLE
192      when "--tracer"
193	@CONF[:USE_TRACER] = true
194      when /^--back-trace-limit(?:=(.+))?/
195	@CONF[:BACK_TRACE_LIMIT] = ($1 || ARGV.shift).to_i
196      when /^--context-mode(?:=(.+))?/
197	@CONF[:CONTEXT_MODE] = ($1 || ARGV.shift).to_i
198      when "--single-irb"
199	@CONF[:SINGLE_IRB] = true
200      when /^--irb_debug(?:=(.+))?/
201	@CONF[:DEBUG_LEVEL] = ($1 || ARGV.shift).to_i
202      when "-v", "--version"
203	print IRB.version, "\n"
204	exit 0
205      when "-h", "--help"
206	require "irb/help"
207	IRB.print_usage
208	exit 0
209      when "--"
210	if opt = ARGV.shift
211	  @CONF[:SCRIPT] = opt
212	  $0 = opt
213	end
214        break
215      when /^-/
216	IRB.fail UnrecognizedSwitch, opt
217      else
218	@CONF[:SCRIPT] = opt
219	$0 = opt
220	break
221      end
222    end
223    if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION
224      load_path.collect! do |path|
225	/\A\.\// =~ path ? path : File.expand_path(path)
226      end
227    end
228    $LOAD_PATH.unshift(*load_path)
229
230  end
231
232  # running config
233  def IRB.run_config
234    if @CONF[:RC]
235      begin
236	load rc_file
237      rescue LoadError, Errno::ENOENT
238      rescue # StandardError, ScriptError
239	print "load error: #{rc_file}\n"
240	print $!.class, ": ", $!, "\n"
241	for err in $@[0, $@.size - 2]
242	  print "\t", err, "\n"
243	end
244      end
245    end
246  end
247
248  IRBRC_EXT = "rc"
249  def IRB.rc_file(ext = IRBRC_EXT)
250    if !@CONF[:RC_NAME_GENERATOR]
251      rc_file_generators do |rcgen|
252	@CONF[:RC_NAME_GENERATOR] ||= rcgen
253	if File.exist?(rcgen.call(IRBRC_EXT))
254	  @CONF[:RC_NAME_GENERATOR] = rcgen
255	  break
256	end
257      end
258    end
259    case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
260    when String
261      return rc_file
262    else
263      IRB.fail IllegalRCNameGenerator
264    end
265  end
266
267  # enumerate possible rc-file base name generators
268  def IRB.rc_file_generators
269    if irbrc = ENV["IRBRC"]
270      yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
271    end
272    if home = ENV["HOME"]
273      yield proc{|rc| home+"/.irb#{rc}"}
274    end
275    home = Dir.pwd
276    yield proc{|rc| home+"/.irb#{rc}"}
277    yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
278    yield proc{|rc| home+"/_irb#{rc}"}
279    yield proc{|rc| home+"/$irb#{rc}"}
280  end
281
282  # loading modules
283  def IRB.load_modules
284    for m in @CONF[:LOAD_MODULES]
285      begin
286	require m
287      rescue LoadError => err
288	warn err.backtrace[0] << ":#{err.class}: #{err}"
289      end
290    end
291  end
292
293
294  DefaultEncodings = Struct.new(:external, :internal)
295  class << IRB
296    private
297    def set_encoding(extern, intern = nil)
298      verbose, $VERBOSE = $VERBOSE, nil
299      Encoding.default_external = extern unless extern.nil? || extern.empty?
300      Encoding.default_internal = intern unless intern.nil? || intern.empty?
301      @CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
302      [$stdin, $stdout, $stderr].each do |io|
303	io.set_encoding(extern, intern)
304      end
305      @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
306    ensure
307      $VERBOSE = verbose
308    end
309  end
310end
311