ruby-debug 0.9.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +1 -0
- data/CHANGES +41 -0
- data/ChangeLog +0 -0
- data/README +27 -13
- data/Rakefile +220 -0
- data/bin/rdebug +116 -42
- data/cli/ruby-debug.rb +33 -3
- data/cli/ruby-debug/command.rb +49 -12
- data/cli/ruby-debug/commands/breakpoints.rb +47 -64
- data/cli/ruby-debug/commands/control.rb +41 -13
- data/cli/ruby-debug/commands/display.rb +35 -18
- data/cli/ruby-debug/commands/enable.rb +159 -0
- data/cli/ruby-debug/commands/eval.rb +78 -4
- data/cli/ruby-debug/commands/frame.rb +67 -42
- data/cli/ruby-debug/commands/help.rb +21 -17
- data/cli/ruby-debug/commands/info.rb +210 -0
- data/cli/ruby-debug/commands/irb.rb +9 -1
- data/cli/ruby-debug/commands/list.rb +11 -8
- data/cli/ruby-debug/commands/method.rb +12 -23
- data/cli/ruby-debug/commands/script.rb +14 -9
- data/cli/ruby-debug/commands/settings.rb +174 -39
- data/cli/ruby-debug/commands/show.rb +193 -0
- data/cli/ruby-debug/commands/stepping.rb +15 -10
- data/cli/ruby-debug/commands/threads.rb +55 -56
- data/cli/ruby-debug/commands/variables.rb +27 -27
- data/cli/ruby-debug/helper.rb +134 -0
- data/cli/ruby-debug/interface.rb +46 -15
- data/cli/ruby-debug/processor.rb +156 -25
- data/doc/rdebug.1 +236 -0
- data/runner.sh +7 -0
- data/test/breakpoints.cmd +43 -0
- data/test/breakpoints.right +94 -0
- data/test/display.cmd +18 -0
- data/test/display.right +37 -0
- data/test/frame.cmd +21 -0
- data/test/frame.right +45 -0
- data/test/gcd.rb +18 -0
- data/test/help.cmd +12 -0
- data/test/help.right +4 -0
- data/test/helper.rb +87 -0
- data/test/info-var-bug.rb +45 -0
- data/test/info-var.cmd +23 -0
- data/test/info-var.right +47 -0
- data/test/info.cmd +12 -0
- data/test/info.right +35 -0
- data/test/quit.cmd +9 -0
- data/test/quit.right +22 -0
- data/test/setshow.cmd +44 -0
- data/test/setshow.right +73 -0
- data/test/stepping.cmd +17 -0
- data/test/stepping.right +40 -0
- data/test/tdebug.rb +196 -0
- data/test/test-breakpoints.rb +28 -0
- data/test/test-columnize.rb +46 -0
- data/test/test-display.rb +26 -0
- data/test/test-frame.rb +27 -0
- data/test/test-help.rb +44 -0
- data/test/test-info-var.rb +33 -0
- data/test/test-info.rb +28 -0
- data/test/test-quit.rb +28 -0
- data/test/test-ruby-debug-base.rb +76 -0
- data/test/test-setshow.rb +24 -0
- data/test/test-stepping.rb +26 -0
- metadata +63 -22
data/cli/ruby-debug.rb
CHANGED
@@ -9,11 +9,25 @@ module Debugger
|
|
9
9
|
self.handler = CommandProcessor.new
|
10
10
|
|
11
11
|
# the port number used for remote debugging
|
12
|
-
PORT = 8989
|
12
|
+
PORT = 8989 unless defined?(PORT)
|
13
13
|
|
14
|
+
# What file is used for debugger startup commands.
|
15
|
+
unless defined?(INITFILE)
|
16
|
+
if RUBY_PLATFORM =~ /mswin/
|
17
|
+
# Of course MS Windows has to be different
|
18
|
+
INITFILE = 'rdebug.ini'
|
19
|
+
HOME_DIR = (ENV['HOME'] ||
|
20
|
+
ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
|
21
|
+
else
|
22
|
+
INITFILE = '.rdebugrc'
|
23
|
+
HOME_DIR = ENV['HOME'].to_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
14
27
|
class << self
|
15
28
|
# in remote mode, wait for the remote connection
|
16
29
|
attr_accessor :wait_connection
|
30
|
+
attr_accessor :annotate
|
17
31
|
|
18
32
|
attr_reader :thread, :control_thread
|
19
33
|
|
@@ -105,13 +119,29 @@ module Debugger
|
|
105
119
|
socket.close
|
106
120
|
end
|
107
121
|
|
122
|
+
# Runs normal debugger initialization scripts
|
123
|
+
# Reads and executes the commands from init file (if any) in the
|
124
|
+
# current working directory. This is only done if the current
|
125
|
+
# directory is different from your home directory. Thus, you can
|
126
|
+
# have more than one init file, one generic in your home directory,
|
127
|
+
# and another, specific to the program you are debugging, in the
|
128
|
+
# directory where you invoke ruby-debug.
|
129
|
+
def run_init_script(out = handler.interface)
|
130
|
+
cwd_script_file = File.expand_path(File.join(".", INITFILE))
|
131
|
+
run_script(cwd_script_file, out) if File.exists?(cwd_script_file)
|
132
|
+
|
133
|
+
home_script_file = File.expand_path(File.join(HOME_DIR, INITFILE))
|
134
|
+
run_script(home_script_file, out) if File.exists?(home_script_file) and
|
135
|
+
cwd_script_file != home_script_file
|
136
|
+
end
|
137
|
+
|
108
138
|
#
|
109
139
|
# Runs a script file
|
110
140
|
#
|
111
141
|
def run_script(file, out = handler.interface)
|
112
|
-
interface = ScriptInterface.new(file, out)
|
142
|
+
interface = ScriptInterface.new(File.expand_path(file), out)
|
113
143
|
processor = ControlCommandProcessor.new(interface)
|
114
144
|
processor.process_commands
|
115
145
|
end
|
116
146
|
end
|
117
|
-
end
|
147
|
+
end
|
data/cli/ruby-debug/command.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
require 'ruby-debug/helper'
|
2
|
+
|
1
3
|
module Debugger
|
4
|
+
|
2
5
|
class Command # :nodoc:
|
3
6
|
class << self
|
4
7
|
def commands
|
@@ -8,10 +11,10 @@ module Debugger
|
|
8
11
|
DEF_OPTIONS = {
|
9
12
|
:event => true,
|
10
13
|
:control => false,
|
11
|
-
:always_run =>
|
14
|
+
:always_run => 0,
|
12
15
|
:unknown => false,
|
13
16
|
:need_context => false,
|
14
|
-
}
|
17
|
+
} unless defined?(DEF_OPTIONS)
|
15
18
|
|
16
19
|
def inherited(klass)
|
17
20
|
DEF_OPTIONS.each do |o, v|
|
@@ -25,6 +28,9 @@ module Debugger
|
|
25
28
|
Dir[File.join(dir, 'commands', '*')].each do |file|
|
26
29
|
require file if file =~ /\.rb$/
|
27
30
|
end
|
31
|
+
Debugger.constants.grep(/Functions$/).map { |name| Debugger.const_get(name) }.each do |mod|
|
32
|
+
include mod
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
def method_missing(meth, *args, &block)
|
@@ -49,16 +55,32 @@ module Debugger
|
|
49
55
|
private :settings_map
|
50
56
|
|
51
57
|
def settings
|
52
|
-
unless @settings
|
58
|
+
unless true and defined? @settings and @settings
|
53
59
|
@settings = Object.new
|
54
60
|
map = settings_map
|
55
|
-
class << @settings; self end
|
56
|
-
|
57
|
-
|
61
|
+
c = class << @settings; self end
|
62
|
+
if c.respond_to?(:funcall)
|
63
|
+
c.funcall(:define_method, :[]) do |name|
|
64
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
65
|
+
map[name][:getter].call
|
66
|
+
end
|
67
|
+
else
|
68
|
+
c.send(:define_method, :[]) do |name|
|
69
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
70
|
+
map[name][:getter].call
|
71
|
+
end
|
58
72
|
end
|
59
|
-
class << @settings; self end
|
60
|
-
|
61
|
-
|
73
|
+
c = class << @settings; self end
|
74
|
+
if c.respond_to?(:funcall)
|
75
|
+
c.funcall(:define_method, :[]=) do |name, value|
|
76
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
77
|
+
map[name][:setter].call(value)
|
78
|
+
end
|
79
|
+
else
|
80
|
+
c.send(:define_method, :[]=) do |name, value|
|
81
|
+
raise "No such setting #{name}" unless map.has_key?(name)
|
82
|
+
map[name][:setter].call(value)
|
83
|
+
end
|
62
84
|
end
|
63
85
|
end
|
64
86
|
@settings
|
@@ -82,10 +104,25 @@ module Debugger
|
|
82
104
|
end
|
83
105
|
end
|
84
106
|
|
85
|
-
register_setting_var(:
|
86
|
-
register_setting_var(:
|
87
|
-
register_setting_var(:
|
107
|
+
register_setting_var(:basename, false) # use basename in showing files?
|
108
|
+
register_setting_var(:callstyle, :last)
|
109
|
+
register_setting_var(:debuggertesting, false)
|
88
110
|
register_setting_var(:force_stepping, false)
|
111
|
+
register_setting_var(:full_path, true)
|
112
|
+
register_setting_var(:listsize, 10) # number of lines in list command
|
113
|
+
register_setting_var(:stack_trace_on_error, false)
|
114
|
+
register_setting_var(:tracing_plus, false) # different linetrace lines?
|
115
|
+
|
116
|
+
# width of line output. Use COLUMNS value if it exists and is
|
117
|
+
# not too rediculously large.
|
118
|
+
width = ENV['COLUMNS'].to_i
|
119
|
+
width = 80 unless width > 10
|
120
|
+
register_setting_var(:width, width)
|
121
|
+
|
122
|
+
if not defined? Debugger::ARGV
|
123
|
+
Debugger::ARGV = ARGV.clone
|
124
|
+
end
|
125
|
+
register_setting_var(:argv, Debugger::ARGV)
|
89
126
|
|
90
127
|
def initialize(state)
|
91
128
|
@state = state
|
@@ -5,11 +5,11 @@ module Debugger
|
|
5
5
|
def regexp
|
6
6
|
/ ^\s*
|
7
7
|
b(?:reak)?
|
8
|
-
\s+
|
8
|
+
(?: \s+
|
9
9
|
(?:
|
10
10
|
(\d+) |
|
11
11
|
(.+?)[:.#]([^.:\s]+)
|
12
|
-
)
|
12
|
+
))?
|
13
13
|
(?:\s+
|
14
14
|
if\s+(.+)
|
15
15
|
)?
|
@@ -19,35 +19,50 @@ module Debugger
|
|
19
19
|
|
20
20
|
def execute
|
21
21
|
if @match[1]
|
22
|
-
|
22
|
+
line, _, _, expr = @match.captures
|
23
23
|
else
|
24
|
-
_, file,
|
24
|
+
_, file, line, expr = @match.captures
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
|
+
full_file = nil
|
27
28
|
if file.nil?
|
29
|
+
full_file = @state.file
|
28
30
|
file = File.basename(@state.file)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
if line.nil?
|
32
|
+
# Set breakpoint at current line
|
33
|
+
line = @state.line.to_s
|
34
|
+
end
|
35
|
+
elsif line !~ /^\d+$/
|
36
|
+
# See if "line" is a method/function name
|
37
|
+
klass = debug_silent_eval(file)
|
38
|
+
if klass && klass.kind_of?(Module)
|
39
|
+
class_name = klass.name if klass
|
37
40
|
else
|
38
|
-
|
39
|
-
|
41
|
+
print "Unknown class #{file}.\n"
|
42
|
+
throw :debug_error
|
40
43
|
end
|
44
|
+
else
|
45
|
+
file = File.expand_path(file) if file.index(File::SEPARATOR) || \
|
46
|
+
File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
|
47
|
+
full_file = file
|
41
48
|
end
|
42
49
|
|
43
|
-
if
|
44
|
-
|
50
|
+
if line =~ /^\d+$/
|
51
|
+
line = line.to_i
|
52
|
+
lines = Debugger.source_for(full_file)
|
53
|
+
if not lines
|
54
|
+
print "No source file named %s\n", file
|
55
|
+
elsif lines.size < line
|
56
|
+
print "No line %d in file \"%s\"\n", line, file
|
57
|
+
else
|
58
|
+
b = Debugger.add_breakpoint file, line, expr
|
59
|
+
print "Breakpoint %d file %s, line %s\n", b.id, file, line.to_s
|
60
|
+
end
|
45
61
|
else
|
46
|
-
|
62
|
+
method = line.intern.id2name
|
63
|
+
b = Debugger.add_breakpoint class_name, method, expr
|
64
|
+
print "Breakpoint %d at %s::%s\n", b.id, class_name, method.to_s
|
47
65
|
end
|
48
|
-
|
49
|
-
b = Debugger.add_breakpoint file, pos, expr
|
50
|
-
print "Set breakpoint %d at %s:%s\n", b.id, file, pos.to_s
|
51
66
|
end
|
52
67
|
|
53
68
|
class << self
|
@@ -65,58 +80,26 @@ module Debugger
|
|
65
80
|
end
|
66
81
|
end
|
67
82
|
|
68
|
-
class BreakpointsCommand < Command # :nodoc:
|
69
|
-
self.control = true
|
70
|
-
|
71
|
-
def regexp
|
72
|
-
/^\s*b(?:reak)?$/
|
73
|
-
end
|
74
|
-
|
75
|
-
def execute
|
76
|
-
unless Debugger.breakpoints.empty?
|
77
|
-
print "Breakpoints:\n"
|
78
|
-
Debugger.breakpoints.sort_by{|b| b.id }.each do |b|
|
79
|
-
if b.expr.nil?
|
80
|
-
print " %d %s:%s\n", b.id, b.source, b.pos
|
81
|
-
else
|
82
|
-
print " %d %s:%s if %s\n", b.id, b.source, b.pos, b.expr
|
83
|
-
end
|
84
|
-
end
|
85
|
-
else
|
86
|
-
print "No breakpoints\n"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class << self
|
91
|
-
def help_command
|
92
|
-
'break'
|
93
|
-
end
|
94
|
-
|
95
|
-
def help(cmd)
|
96
|
-
%{
|
97
|
-
b[reak]\tlist breakpoints
|
98
|
-
}
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
83
|
class DeleteBreakpointCommand < Command # :nodoc:
|
104
84
|
self.control = true
|
105
85
|
|
106
86
|
def regexp
|
107
|
-
/^\s*del(?:ete)?(?:\s+(
|
87
|
+
/^\s*del(?:ete)?(?:\s+(.*))?$/
|
108
88
|
end
|
109
89
|
|
110
90
|
def execute
|
111
|
-
|
112
|
-
unless
|
113
|
-
if confirm("
|
91
|
+
brkpts = @match[1]
|
92
|
+
unless brkpts
|
93
|
+
if confirm("Delete all breakpoints? (y or n) ")
|
114
94
|
Debugger.breakpoints.clear
|
115
95
|
end
|
116
96
|
else
|
117
|
-
|
118
|
-
|
119
|
-
|
97
|
+
brkpts.split(/[ \t]+/).each do |pos|
|
98
|
+
pos = get_int(pos, "Delete", 1)
|
99
|
+
return unless pos
|
100
|
+
unless Debugger.remove_breakpoint(pos)
|
101
|
+
print "No breakpoint number %d\n", pos
|
102
|
+
end
|
120
103
|
end
|
121
104
|
end
|
122
105
|
end
|
@@ -128,7 +111,7 @@ module Debugger
|
|
128
111
|
|
129
112
|
def help(cmd)
|
130
113
|
%{
|
131
|
-
del[ete][ nnn]\tdelete some or all breakpoints
|
114
|
+
del[ete][ nnn...]\tdelete some or all breakpoints
|
132
115
|
}
|
133
116
|
end
|
134
117
|
end
|
@@ -3,11 +3,11 @@ module Debugger
|
|
3
3
|
self.control = true
|
4
4
|
|
5
5
|
def regexp
|
6
|
-
/^\s*(?:q(?:uit)?|exit)\s*$/
|
6
|
+
/^\s*(?:q(?:uit)?|exit)\s*(\s+unconditionally)?\s*$/
|
7
7
|
end
|
8
8
|
|
9
9
|
def execute
|
10
|
-
if confirm("Really quit? (y/n) ")
|
10
|
+
if @match[1] or confirm("Really quit? (y/n) ")
|
11
11
|
Debugger.save_history if Debugger.respond_to? :save_history
|
12
12
|
exit! # exit -> exit!: No graceful way to stop threads...
|
13
13
|
end
|
@@ -20,8 +20,11 @@ module Debugger
|
|
20
20
|
|
21
21
|
def help(cmd)
|
22
22
|
%{
|
23
|
-
q[uit]\texit from debugger
|
23
|
+
q[uit] [unconditionally]\texit from debugger.
|
24
24
|
exit\talias to quit
|
25
|
+
|
26
|
+
Normally we prompt before exiting. However if the parameter
|
27
|
+
"unconditionally" is given, we stop without asking further questions.
|
25
28
|
}
|
26
29
|
end
|
27
30
|
end
|
@@ -32,25 +35,50 @@ module Debugger
|
|
32
35
|
|
33
36
|
def regexp
|
34
37
|
/ ^\s*
|
35
|
-
(restart|R)
|
36
|
-
(
|
38
|
+
(?:restart|R)
|
39
|
+
(?:\s+ (\S?.*\S))? \s*
|
37
40
|
$
|
38
|
-
/
|
41
|
+
/ix
|
39
42
|
end
|
40
43
|
|
41
44
|
def execute
|
42
|
-
if not defined? Debugger::RDEBUG_SCRIPT
|
43
|
-
|
45
|
+
if not defined? Debugger::RDEBUG_SCRIPT
|
46
|
+
# FIXME? Should ask for confirmation?
|
47
|
+
print "Debugger was not called from the outset...\n"
|
48
|
+
rdebug_script = ''
|
49
|
+
else
|
50
|
+
rdebug_script = Debugger::RDEBUG_SCRIPT + " "
|
51
|
+
end
|
52
|
+
prog_script = Debugger::PROG_SCRIPT
|
53
|
+
begin
|
54
|
+
Dir.chdir(Debugger::INITIAL_DIR)
|
55
|
+
rescue
|
56
|
+
print "Failed to change initial directory #{Debugger::INITIAL_DIR}"
|
57
|
+
end
|
58
|
+
if not File.exists?(prog_script)
|
59
|
+
print "Ruby program #{prog_script} doesn't exist\n"
|
44
60
|
return
|
45
61
|
end
|
46
|
-
if
|
47
|
-
|
62
|
+
if not File.executable?(prog_script) and rdebug_script == ''
|
63
|
+
print "Ruby program #{prog_script} doesn't seem to be executable...\n"
|
64
|
+
print "We'll add a call to Ruby.\n"
|
65
|
+
ruby = begin defined?(Gem) ? Gem.ruby : "ruby" rescue "ruby" end
|
66
|
+
rdebug_script = "#{ruby} -I#{$:.join(' -I')} #{prog_script}"
|
67
|
+
end
|
68
|
+
if @match[1]
|
69
|
+
argv = [prog_script] + @match[1].split(/[ \t]+/)
|
48
70
|
else
|
49
|
-
|
71
|
+
if not defined? Command.settings[:argv]
|
72
|
+
print "Arguments have not been set. Use 'set args' to set them.\n"
|
73
|
+
return
|
74
|
+
else
|
75
|
+
argv = Command.settings[:argv]
|
76
|
+
end
|
50
77
|
end
|
78
|
+
args = argv.join(" ")
|
51
79
|
|
52
80
|
# An execv would be preferable to the "exec" below.
|
53
|
-
cmd =
|
81
|
+
cmd = rdebug_script + args
|
54
82
|
print "Re exec'ing:\n\t#{cmd}\n"
|
55
83
|
exec cmd
|
56
84
|
rescue Errno::EOPNOTSUPP
|
@@ -100,4 +128,4 @@ module Debugger
|
|
100
128
|
end
|
101
129
|
end
|
102
130
|
end
|
103
|
-
end
|
131
|
+
end
|
@@ -3,11 +3,24 @@ module Debugger
|
|
3
3
|
def display_expression(exp)
|
4
4
|
print "%s = %s\n", exp, debug_silent_eval(exp).to_s
|
5
5
|
end
|
6
|
+
|
7
|
+
def active_display_expressions?
|
8
|
+
@state.display.select{|d| d[0]}.size > 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_display_expressions
|
12
|
+
n = 1
|
13
|
+
for d in @state.display
|
14
|
+
if d[0]
|
15
|
+
print "%d: ", n
|
16
|
+
display_expression(d[1])
|
17
|
+
end
|
18
|
+
n += 1
|
19
|
+
end
|
20
|
+
end
|
6
21
|
end
|
7
22
|
|
8
23
|
class AddDisplayCommand < Command # :nodoc:
|
9
|
-
include DisplayFunctions
|
10
|
-
|
11
24
|
def regexp
|
12
25
|
/^\s*disp(?:lay)?\s+(.+)$/
|
13
26
|
end
|
@@ -33,22 +46,21 @@ module Debugger
|
|
33
46
|
end
|
34
47
|
|
35
48
|
class DisplayCommand < Command # :nodoc:
|
36
|
-
self.always_run
|
37
|
-
|
49
|
+
def self.always_run
|
50
|
+
Debugger.annotate = 0 unless Debugger.annotate
|
51
|
+
if Debugger.annotate > 1
|
52
|
+
0
|
53
|
+
else
|
54
|
+
2
|
55
|
+
end
|
56
|
+
end
|
38
57
|
|
39
58
|
def regexp
|
40
59
|
/^\s*disp(?:lay)?$/
|
41
60
|
end
|
42
61
|
|
43
62
|
def execute
|
44
|
-
|
45
|
-
for d in @state.display
|
46
|
-
if d[0]
|
47
|
-
print "%d: ", n
|
48
|
-
display_expression(d[1])
|
49
|
-
end
|
50
|
-
n += 1
|
51
|
-
end
|
63
|
+
print_display_expressions
|
52
64
|
end
|
53
65
|
|
54
66
|
class << self
|
@@ -65,10 +77,9 @@ module Debugger
|
|
65
77
|
end
|
66
78
|
|
67
79
|
class DeleteDisplayCommand < Command # :nodoc:
|
68
|
-
include DisplayFunctions
|
69
80
|
|
70
81
|
def regexp
|
71
|
-
/^\s*undisp(?:lay)?
|
82
|
+
/^\s* undisp(?:lay)? \s* (?:(\S+))?$/x
|
72
83
|
end
|
73
84
|
|
74
85
|
def execute
|
@@ -79,9 +90,10 @@ module Debugger
|
|
79
90
|
end
|
80
91
|
end
|
81
92
|
else
|
82
|
-
pos = pos
|
93
|
+
pos = get_int(pos, "Undisplay")
|
94
|
+
return unless pos
|
83
95
|
if @state.display[pos-1]
|
84
|
-
@state.display[pos-1][0] =
|
96
|
+
@state.display[pos-1][0] = nil
|
85
97
|
else
|
86
98
|
print "Display expression %d is not defined\n", pos
|
87
99
|
end
|
@@ -95,9 +107,14 @@ module Debugger
|
|
95
107
|
|
96
108
|
def help(cmd)
|
97
109
|
%{
|
98
|
-
undisp[lay][ nnn]
|
110
|
+
undisp[lay][ nnn]
|
111
|
+
Cancel some expressions to be displayed when program stops.
|
112
|
+
Arguments are the code numbers of the expressions to stop displaying.
|
113
|
+
No argument means cancel all automatic-display expressions.
|
114
|
+
"delete display" has the same effect as this command.
|
115
|
+
Do "info display" to see current list of code numbers.
|
99
116
|
}
|
100
117
|
end
|
101
118
|
end
|
102
119
|
end
|
103
|
-
end
|
120
|
+
end
|