-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.rb
112 lines (88 loc) · 2.57 KB
/
cli.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
require 'optparse'
class CLI
def parse_argv
options = {
require: [],
load_path: [],
eval: nil,
pre: nil,
debug: false,
debug_focus_on: nil,
debug_print_stack: false,
}
OptionParser.new do |opts|
opts.banner = 'Usage: run.rb [options]'
opts.on('--pre=CODE') do |code|
options[:pre] = code
end
opts.on('-I=PATH', 'Append load path') do |path|
options[:load_path] << path
end
opts.on('-rFILE', '--require=FILE', 'Require file') do |file|
options[:require] << file
end
opts.on('-e=CODE') do |code|
options[:eval] = code
end
opts.on('--print-missing-insns', 'Print missing insns') do
options[:print_missing_insns] = true
end
opts.on('-h', '--help', 'Prints this help') do
puts opts
exit
end
opts.on('--debug', 'Run in debug mode') do
options[:debug] = true
end
opts.on('--debug-focus-on=FRAME', 'Focus on some specific frame') do |debug_focus_on|
options[:debug_focus_on] = debug_focus_on
end
opts.on('--debug-print-stack') do
options[:debug_print_stack] = true
end
end.parse!
options[:file_to_run] = ARGV.shift
if options[:print_missing_insns]
ignored = [:execute_bitblt, :execute_answer]
all = RubyVM::INSTRUCTION_NAMES.map { |insn| :"execute_#{insn}" }.grep_v(/execute_trace_/)
all -= ignored
existing = Executor.instance_methods + [:execute_leave]
existing &= all
missing = all - existing
puts "+#{existing.length} / -#{missing.length} / total: #{all.length}"
puts missing
exit(0)
end
if options[:eval] && options[:file_to_run]
raise "-e and [file].rb are mutually exclusive"
end
if options[:eval].nil? && options[:file_to_run].nil?
raise "at least one of -e or [file].rb must be given"
end
options
end
def run(eval:, require:)
options = parse_argv
if options[:debug]
$debug = $stdout
else
$debug = StringIO.new
end
VM.instance.debug = options[:debug]
VM.instance.debug_focus_on = options[:debug_focus_on]
VM.instance.debug_print_stack = options[:debug_print_stack]
options[:load_path].each { |path| $LOAD_PATH << path }
if (pre = options[:pre])
eval(pre)
end
options[:require].each { |path| require[path] }
if (code = options[:eval])
$0 = '-e'
eval[code]
end
if (file_to_run = options[:file_to_run])
$0 = file_to_run
require[file_to_run]
end
end
end