1 |
1 |
#
|
2 |
2 |
# irb.rb - irb main module
|
3 |
|
# $Release Version: 0.9.6 $
|
4 |
|
# $Revision$
|
5 |
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
|
3 |
# $Release Version: 0.9.6 $
|
|
4 |
# $Revision$
|
|
5 |
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
6 |
6 |
#
|
7 |
7 |
# --
|
8 |
8 |
#
|
... | ... | |
67 |
67 |
|
68 |
68 |
begin
|
69 |
69 |
catch(:IRB_EXIT) do
|
70 |
|
irb.eval_input
|
|
70 |
irb.eval_input
|
71 |
71 |
end
|
72 |
72 |
ensure
|
73 |
73 |
irb_at_exit
|
... | ... | |
107 |
107 |
attr_accessor :scanner
|
108 |
108 |
|
109 |
109 |
def eval_input
|
110 |
|
@scanner.set_prompt do
|
111 |
|
|ltype, indent, continue, line_no|
|
112 |
|
if ltype
|
113 |
|
f = @context.prompt_s
|
114 |
|
elsif continue
|
115 |
|
f = @context.prompt_c
|
116 |
|
elsif indent > 0
|
117 |
|
f = @context.prompt_n
|
118 |
|
else
|
119 |
|
f = @context.prompt_i
|
120 |
|
end
|
121 |
|
f = "" unless f
|
122 |
|
if @context.prompting?
|
123 |
|
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
124 |
|
else
|
125 |
|
@context.io.prompt = p = ""
|
126 |
|
end
|
127 |
|
if @context.auto_indent_mode
|
128 |
|
unless ltype
|
|
110 |
@scanner.set_prompt do |ltype, indent, continue, line_no|
|
|
111 |
if ltype
|
|
112 |
f = @context.prompt_s
|
|
113 |
elsif continue
|
|
114 |
f = @context.prompt_c
|
|
115 |
elsif indent > 0
|
|
116 |
f = @context.prompt_n
|
|
117 |
else
|
|
118 |
f = @context.prompt_i
|
|
119 |
end
|
|
120 |
f = "" unless f
|
|
121 |
if @context.prompting?
|
|
122 |
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
|
123 |
else
|
|
124 |
@context.io.prompt = p = ""
|
|
125 |
end
|
|
126 |
if @context.auto_indent_mode
|
|
127 |
unless ltype
|
129 |
128 |
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
130 |
|
indent * 2 - p.size
|
131 |
|
ind += 2 if continue
|
132 |
|
@context.io.prompt = p + " " * ind if ind > 0
|
133 |
|
end
|
134 |
|
end
|
|
129 |
indent * 2 - p.size
|
|
130 |
ind += 2 if continue
|
|
131 |
@context.io.prompt = p + " " * ind if ind > 0
|
|
132 |
end
|
|
133 |
end
|
135 |
134 |
end
|
136 |
135 |
|
137 |
136 |
@scanner.set_input(@context.io) do
|
138 |
|
signal_status(:IN_INPUT) do
|
139 |
|
if l = @context.io.gets
|
140 |
|
print l if @context.verbose?
|
141 |
|
else
|
142 |
|
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
143 |
|
l = "\n"
|
144 |
|
if @context.verbose?
|
145 |
|
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
146 |
|
end
|
147 |
|
else
|
148 |
|
print "\n"
|
149 |
|
end
|
150 |
|
end
|
151 |
|
l
|
152 |
|
end
|
|
137 |
signal_status(:IN_INPUT) do
|
|
138 |
if l = @context.io.gets
|
|
139 |
print l if @context.verbose?
|
|
140 |
else
|
|
141 |
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
|
142 |
l = "\n"
|
|
143 |
if @context.verbose?
|
|
144 |
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
|
145 |
end
|
|
146 |
else
|
|
147 |
print "\n"
|
|
148 |
end
|
|
149 |
end
|
|
150 |
l
|
|
151 |
end
|
153 |
152 |
end
|
154 |
153 |
|
155 |
154 |
@scanner.each_top_level_statement do |line, line_no|
|
156 |
|
signal_status(:IN_EVAL) do
|
157 |
|
begin
|
|
155 |
signal_status(:IN_EVAL) do
|
|
156 |
begin
|
158 |
157 |
line.untaint
|
159 |
|
@context.evaluate(line, line_no)
|
160 |
|
output_value if @context.echo?
|
161 |
|
exc = nil
|
162 |
|
rescue Interrupt => exc
|
163 |
|
rescue SystemExit, SignalException
|
164 |
|
raise
|
165 |
|
rescue Exception => exc
|
166 |
|
end
|
167 |
|
if exc
|
168 |
|
print exc.class, ": ", exc, "\n"
|
169 |
|
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
|
158 |
@context.evaluate(line, line_no)
|
|
159 |
output_value if @context.echo?
|
|
160 |
exc = nil
|
|
161 |
rescue Interrupt => exc
|
|
162 |
rescue SystemExit, SignalException
|
|
163 |
raise
|
|
164 |
rescue Exception => exc
|
|
165 |
end
|
|
166 |
if exc
|
|
167 |
print exc.class, ": ", exc, "\n"
|
|
168 |
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
170 |
169 |
!(SyntaxError === exc)
|
171 |
|
irb_bug = true
|
172 |
|
else
|
173 |
|
irb_bug = false
|
174 |
|
end
|
175 |
|
|
176 |
|
messages = []
|
177 |
|
lasts = []
|
178 |
|
levels = 0
|
179 |
|
for m in exc.backtrace
|
180 |
|
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
181 |
|
if m
|
182 |
|
if messages.size < @context.back_trace_limit
|
183 |
|
messages.push "\tfrom "+m
|
184 |
|
else
|
185 |
|
lasts.push "\tfrom "+m
|
186 |
|
if lasts.size > @context.back_trace_limit
|
187 |
|
lasts.shift
|
188 |
|
levels += 1
|
189 |
|
end
|
190 |
|
end
|
191 |
|
end
|
192 |
|
end
|
193 |
|
print messages.join("\n"), "\n"
|
194 |
|
unless lasts.empty?
|
195 |
|
printf "... %d levels...\n", levels if levels > 0
|
196 |
|
print lasts.join("\n")
|
197 |
|
end
|
198 |
|
print "Maybe IRB bug!\n" if irb_bug
|
199 |
|
end
|
|
170 |
irb_bug = true
|
|
171 |
else
|
|
172 |
irb_bug = false
|
|
173 |
end
|
|
174 |
|
|
175 |
messages = []
|
|
176 |
lasts = []
|
|
177 |
levels = 0
|
|
178 |
for m in exc.backtrace
|
|
179 |
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
|
180 |
if m
|
|
181 |
if messages.size < @context.back_trace_limit
|
|
182 |
messages.push "\tfrom "+m
|
|
183 |
else
|
|
184 |
lasts.push "\tfrom "+m
|
|
185 |
if lasts.size > @context.back_trace_limit
|
|
186 |
lasts.shift
|
|
187 |
levels += 1
|
|
188 |
end
|
|
189 |
end
|
|
190 |
end
|
|
191 |
end
|
|
192 |
print messages.join("\n"), "\n"
|
|
193 |
unless lasts.empty?
|
|
194 |
printf "... %d levels...\n", levels if levels > 0
|
|
195 |
print lasts.join("\n")
|
|
196 |
end
|
|
197 |
print "Maybe IRB bug!\n" if irb_bug
|
|
198 |
end
|
200 |
199 |
if $SAFE > 2
|
201 |
200 |
abort "Error: irb does not work for $SAFE level higher than 2"
|
202 |
201 |
end
|
203 |
|
end
|
|
202 |
end
|
204 |
203 |
end
|
205 |
204 |
end
|
206 |
205 |
|
... | ... | |
208 |
207 |
@context.irb_path, back_path = path, @context.irb_path if path
|
209 |
208 |
@context.irb_name, back_name = name, @context.irb_name if name
|
210 |
209 |
begin
|
211 |
|
yield back_path, back_name
|
|
210 |
yield back_path, back_name
|
212 |
211 |
ensure
|
213 |
|
@context.irb_path = back_path if path
|
214 |
|
@context.irb_name = back_name if name
|
|
212 |
@context.irb_path = back_path if path
|
|
213 |
@context.irb_name = back_name if name
|
215 |
214 |
end
|
216 |
215 |
end
|
217 |
216 |
|
218 |
217 |
def suspend_workspace(workspace)
|
219 |
218 |
@context.workspace, back_workspace = workspace, @context.workspace
|
220 |
219 |
begin
|
221 |
|
yield back_workspace
|
|
220 |
yield back_workspace
|
222 |
221 |
ensure
|
223 |
|
@context.workspace = back_workspace
|
|
222 |
@context.workspace = back_workspace
|
224 |
223 |
end
|
225 |
224 |
end
|
226 |
225 |
|
... | ... | |
228 |
227 |
back_io = @context.io
|
229 |
228 |
@context.instance_eval{@io = input_method}
|
230 |
229 |
begin
|
231 |
|
yield back_io
|
|
230 |
yield back_io
|
232 |
231 |
ensure
|
233 |
|
@context.instance_eval{@io = back_io}
|
|
232 |
@context.instance_eval{@io = back_io}
|
234 |
233 |
end
|
235 |
234 |
end
|
236 |
235 |
|
237 |
236 |
def suspend_context(context)
|
238 |
237 |
@context, back_context = context, @context
|
239 |
238 |
begin
|
240 |
|
yield back_context
|
|
239 |
yield back_context
|
241 |
240 |
ensure
|
242 |
|
@context = back_context
|
|
241 |
@context = back_context
|
243 |
242 |
end
|
244 |
243 |
end
|
245 |
244 |
|
246 |
245 |
def signal_handle
|
247 |
246 |
unless @context.ignore_sigint?
|
248 |
|
print "\nabort!\n" if @context.verbose?
|
249 |
|
exit
|
|
247 |
print "\nabort!\n" if @context.verbose?
|
|
248 |
exit
|
250 |
249 |
end
|
251 |
250 |
|
252 |
251 |
case @signal_status
|
253 |
252 |
when :IN_INPUT
|
254 |
|
print "^C\n"
|
255 |
|
raise RubyLex::TerminateLineInput
|
|
253 |
print "^C\n"
|
|
254 |
raise RubyLex::TerminateLineInput
|
256 |
255 |
when :IN_EVAL
|
257 |
|
IRB.irb_abort(self)
|
|
256 |
IRB.irb_abort(self)
|
258 |
257 |
when :IN_LOAD
|
259 |
|
IRB.irb_abort(self, LoadAbort)
|
|
258 |
IRB.irb_abort(self, LoadAbort)
|
260 |
259 |
when :IN_IRB
|
261 |
|
# ignore
|
|
260 |
# ignore
|
262 |
261 |
else
|
263 |
|
# ignore other cases as well
|
|
262 |
# ignore other cases as well
|
264 |
263 |
end
|
265 |
264 |
end
|
266 |
265 |
|
... | ... | |
270 |
269 |
signal_status_back = @signal_status
|
271 |
270 |
@signal_status = status
|
272 |
271 |
begin
|
273 |
|
yield
|
|
272 |
yield
|
274 |
273 |
ensure
|
275 |
|
@signal_status = signal_status_back
|
|
274 |
@signal_status = signal_status_back
|
276 |
275 |
end
|
277 |
276 |
end
|
278 |
277 |
|
279 |
278 |
def prompt(prompt, ltype, indent, line_no)
|
280 |
279 |
p = prompt.dup
|
281 |
280 |
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
282 |
|
case $2
|
283 |
|
when "N"
|
284 |
|
@context.irb_name
|
285 |
|
when "m"
|
286 |
|
@context.main.to_s
|
287 |
|
when "M"
|
288 |
|
@context.main.inspect
|
289 |
|
when "l"
|
290 |
|
ltype
|
291 |
|
when "i"
|
292 |
|
if $1
|
293 |
|
format("%" + $1 + "d", indent)
|
294 |
|
else
|
295 |
|
indent.to_s
|
296 |
|
end
|
297 |
|
when "n"
|
298 |
|
if $1
|
299 |
|
format("%" + $1 + "d", line_no)
|
300 |
|
else
|
301 |
|
line_no.to_s
|
302 |
|
end
|
303 |
|
when "%"
|
304 |
|
"%"
|
305 |
|
end
|
|
281 |
case $2
|
|
282 |
when "N"
|
|
283 |
@context.irb_name
|
|
284 |
when "m"
|
|
285 |
@context.main.to_s
|
|
286 |
when "M"
|
|
287 |
@context.main.inspect
|
|
288 |
when "l"
|
|
289 |
ltype
|
|
290 |
when "i"
|
|
291 |
if $1
|
|
292 |
format("%" + $1 + "d", indent)
|
|
293 |
else
|
|
294 |
indent.to_s
|
|
295 |
end
|
|
296 |
when "n"
|
|
297 |
if $1
|
|
298 |
format("%" + $1 + "d", line_no)
|
|
299 |
else
|
|
300 |
line_no.to_s
|
|
301 |
end
|
|
302 |
when "%"
|
|
303 |
"%"
|
|
304 |
end
|
306 |
305 |
end
|
307 |
306 |
p
|
308 |
307 |
end
|
... | ... | |
314 |
313 |
def inspect
|
315 |
314 |
ary = []
|
316 |
315 |
for iv in instance_variables
|
317 |
|
case (iv = iv.to_s)
|
318 |
|
when "@signal_status"
|
319 |
|
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
320 |
|
when "@context"
|
321 |
|
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
322 |
|
else
|
323 |
|
ary.push format("%s=%s", iv, eval(iv))
|
324 |
|
end
|
|
316 |
case (iv = iv.to_s)
|
|
317 |
when "@signal_status"
|
|
318 |
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
|
319 |
when "@context"
|
|
320 |
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
|
321 |
else
|
|
322 |
ary.push format("%s=%s", iv, eval(iv))
|
|
323 |
end
|
325 |
324 |
end
|
326 |
325 |
format("#<%s: %s>", self.class, ary.join(", "))
|
327 |
326 |
end
|
... | ... | |
335 |
334 |
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
336 |
335 |
case k
|
337 |
336 |
when :MAIN_CONTEXT, :__TMP__EHV__
|
338 |
|
array.push format("CONF[:%s]=...myself...", k.id2name)
|
|
337 |
array.push format("CONF[:%s]=...myself...", k.id2name)
|
339 |
338 |
when :PROMPT
|
340 |
|
s = v.collect{
|
341 |
|
|kk, vv|
|
342 |
|
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
343 |
|
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
344 |
|
}
|
345 |
|
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
|
339 |
s = v.collect{
|
|
340 |
|kk, vv|
|
|
341 |
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
|
342 |
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
|
343 |
}
|
|
344 |
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
346 |
345 |
else
|
347 |
|
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
|
346 |
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
348 |
347 |
end
|
349 |
348 |
end
|
350 |
349 |
array.join("\n")
|
351 |
|
-
|