curses 1.1.0-x86-mingw32
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.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/COPYING +56 -0
- data/README.md +71 -0
- data/ext/curses/curses.c +4618 -0
- data/ext/curses/depend +5 -0
- data/ext/curses/extconf.rb +144 -0
- data/lib/2.2/curses.so +0 -0
- data/lib/2.3/curses.so +0 -0
- data/lib/2.4/curses.so +0 -0
- data/lib/curses.rb +22 -0
- data/sample/hello.rb +29 -0
- data/sample/mouse.rb +53 -0
- data/sample/rain.rb +72 -0
- data/sample/view.rb +76 -0
- data/sample/view2.rb +138 -0
- data/vendor/x86-mingw32/PDCurses/pdcurses.dll +0 -0
- metadata +110 -0
data/ext/curses/depend
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
def have_all(*args)
|
4
|
+
old_libs = $libs.dup
|
5
|
+
old_defs = $defs.dup
|
6
|
+
result = []
|
7
|
+
begin
|
8
|
+
args.each {|arg|
|
9
|
+
r = arg.call(*result)
|
10
|
+
if !r
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
result << r
|
14
|
+
}
|
15
|
+
result
|
16
|
+
ensure
|
17
|
+
if result.length != args.length
|
18
|
+
$libs = old_libs
|
19
|
+
$defs = old_defs
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
dir_config('curses')
|
25
|
+
dir_config('ncurses')
|
26
|
+
dir_config('termcap')
|
27
|
+
|
28
|
+
have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
|
29
|
+
have_library("tinfo", "tgetent") or have_library("termcap", "tgetent")
|
30
|
+
|
31
|
+
header_library = nil
|
32
|
+
[
|
33
|
+
["ncursesw/curses.h", ["ncursesw"]],
|
34
|
+
["ncurses.h", ["ncursesw", "ncurses"]],
|
35
|
+
["ncurses/curses.h", ["ncurses"]],
|
36
|
+
["curses_colr/curses.h", ["cur_colr"]],
|
37
|
+
["curses.h", ["curses", "pdcurses"]],
|
38
|
+
# ["xcurses.h", ["XCurses"]], # XCurses (PDCurses for X11)
|
39
|
+
].each {|hdr, libs|
|
40
|
+
header_library = have_all(
|
41
|
+
lambda { have_header(hdr) && hdr },
|
42
|
+
lambda {|h| libs.find {|lib| have_library(lib, "initscr", h) } })
|
43
|
+
if header_library
|
44
|
+
break;
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
if header_library
|
49
|
+
header, library = header_library
|
50
|
+
puts "header: #{header}"
|
51
|
+
puts "library: #{library}"
|
52
|
+
|
53
|
+
curses = [header]
|
54
|
+
if header == 'curses_colr/curses.h'
|
55
|
+
curses.unshift("varargs.h")
|
56
|
+
end
|
57
|
+
|
58
|
+
for f in %w(beep bkgd bkgdset curs_set deleteln doupdate flash
|
59
|
+
getbkgd getnstr init isendwin keyname keypad resizeterm
|
60
|
+
scrl set setscrreg ungetch
|
61
|
+
wattroff wattron wattrset wbkgd wbkgdset wdeleteln wgetnstr
|
62
|
+
wresize wscrl wsetscrreg werase redrawwin
|
63
|
+
def_prog_mode reset_prog_mode timeout wtimeout nodelay
|
64
|
+
init_color wcolor_set use_default_colors newpad
|
65
|
+
unget_wch get_wch wget_wch)
|
66
|
+
have_func(f) || (have_macro(f, curses) && $defs.push(format("-DHAVE_%s", f.upcase)))
|
67
|
+
end
|
68
|
+
flag = "-D_XOPEN_SOURCE_EXTENDED"
|
69
|
+
if try_static_assert("sizeof(char*)>sizeof(int)",
|
70
|
+
%w[stdio.h stdlib.h]+curses,
|
71
|
+
flag)
|
72
|
+
$defs << flag
|
73
|
+
end
|
74
|
+
have_var("ESCDELAY", curses)
|
75
|
+
have_var("TABSIZE", curses)
|
76
|
+
have_var("COLORS", curses)
|
77
|
+
have_var("COLOR_PAIRS", curses)
|
78
|
+
|
79
|
+
# SVR4 curses has a (undocumented) variable char *curses_version.
|
80
|
+
# ncurses and PDcurses has a function char *curses_version().
|
81
|
+
# Note that the original BSD curses doesn't provide version information.
|
82
|
+
#
|
83
|
+
# configure option:
|
84
|
+
# --with-curses-version=function for SVR4
|
85
|
+
# --with-curses-version=variable for ncurses and PDcurses
|
86
|
+
# (not given) automatically determined
|
87
|
+
|
88
|
+
case with_curses_version = with_config("curses-version")
|
89
|
+
when "function"
|
90
|
+
$defs << '-DHAVE_FUNC_CURSES_VERSION'
|
91
|
+
when "variable"
|
92
|
+
$defs << '-DHAVE_VAR_CURSES_VERSION'
|
93
|
+
when nil
|
94
|
+
func_test_program = cpp_include(curses) + <<-"End"
|
95
|
+
int main(int argc, char *argv[])
|
96
|
+
{
|
97
|
+
curses_version();
|
98
|
+
return EXIT_SUCCESS;
|
99
|
+
}
|
100
|
+
End
|
101
|
+
var_test_program = cpp_include(curses) + <<-"End"
|
102
|
+
extern char *curses_version;
|
103
|
+
int main(int argc, char *argv[])
|
104
|
+
{
|
105
|
+
int i = 0;
|
106
|
+
for (i = 0; i < 100; i++) {
|
107
|
+
if (curses_version[i] == 0)
|
108
|
+
return 0 < i ? EXIT_SUCCESS : EXIT_FAILURE;
|
109
|
+
if (curses_version[i] & 0x80)
|
110
|
+
return EXIT_FAILURE;
|
111
|
+
}
|
112
|
+
return EXIT_FAILURE;
|
113
|
+
}
|
114
|
+
End
|
115
|
+
try = method(CROSS_COMPILING ? :try_link : :try_run)
|
116
|
+
function_p = checking_for(checking_message('function curses_version', curses)) { try[func_test_program] }
|
117
|
+
variable_p = checking_for(checking_message('variable curses_version', curses)) { try[var_test_program] }
|
118
|
+
if function_p and variable_p
|
119
|
+
if [header, library].grep(/ncurses|pdcurses|xcurses/i)
|
120
|
+
variable_p = false
|
121
|
+
else
|
122
|
+
warn "found curses_version but cannot determine whether it is a"
|
123
|
+
warn "function or a variable, so assume a variable in old SVR4"
|
124
|
+
warn "ncurses."
|
125
|
+
function_p = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
$defs << '-DHAVE_FUNC_CURSES_VERSION' if function_p
|
129
|
+
$defs << '-DHAVE_VAR_CURSES_VERSION' if variable_p
|
130
|
+
else
|
131
|
+
warn "unexpected value for --with-curses-version: #{with_curses_version}"
|
132
|
+
end
|
133
|
+
|
134
|
+
if RUBY_VERSION >= '2.1'
|
135
|
+
create_makefile("curses")
|
136
|
+
else
|
137
|
+
# curses is part of ruby-core pre-2.1.0, so this gem is not required. But
|
138
|
+
# make pre-2.1.0 a no-op rather than failing or listing as unsupported, to
|
139
|
+
# aid gems offering multi-version Ruby support.
|
140
|
+
File.open("Makefile", 'w') do |f|
|
141
|
+
f.puts dummy_makefile("curses").join
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/2.2/curses.so
ADDED
Binary file
|
data/lib/2.3/curses.so
ADDED
Binary file
|
data/lib/2.4/curses.so
ADDED
Binary file
|
data/lib/curses.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
pdcurses_path = File.expand_path("../vendor/#{RUBY_PLATFORM}/PDCurses", __dir__)
|
2
|
+
pdcurses_bundled = File.directory?(pdcurses_path)
|
3
|
+
if pdcurses_bundled
|
4
|
+
path = ENV["PATH"]
|
5
|
+
dir = File::ALT_SEPARATOR ?
|
6
|
+
pdcurses_path.tr("/", File::ALT_SEPARATOR) : dir
|
7
|
+
dirs = path.split(File::PATH_SEPARATOR)
|
8
|
+
if !dirs.include?(dir)
|
9
|
+
ENV["PATH"] = [dir, *dirs].join(File::PATH_SEPARATOR)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
major, minor, _ = RUBY_VERSION.split(/\./)
|
15
|
+
require "#{major}.#{minor}/curses.so"
|
16
|
+
rescue LoadError
|
17
|
+
require "curses.so"
|
18
|
+
end
|
19
|
+
|
20
|
+
if pdcurses_bundled
|
21
|
+
Curses.keyboard_encoding = Encoding::UTF_8
|
22
|
+
end
|
data/sample/hello.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "curses"
|
4
|
+
|
5
|
+
def show_message(message)
|
6
|
+
height = 5
|
7
|
+
width = message.length + 6
|
8
|
+
top = (Curses.lines - height) / 2
|
9
|
+
left = (Curses.cols - width) / 2
|
10
|
+
win = Curses::Window.new(height, width, top, left)
|
11
|
+
win.box("|", "-")
|
12
|
+
win.setpos(2, 3)
|
13
|
+
win.addstr(message)
|
14
|
+
win.refresh
|
15
|
+
win.getch
|
16
|
+
win.close
|
17
|
+
end
|
18
|
+
|
19
|
+
Curses.init_screen
|
20
|
+
begin
|
21
|
+
Curses.crmode
|
22
|
+
Curses.setpos((Curses.lines - 1) / 2, (Curses.cols - 11) / 2)
|
23
|
+
Curses.addstr("Hit any key")
|
24
|
+
Curses.refresh
|
25
|
+
Curses.getch
|
26
|
+
show_message("Hello, World!")
|
27
|
+
ensure
|
28
|
+
Curses.close_screen
|
29
|
+
end
|
data/sample/mouse.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "curses"
|
4
|
+
include Curses
|
5
|
+
|
6
|
+
def show_message(*msgs)
|
7
|
+
message = msgs.join
|
8
|
+
height, width = 5, message.length + 6
|
9
|
+
top, left = (lines - height) / 2, (cols - width) / 2
|
10
|
+
win = Window.new(height, width, top, left)
|
11
|
+
win.keypad = true
|
12
|
+
win.attron(color_pair(COLOR_RED)) do
|
13
|
+
win.box("|", "-", "+")
|
14
|
+
end
|
15
|
+
win.setpos(2, 3)
|
16
|
+
win.addstr(message)
|
17
|
+
win.refresh
|
18
|
+
win.getch
|
19
|
+
win.close
|
20
|
+
end
|
21
|
+
|
22
|
+
init_screen
|
23
|
+
start_color
|
24
|
+
init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_WHITE)
|
25
|
+
init_pair(COLOR_RED, COLOR_RED, COLOR_WHITE)
|
26
|
+
crmode
|
27
|
+
noecho
|
28
|
+
stdscr.keypad(true)
|
29
|
+
|
30
|
+
begin
|
31
|
+
mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)
|
32
|
+
setpos((lines - 1) / 2, (cols - 5) / 2)
|
33
|
+
attron(color_pair(COLOR_BLUE)|A_BOLD) do
|
34
|
+
addstr("click")
|
35
|
+
end
|
36
|
+
refresh
|
37
|
+
loop do
|
38
|
+
c = getch
|
39
|
+
case c
|
40
|
+
when KEY_MOUSE
|
41
|
+
m = getmouse
|
42
|
+
if m
|
43
|
+
show_message("getch = #{c.inspect}, ",
|
44
|
+
"mouse event = #{'0x%x' % m.bstate}, ",
|
45
|
+
"axis = (#{m.x},#{m.y},#{m.z})")
|
46
|
+
end
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
refresh
|
51
|
+
ensure
|
52
|
+
close_screen
|
53
|
+
end
|
data/sample/rain.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "curses"
|
4
|
+
|
5
|
+
def onsig(signal)
|
6
|
+
Curses.close_screen
|
7
|
+
exit signal
|
8
|
+
end
|
9
|
+
|
10
|
+
def place_string(y, x, string)
|
11
|
+
Curses.setpos(y, x)
|
12
|
+
Curses.addstr(string)
|
13
|
+
end
|
14
|
+
|
15
|
+
def cycle_index(index)
|
16
|
+
(index + 1) % 5
|
17
|
+
end
|
18
|
+
|
19
|
+
%w[HUP INT QUIT TERM].each do |sig|
|
20
|
+
unless trap(sig, "IGNORE") == "IGNORE" # previous handler
|
21
|
+
trap(sig) {|s| onsig(s) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Curses.init_screen
|
26
|
+
Curses.nl
|
27
|
+
Curses.noecho
|
28
|
+
Curses.curs_set 0
|
29
|
+
srand
|
30
|
+
|
31
|
+
xpos, ypos = {}, {}
|
32
|
+
x_range = 2..(Curses.cols - 3)
|
33
|
+
y_range = 2..(Curses.lines - 3)
|
34
|
+
(0..4).each do |i|
|
35
|
+
xpos[i], ypos[i] = rand(x_range), rand(y_range)
|
36
|
+
end
|
37
|
+
|
38
|
+
i = 0
|
39
|
+
loop do
|
40
|
+
x, y = rand(x_range), rand(y_range)
|
41
|
+
|
42
|
+
place_string(y, x, ".")
|
43
|
+
|
44
|
+
place_string(ypos[i], xpos[i], "o")
|
45
|
+
|
46
|
+
i = cycle_index(i)
|
47
|
+
place_string(ypos[i], xpos[i], "O")
|
48
|
+
|
49
|
+
i = cycle_index(i)
|
50
|
+
place_string(ypos[i] - 1, xpos[i], "-")
|
51
|
+
place_string(ypos[i], xpos[i] - 1, "|.|")
|
52
|
+
place_string(ypos[i] + 1, xpos[i], "-")
|
53
|
+
|
54
|
+
i = cycle_index(i)
|
55
|
+
place_string(ypos[i] - 2, xpos[i], "-")
|
56
|
+
place_string(ypos[i] - 1, xpos[i] - 1, "/ \\")
|
57
|
+
place_string(ypos[i], xpos[i] - 2, "| O |")
|
58
|
+
place_string(ypos[i] + 1, xpos[i] - 1, "\\ /")
|
59
|
+
place_string(ypos[i] + 2, xpos[i], "-")
|
60
|
+
|
61
|
+
i = cycle_index(i)
|
62
|
+
place_string(ypos[i] - 2, xpos[i], " ")
|
63
|
+
place_string(ypos[i] - 1, xpos[i] - 1, " ")
|
64
|
+
place_string(ypos[i], xpos[i] - 2, " ")
|
65
|
+
place_string(ypos[i] + 1, xpos[i] - 1, " ")
|
66
|
+
place_string(ypos[i] + 2, xpos[i], " ")
|
67
|
+
|
68
|
+
xpos[i], ypos[i] = x, y
|
69
|
+
|
70
|
+
Curses.refresh
|
71
|
+
sleep(0.5)
|
72
|
+
end
|
data/sample/view.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "curses"
|
4
|
+
include Curses
|
5
|
+
|
6
|
+
unless ARGV.size == 1
|
7
|
+
puts "usage: #{$0} file"
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
begin
|
12
|
+
data_lines = File.readlines(ARGV[0])
|
13
|
+
rescue
|
14
|
+
raise "cannot open file: #{ARGV[0]}"
|
15
|
+
end
|
16
|
+
|
17
|
+
init_screen
|
18
|
+
#keypad(stdscr, true)
|
19
|
+
nonl
|
20
|
+
cbreak
|
21
|
+
noecho
|
22
|
+
#scrollok(stdscr, true)
|
23
|
+
|
24
|
+
lptr = 0
|
25
|
+
loop do
|
26
|
+
lines.times do |i|
|
27
|
+
setpos(i, 0)
|
28
|
+
#clrtoeol
|
29
|
+
addstr(data_lines[lptr + i] || "")
|
30
|
+
end
|
31
|
+
refresh
|
32
|
+
|
33
|
+
explicit = false
|
34
|
+
n = 0
|
35
|
+
c = nil
|
36
|
+
loop do
|
37
|
+
c = getch
|
38
|
+
if c =~ /[0-9]/
|
39
|
+
n = 10 * n + c.to_i
|
40
|
+
explicit = true
|
41
|
+
else
|
42
|
+
break
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
n = 1 if !explicit && n == 0
|
47
|
+
|
48
|
+
case c
|
49
|
+
when "n" #when KEY_DOWN
|
50
|
+
i = 0
|
51
|
+
n.times do
|
52
|
+
if lptr + lines < data_lines.size
|
53
|
+
lptr += 1
|
54
|
+
else
|
55
|
+
break
|
56
|
+
end
|
57
|
+
i += 1
|
58
|
+
end
|
59
|
+
#wscrl(i)
|
60
|
+
when "p" #when KEY_UP
|
61
|
+
i = 0
|
62
|
+
n.times do
|
63
|
+
if lptr > 0
|
64
|
+
lptr -= 1
|
65
|
+
else
|
66
|
+
break
|
67
|
+
end
|
68
|
+
i += 1
|
69
|
+
end
|
70
|
+
#wscrl(-i)
|
71
|
+
when "q"
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
close_screen
|
data/sample/view2.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "curses"
|
4
|
+
|
5
|
+
|
6
|
+
# A curses based file viewer.
|
7
|
+
class FileViewer
|
8
|
+
|
9
|
+
# Create a new FileViewer and view the file.
|
10
|
+
def initialize(filename)
|
11
|
+
@data_lines = []
|
12
|
+
@screen = nil
|
13
|
+
@top = nil
|
14
|
+
init_curses
|
15
|
+
load_file(filename)
|
16
|
+
interact
|
17
|
+
end
|
18
|
+
|
19
|
+
# Perform the curses setup.
|
20
|
+
def init_curses
|
21
|
+
Curses.init_screen
|
22
|
+
Curses.nonl
|
23
|
+
Curses.cbreak
|
24
|
+
Curses.noecho
|
25
|
+
|
26
|
+
@screen = Curses.stdscr
|
27
|
+
|
28
|
+
@screen.scrollok(true)
|
29
|
+
#@screen.keypad(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Load the file into memory and
|
33
|
+
# put the first part on the curses display.
|
34
|
+
def load_file(filename)
|
35
|
+
@data_lines = File.readlines(filename).map(&:chomp)
|
36
|
+
@top = 0
|
37
|
+
@data_lines[0..@screen.maxy-1].each_with_index do |line, idx|
|
38
|
+
@screen.setpos(idx, 0)
|
39
|
+
@screen.addstr(line)
|
40
|
+
end
|
41
|
+
@screen.setpos(0, 0)
|
42
|
+
@screen.refresh
|
43
|
+
rescue
|
44
|
+
raise "cannot open file '#{filename}' for reading"
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# Scroll the display up by one line.
|
49
|
+
def scroll_up
|
50
|
+
if @top > 0
|
51
|
+
@screen.scrl(-1)
|
52
|
+
@top -= 1
|
53
|
+
str = @data_lines[@top]
|
54
|
+
if str
|
55
|
+
@screen.setpos(0, 0)
|
56
|
+
@screen.addstr(str)
|
57
|
+
end
|
58
|
+
return true
|
59
|
+
else
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Scroll the display down by one line.
|
65
|
+
def scroll_down
|
66
|
+
if @top + @screen.maxy < @data_lines.length
|
67
|
+
@screen.scrl(1)
|
68
|
+
@top += 1
|
69
|
+
str = @data_lines[@top + @screen.maxy - 1]
|
70
|
+
if str
|
71
|
+
@screen.setpos(@screen.maxy - 1, 0)
|
72
|
+
@screen.addstr(str)
|
73
|
+
end
|
74
|
+
return true
|
75
|
+
else
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Allow the user to interact with the display.
|
81
|
+
# This uses Emacs-like keybindings, and also
|
82
|
+
# vi-like keybindings as well, except that left
|
83
|
+
# and right move to the beginning and end of the
|
84
|
+
# file, respectively.
|
85
|
+
def interact
|
86
|
+
loop do
|
87
|
+
result = true
|
88
|
+
c = Curses.getch
|
89
|
+
case c
|
90
|
+
when Curses::KEY_DOWN, Curses::KEY_CTRL_N, "j"
|
91
|
+
result = scroll_down
|
92
|
+
when Curses::KEY_UP, Curses::KEY_CTRL_P, "k"
|
93
|
+
result = scroll_up
|
94
|
+
when Curses::KEY_NPAGE, " "
|
95
|
+
(@screen.maxy - 1).times do |i|
|
96
|
+
if !scroll_down && i == 0
|
97
|
+
result = false
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
when Curses::KEY_PPAGE
|
102
|
+
(@screen.maxy - 1).times do |i|
|
103
|
+
if !scroll_up && i == 0
|
104
|
+
result = false
|
105
|
+
break
|
106
|
+
end
|
107
|
+
end
|
108
|
+
when Curses::KEY_LEFT, Curses::KEY_CTRL_T, "h"
|
109
|
+
while scroll_up
|
110
|
+
end
|
111
|
+
when Curses::KEY_RIGHT, Curses::KEY_CTRL_B, "l"
|
112
|
+
while scroll_down
|
113
|
+
end
|
114
|
+
when "q"
|
115
|
+
break
|
116
|
+
else
|
117
|
+
@screen.setpos(0, 0)
|
118
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
119
|
+
end
|
120
|
+
if !result
|
121
|
+
Curses.beep
|
122
|
+
end
|
123
|
+
@screen.setpos(0, 0)
|
124
|
+
end
|
125
|
+
Curses.close_screen
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# If we are being run as a main program...
|
131
|
+
if __FILE__ == $0
|
132
|
+
unless ARGV.size == 1
|
133
|
+
puts "usage: #{$0} file"
|
134
|
+
exit
|
135
|
+
end
|
136
|
+
|
137
|
+
viewer = FileViewer.new(ARGV[0])
|
138
|
+
end
|