ruby-terminfo-r3 0.1.1

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.
Files changed (7) hide show
  1. data/ChangeLog +44 -0
  2. data/README +92 -0
  3. data/extconf.rb +80 -0
  4. data/lib/terminfo.rb +140 -0
  5. data/make_gem +24 -0
  6. data/terminfo.c +427 -0
  7. metadata +73 -0
data/ChangeLog ADDED
@@ -0,0 +1,44 @@
1
+ 2009-03-06 Tanaka Akira <akr@fsij.org>
2
+
3
+ * version 0.2 released.
4
+
5
+ 2008-12-30 Tanaka Akira <akr@fsij.org>
6
+
7
+ * terminfo.c (rt_wcswidth): check the return value of wcwidth.
8
+
9
+ 2008-12-30 Tanaka Akira <akr@fsij.org>
10
+
11
+ * terminfo.c: prefer ruby/io.h over rubyio.h.
12
+ include wchar.h.
13
+ (FILENO): condition refined.
14
+ (rt_wcswidth): new method TermInfo.wcswidth.
15
+
16
+ * extconf.rb: check ruby/io.h and ruby/encoding.h.
17
+
18
+ 2007-05-30 Tanaka Akira <akr@fsij.org>
19
+
20
+ * terminfo.c (TermInfo.ctermid): defined.
21
+
22
+ * lib/terminfo.rb, sample/resize: use TermInfo.ctermid instead of
23
+ "/dev/tty".
24
+
25
+ 2007-05-29 Tanaka Akira <akr@fsij.org>
26
+
27
+ * sample/resize: new sample program.
28
+
29
+ 2007-04-29 Tanaka Akira <akr@fsij.org>
30
+
31
+ * lib/terminfo.rb (TermInfo.default_object): Use File::NOCTTY for
32
+ opening /dev/tty to avoid acquire a controlling terminal.
33
+
34
+ 2007-04-19 Tanaka Akira <akr@fsij.org>
35
+
36
+ * extconf.rb, terminfo.c: try ncurses.h when ncurses is used.
37
+ NetBSD has curses.h which is incompatible with ncurses.
38
+
39
+ * terminfo.c: define del_curterm empty on FreeBSD and OpenBSD to
40
+ avoid warning and core dump.
41
+
42
+ 2007-04-10 Tanaka Akira <akr@fsij.org>
43
+
44
+ * version 0.1 released.
data/README ADDED
@@ -0,0 +1,92 @@
1
+ = ruby-terminfo-r3 - terminfo binding for Ruby-3
2
+
3
+ ruby-terminfo-r3 is a terminfo binding for Ruby-3. It is a repackaged version
4
+ of the Ruby-2 package ruby-terminfo.
5
+
6
+ Use './make_gem' to build the GEM.
7
+
8
+ The home page for this package is https://github.com/clrgit/ruby-terminfo-r3,
9
+ the original README follows below:
10
+
11
+ = ruby-terminfo - terminfo binding for Ruby
12
+
13
+ ruby-terminfo is a terminfo binding for Ruby
14
+
15
+ == Author
16
+
17
+ Tanaka Akira <akr@fsij.org>
18
+
19
+ == Home Page
20
+
21
+ http://www.a-k-r.org/ruby-terminfo/
22
+
23
+ == Feature
24
+
25
+ * easy to use method, control, for combination of tigetstr/tparm/tputs
26
+ * low-level terminfo binding (setupterm, tigetflag, tigetnum, tigetstr, tparm, tputs)
27
+ * TIOCGWINSZ/TIOCSWINSZ ioctl for screen size
28
+ * ctermid to avoid hardcoding /dev/tty
29
+ * wcswidth to measure a string width in number of columns
30
+
31
+ == Usage
32
+
33
+ === easy to use methods
34
+
35
+ require 'terminfo'
36
+ TermInfo.control("cuf", 7) # cursor forward 7 columns
37
+ p TermInfo.screen_size # use TIOCGWINSZ, LINES/COLUMNS env. or terminfo lines#/cols#
38
+
39
+ === low level methods
40
+
41
+ require 'terminfo'
42
+ t = TermInfo.new(ENV["TERM"], File.open(TermInfo.ctermid, "r+"))
43
+ print t.tputs(t.tparm(t.tigetstr("cuf"), 7), 1) # cursor forward 7 columns
44
+ p TermInfo.tiocgwinsz(STDOUT) # use TIOCGWINSZ
45
+
46
+ == Requirements
47
+
48
+ * ruby : http://www.ruby-lang.org/
49
+
50
+ == Download
51
+
52
+ * latest release: http://www.a-k-r.org/ruby-terminfo/ruby-terminfo-0.2.tar.gz
53
+
54
+ * development version: http://github.com/akr/ruby-terminfo
55
+
56
+ == Install
57
+
58
+ % ruby extconf.rb
59
+ % make
60
+ % make install
61
+
62
+ == Reference Manual
63
+
64
+ See rdoc/TermInfo.html or
65
+ http://www.a-k-r.org/ruby-terminfo/rdoc/TermInfo.html
66
+
67
+ == License
68
+
69
+
70
+ Redistribution and use in source and binary forms, with or without
71
+ modification, are permitted provided that the following conditions are met:
72
+
73
+ (1) Redistributions of source code must retain the above copyright notice, this
74
+ list of conditions and the following disclaimer.
75
+ (2) Redistributions in binary form must reproduce the above copyright notice,
76
+ this list of conditions and the following disclaimer in the documentation
77
+ and/or other materials provided with the distribution.
78
+ (3) The name of the author may not be used to endorse or promote products
79
+ derived from this software without specific prior written permission.
80
+
81
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
82
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
83
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
84
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
85
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
86
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
87
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
88
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
89
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
90
+ OF SUCH DAMAGE.
91
+
92
+ (The modified BSD licence)
data/extconf.rb ADDED
@@ -0,0 +1,80 @@
1
+ # extconf.rb - a part of a Ruby binding for terminfo library.
2
+ #
3
+ # Copyright (C) 2007 Tanaka Akira. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions
7
+ # are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # 2. Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following
13
+ # disclaimer in the documentation and/or other materials provided
14
+ # with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote
16
+ # products derived from this software without specific prior
17
+ # written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'mkmf'
32
+
33
+ # Debian GNU/Linux 4.0 (etch) curses.h, term.h, -lncurses (ncurses.h is linked to curses.h)
34
+ # FreeBSD 6.2 curses.h, term.h, -lncurses (ncurses.h is linked to curses.h)
35
+ # OpenBSD 4.0 curses.h, term.h, -lncurses (curses.h includes ncurses.h by default)
36
+ # HP-UX 11i v3 term.h, -lcurses
37
+ # SunOS 5.10 curses.h, term.h, -lcurses
38
+
39
+ # NetBSD 3.1 with ncurses ncurses.h, -lncurses (curses.h is incompatible for ncurses)
40
+
41
+ have_header("curses.h")
42
+ have_header("term.h")
43
+
44
+ have_func("ctermid", "stdio.h")
45
+
46
+ has_setupterm = true
47
+ if have_library("ncurses", "setupterm")
48
+ have_header("ncurses.h")
49
+ elsif have_library("curses", "setupterm")
50
+ else
51
+ has_setupterm = false
52
+ end
53
+
54
+ have_header("wchar.h")
55
+
56
+ rubyio_h = nil
57
+ rubyio_h = "ruby/io.h" if have_header("ruby/io.h")
58
+ rubyio_h = "rubyio.h" unless rubyio_h
59
+
60
+ if have_type("rb_io_t", ["ruby.h", rubyio_h])
61
+ have_struct_member("rb_io_t", "fd", ["ruby.h", rubyio_h])
62
+ else
63
+ have_struct_member("OpenFile", "fd", ["ruby.h", rubyio_h])
64
+ end
65
+
66
+ have_header("ruby/encoding.h")
67
+
68
+ if has_setupterm
69
+ create_header
70
+ create_makefile('terminfo')
71
+
72
+ open("Makefile", "a") {|mfile|
73
+ mfile.puts <<'End'
74
+ rdoc:
75
+ rdoc --op rdoc terminfo.c lib/terminfo.rb
76
+ End
77
+ }
78
+ else
79
+ puts "terminfo library not found"
80
+ end
data/lib/terminfo.rb ADDED
@@ -0,0 +1,140 @@
1
+ # terminfo.rb - a part of a Ruby binding for terminfo library.
2
+ #
3
+ # Copyright (C) 2007 Tanaka Akira. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions
7
+ # are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # 2. Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following
13
+ # disclaimer in the documentation and/or other materials provided
14
+ # with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote
16
+ # products derived from this software without specific prior
17
+ # written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'terminfo.so'
32
+
33
+ class TermInfo
34
+ def TermInfo.default_object
35
+ unless defined? @default_terminfo
36
+ io = File.open(TermInfo.ctermid, File::RDWR|File::NOCTTY)
37
+ io.sync = true
38
+ @default_terminfo = TermInfo.new(ENV['TERM'], io)
39
+ end
40
+ @default_terminfo
41
+ end
42
+
43
+ def TermInfo.control_string(*args) default_object.control_string(*args) end
44
+ def TermInfo.control(*args) default_object.control(*args) end
45
+ def TermInfo.write(str) default_object.write(str) end
46
+ def TermInfo.flush(&block) default_object.flush(&block) end
47
+ def TermInfo.screen_size() default_object.screen_size() end
48
+ def TermInfo.screen_lines() default_object.screen_lines() end
49
+ def TermInfo.screen_height() default_object.screen_height() end
50
+ def TermInfo.screen_columns() default_object.screen_columns() end
51
+ def TermInfo.screen_width() default_object.screen_width() end
52
+ def TermInfo.io() default_object.io() end
53
+
54
+ def initialize(term=ENV['TERM'], io=STDERR)
55
+ setupterm(term, io.fileno)
56
+ @term = term
57
+ @io = io
58
+ end
59
+ attr_reader :io
60
+
61
+ def inspect
62
+ "\#<#{self.class}:#{@term}>"
63
+ end
64
+
65
+ # TermInfo#control_string return a string to control terminal.
66
+ #
67
+ # TermInfo#control_string([afflines,] capname, p1, p2, ...)
68
+ #
69
+ # capname is a terminfo string capability such as "cuu", "el".
70
+ #
71
+ # p1, p2, ... are parameters for the capability.
72
+ #
73
+ # afflines is a number of lines affected. (used for determining padding length)
74
+ def control_string(*args)
75
+ afflines = 1
76
+ raise ArgumentError, "capname requried" if args.empty?
77
+ afflines = args.shift.to_i if args.first.respond_to?(:to_int)
78
+ raise ArgumentError, "capname not given" if !args.first.respond_to?(:to_str)
79
+ capname = args.shift.to_str
80
+ self.tputs(self.tparm(self.tigetstr(capname), *args), afflines)
81
+ end
82
+
83
+ # TermInfo#control controls a terminal.
84
+ #
85
+ # It prints the result of control_string to io specified at initialization.
86
+ def control(*args)
87
+ @io.write(self.control_string(*args))
88
+ nil
89
+ end
90
+
91
+ def write(str)
92
+ @io.write(str)
93
+ end
94
+
95
+ def flush
96
+ oldlevel = nil
97
+ if block_given?
98
+ oldlevel = Thread.current[:TermInfo_Flush_level]
99
+ oldsync = @io.sync
100
+ begin
101
+ Thread.current[:TermInfo_Flush_level] = (oldlevel || 0) + 1
102
+ @io.sync = false
103
+ yield
104
+ ensure
105
+ Thread.current[:TermInfo_Flush_level] = oldlevel
106
+ @io.sync = oldsync
107
+ end
108
+ end
109
+ @io.flush if oldlevel == nil
110
+ nil
111
+ end
112
+
113
+ # returns terminal screen size in a two element array: [lines, columns].
114
+ def screen_size
115
+ begin
116
+ size = TermInfo.tiocgwinsz(@io)
117
+ rescue NotImplementedError
118
+ size = [0,0]
119
+ end
120
+ if size[0] == 0
121
+ size[0] = ENV.include?('LINES') ? ENV['LINES'].to_i : self.tigetnum("lines")
122
+ end
123
+ if size[1] == 0
124
+ size[1] = ENV.include?('COLUMNS') ? ENV['COLUMNS'].to_i : self.tigetnum("cols")
125
+ end
126
+ size
127
+ end
128
+
129
+ # returns terminal screen height.
130
+ def screen_lines
131
+ self.screen_size[0]
132
+ end
133
+ alias screen_height screen_lines
134
+
135
+ # returns terminal screen width.
136
+ def screen_columns
137
+ self.screen_size[1]
138
+ end
139
+ alias screen_width screen_columns
140
+ end
data/make_gem ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/bash
2
+
3
+ set -eo pipefail
4
+
5
+ # Create the GEM package. The gem command is not used to create the package
6
+ # because it doesn't contain a Gemspec file. Instead it is create using tar and
7
+ # gzip
8
+
9
+ NAME="ruby-terminfo-r3"
10
+ VERSION="0.1.1"
11
+ PCK=$NAME-$VERSION
12
+ FILES="README ChangeLog lib/terminfo.rb terminfo.c extconf.rb make_gem"
13
+
14
+ tar cf - $FILES | gzip --best --stdout >data.tar.gz
15
+ gzip --best --stdout metadata >metadata.gz
16
+ tar cf $PCK.gem data.tar.gz metadata.gz
17
+ rm data.tar.gz metadata.gz
18
+
19
+
20
+ #tar zcf - $FILES | gzip --best --stdout >data.tar.gz
21
+ #gzip --best --stdout metadata >metadata.gz
22
+ #tar cf $PCK.gem data.tar.gz metadata.gz
23
+ #rm data.tar.gz metadata.gz
24
+
data/terminfo.c ADDED
@@ -0,0 +1,427 @@
1
+ /* terminfo.c - Ruby binding for terminfo library.
2
+
3
+ Copyright (C) 2007, 2008 Tanaka Akira. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions
7
+ are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. The name of the author may not be used to endorse or promote
16
+ products derived from this software without specific prior
17
+ written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ #include "ruby.h"
33
+ #ifdef HAVE_RUBY_IO_H
34
+ # include "ruby/io.h"
35
+ #else
36
+ # include "rubyio.h"
37
+ #endif
38
+ #include "extconf.h"
39
+
40
+ #if defined(HAVE_NCURSES_H)
41
+ #include <ncurses.h>
42
+ #elif defined(HAVE_CURSES_H)
43
+ #include <curses.h>
44
+ #endif
45
+
46
+ #ifdef HAVE_TERM_H
47
+ #include <term.h>
48
+ #endif
49
+
50
+ #include <termios.h>
51
+ #include <sys/ioctl.h>
52
+ #include <unistd.h>
53
+
54
+ #ifdef HAVE_WCHAR_H
55
+ #include <wchar.h>
56
+ #endif
57
+
58
+ static VALUE cTermInfo;
59
+ static VALUE eTermInfoError;
60
+
61
+ #ifndef HAVE_TYPE_RB_IO_T
62
+ typedef OpenFile rb_io_t;
63
+ #endif
64
+
65
+ #if defined(HAVE_RB_IO_T_FD) || defined(HAVE_ST_FD)
66
+ # define FILENO(fptr) (fptr->fd)
67
+ #else
68
+ # define FILENO(fptr) fileno(fptr->f)
69
+ #endif
70
+
71
+ #if (defined(__FreeBSD__) && __FreeBSD_cc_version <= 602001) || \
72
+ defined(__OpenBSD__)
73
+ /*
74
+ * warning on FreeBSD
75
+ http://www.FreeBSD.org/cgi/query-pr.cgi?pr=108117&cat=
76
+ * core dump on OpenBSD
77
+ http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&textonly=yes&numbers=5447
78
+ */
79
+ #define del_curterm(oterm) do {} while(0)
80
+ #endif
81
+
82
+ static void
83
+ rt_free(void *ptr)
84
+ {
85
+ if(ptr != NULL)
86
+ del_curterm(ptr);
87
+ }
88
+
89
+ static VALUE
90
+ rt_alloc(VALUE klass)
91
+ {
92
+ return Data_Wrap_Struct(klass, NULL, rt_free, 0);
93
+ }
94
+
95
+ static TERMINAL *
96
+ check_rt(VALUE self)
97
+ {
98
+ Check_Type(self, T_DATA);
99
+ if (RDATA(self)->dfree != rt_free) {
100
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected TermInfo)",
101
+ rb_class2name(CLASS_OF(self)));
102
+ }
103
+ return DATA_PTR(self);
104
+ }
105
+
106
+ static void
107
+ setup(VALUE self)
108
+ {
109
+ TERMINAL *old;
110
+ TERMINAL *term = check_rt(self);
111
+ if (term == NULL) { rb_raise(eTermInfoError, "terminfo object not initialized"); }
112
+ if (cur_term == term)
113
+ return;
114
+ old = set_curterm(term);
115
+ }
116
+
117
+ /*
118
+ * TermInfo#setupterm(term, fd) => int
119
+ *
120
+ * TermInfo#setupterm initializes TermInfo object.
121
+ *
122
+ * term is a string of nil.
123
+ * If nil is given, the environment variable $TERM is used.
124
+ *
125
+ * fd is a file descriptor for target terminal.
126
+ */
127
+ static VALUE
128
+ rt_setupterm(VALUE self, VALUE v_term, VALUE v_fd)
129
+ {
130
+ char *term;
131
+ int fd;
132
+ int err;
133
+ int ret;
134
+ if (check_rt(self) != NULL) { rb_raise(eTermInfoError, "terminfo object already initialized"); }
135
+
136
+ if (v_term == Qnil)
137
+ term = NULL;
138
+ else
139
+ term = StringValueCStr(v_term);
140
+ fd = NUM2INT(v_fd);
141
+
142
+ ret = setupterm(term, fd, &err);
143
+ if (ret == ERR) {
144
+ if (err == 1) rb_raise(eTermInfoError, "hardcopy terminal");
145
+ else if (err == 0) rb_raise(eTermInfoError, "terminal could not be found");
146
+ else if (err == -1) rb_raise(eTermInfoError, "terminfo database could not be found");
147
+ else rb_raise(eTermInfoError, "unexpected setupterm error");
148
+ }
149
+
150
+ DATA_PTR(self) = cur_term;
151
+
152
+ return INT2NUM(err);
153
+ }
154
+
155
+ /*
156
+ * TermInfo#tigetflag(capname) => int
157
+ *
158
+ * TermInfo#tigetflag returns a boolean capability specified by capname.
159
+ */
160
+ static VALUE
161
+ rt_tigetflag(VALUE self, VALUE v_capname)
162
+ {
163
+ int ret;
164
+ setup(self);
165
+ ret = tigetflag(StringValueCStr(v_capname));
166
+ if (ret == -1) { rb_raise(eTermInfoError, "not a boolean capability"); }
167
+ return RTEST(ret) ? Qtrue : Qfalse;
168
+ }
169
+
170
+ /*
171
+ * TermInfo#tigetnum(capname) => int
172
+ *
173
+ * TermInfo#tigetnum returns a numeric capability specified by capname.
174
+ */
175
+ static VALUE
176
+ rt_tigetnum(VALUE self, VALUE v_capname)
177
+ {
178
+ int ret;
179
+ setup(self);
180
+ ret = tigetnum(StringValueCStr(v_capname));
181
+ if (ret == -2) { rb_raise(eTermInfoError, "not a numeric capability"); }
182
+ if (ret == -1) { rb_raise(eTermInfoError, "canceled or absent numeric capability"); }
183
+ return INT2NUM(ret);
184
+ }
185
+
186
+ /*
187
+ * TermInfo#tigetstr(capname) => str
188
+ *
189
+ * TermInfo#tigetstr returns a string capability specified by capname.
190
+ *
191
+ * The return value should be printed after tputs is applied.
192
+ * Also tparm should be applied if it has parameters.
193
+ *
194
+ * io.print ti.tputs(ti.tparm(ti.tigetstr("cuf"), 2))
195
+ *
196
+ * Note that "cuf" means "cursor forward".
197
+ */
198
+ static VALUE
199
+ rt_tigetstr(VALUE self, VALUE v_capname)
200
+ {
201
+ char *ret;
202
+ setup(self);
203
+ ret = tigetstr(StringValueCStr(v_capname));
204
+ if (ret == (char*)-1) {
205
+ rb_raise(eTermInfoError, "not a string capability");
206
+ }
207
+ if (ret == 0) {
208
+ rb_raise(eTermInfoError, "canceled or absent string capability");
209
+ }
210
+ return rb_str_new2(ret);
211
+ }
212
+
213
+ /*
214
+ * TermInfo#tparm(str, ...) => str
215
+ *
216
+ * TermInfo#tparm expands parameters in str returned by tigetstr.
217
+ */
218
+ static VALUE
219
+ rt_tparm(int argc, VALUE *argv, VALUE self)
220
+ {
221
+ char *capname, *ret;
222
+ setup(self);
223
+ VALUE v_capname, v1, v2, v3, v4, v5, v6, v7, v8, v9;
224
+ long p1, p2, p3, p4, p5, p6, p7, p8, p9;
225
+ setup(self);
226
+
227
+ if (rb_scan_args(argc, argv, "19", &v_capname, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9) == 0) {
228
+ rb_raise(rb_eArgError, "capname required");
229
+ }
230
+
231
+ capname = StringValueCStr(v_capname);
232
+ #define conv(p, v) do { if (v == Qnil) p = 0; else p = NUM2LONG(v); } while(0)
233
+ conv(p1, v1);
234
+ conv(p2, v2);
235
+ conv(p3, v3);
236
+ conv(p4, v4);
237
+ conv(p5, v5);
238
+ conv(p6, v6);
239
+ conv(p7, v7);
240
+ conv(p8, v8);
241
+ conv(p9, v9);
242
+
243
+ ret = tparm(capname, p1, p2, p3, p4, p5, p6, p7, p8, p9);
244
+
245
+ if (ret == NULL) { rb_raise(eTermInfoError, "tparm failed"); }
246
+
247
+ return rb_str_new2(ret);
248
+ }
249
+
250
+ static VALUE putfunc_output; /* xxx: not thread safe */
251
+
252
+ static int
253
+ putfunc(int arg)
254
+ {
255
+ char ch = arg;
256
+ rb_str_cat(putfunc_output, &ch, 1);
257
+ return arg;
258
+ }
259
+
260
+ /*
261
+ * TermInfo#tputs(str, affcnt) => str
262
+ *
263
+ * TermInfo#tputs expands padding informaiton using padding characters.
264
+ * affcnt is a number of lines affected by the str.
265
+ */
266
+ static VALUE
267
+ rt_tputs(VALUE self, VALUE v_str, VALUE v_affcnt)
268
+ {
269
+ int ret;
270
+ char *str;
271
+ int affcnt;
272
+ VALUE output;
273
+
274
+ setup(self);
275
+ str = StringValueCStr(v_str);
276
+ affcnt = NUM2INT(v_affcnt);
277
+
278
+ putfunc_output = output = rb_str_new2("");
279
+ ret = tputs(str, affcnt, putfunc);
280
+ putfunc_output = Qnil;
281
+
282
+ if (ret == ERR) { rb_raise(eTermInfoError, "tputs failed"); }
283
+
284
+ return output;
285
+ }
286
+
287
+ /*
288
+ * TermInfo.tiocgwinsz(io) => [row, col]
289
+ *
290
+ * TermInfo.tiocgwinsz returns the screen size of the terminal refered by io,
291
+ * using TIOCGWINSZ ioctl.
292
+ */
293
+ static VALUE
294
+ rt_tiocgwinsz(VALUE self, VALUE io)
295
+ {
296
+ #ifdef TIOCGWINSZ
297
+ rb_io_t *fptr;
298
+ struct winsize sz;
299
+ int ret;
300
+
301
+ GetOpenFile(io, fptr);
302
+
303
+ ret = ioctl(FILENO(fptr), TIOCGWINSZ, &sz);
304
+ if (ret == -1) rb_raise(rb_eIOError, "TIOCGWINSZ failed");
305
+
306
+ return rb_ary_new3(2, INT2NUM(sz.ws_row), INT2NUM(sz.ws_col));
307
+ #else
308
+ rb_notimplement();
309
+ #endif
310
+ }
311
+
312
+ /*
313
+ * TermInfo.tiocswinsz(io, row, col)
314
+ *
315
+ * TermInfo.tiocgwinsz update the screen size information of the terminal refered by io,
316
+ * using TIOCSWINSZ ioctl.
317
+ *
318
+ * It returns nil.
319
+ */
320
+ static VALUE
321
+ rt_tiocswinsz(VALUE self, VALUE io, VALUE row, VALUE col)
322
+ {
323
+ #ifdef TIOCSWINSZ
324
+ rb_io_t *fptr;
325
+ struct winsize sz;
326
+ int ret;
327
+
328
+ GetOpenFile(io, fptr);
329
+
330
+ sz.ws_row = NUM2INT(row);
331
+ sz.ws_col = NUM2INT(col);
332
+
333
+ ret = ioctl(FILENO(fptr), TIOCSWINSZ, &sz);
334
+ if (ret == -1) rb_raise(rb_eIOError, "TIOCSWINSZ failed");
335
+
336
+ return Qnil;
337
+ #else
338
+ rb_notimplement();
339
+ #endif
340
+ }
341
+
342
+ /*
343
+ * TermInfo.ctermid
344
+ *
345
+ * TermInfo.ctermid returns a pathname for the current controling terminal,
346
+ * such as "/dev/tty".
347
+ */
348
+ static VALUE
349
+ rt_ctermid(VALUE self)
350
+ {
351
+ #ifdef HAVE_CTERMID
352
+ char buf[L_ctermid];
353
+ return rb_str_new2(ctermid(buf));
354
+ #else
355
+ return rb_str_new2("/dev/tty");
356
+ #endif
357
+ }
358
+
359
+ /*
360
+ * TermInfo.wcswidth(str)
361
+ *
362
+ * TermInfo.wcswidth returns a the number of columns of str,
363
+ * according to current locale.
364
+ */
365
+ static VALUE
366
+ rt_wcswidth(VALUE self, VALUE str)
367
+ {
368
+ char *s;
369
+ size_t l, r;
370
+ mbstate_t mbs;
371
+ wchar_t wc;
372
+ long cols;
373
+ int width;
374
+
375
+ #ifdef HAVE_RUBY_ENCODING_H
376
+ /* The encoding of str is assumed to be the locale encoding on Ruby 1.8. */
377
+ str = rb_str_encode(str, rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil);
378
+ #endif
379
+
380
+ memset(&mbs,0,sizeof(mbstate_t));
381
+
382
+ s = StringValueCStr(str);
383
+ l = RSTRING_LEN(str);
384
+
385
+ cols = 0;
386
+ while (0 < l) {
387
+ r = mbrtowc(&wc, s, l, &mbs);
388
+ if (r == 0)
389
+ rb_raise(rb_eArgError, "NUL found");
390
+
391
+ width = wcwidth(wc);
392
+ if (width == -1)
393
+ rb_raise(rb_eArgError, "non-printable charactor found");
394
+ cols += width;
395
+
396
+ l -= r;
397
+ s += r;
398
+ }
399
+
400
+ return LONG2NUM(cols);
401
+ }
402
+
403
+ void
404
+ Init_terminfo()
405
+ {
406
+ putfunc_output = Qnil;
407
+ rb_global_variable(&putfunc_output);
408
+
409
+ cTermInfo = rb_define_class("TermInfo", rb_cData);
410
+ eTermInfoError = rb_define_class_under(cTermInfo, "TermInfoError", rb_eRuntimeError);
411
+
412
+ rb_define_alloc_func(cTermInfo, rt_alloc);
413
+
414
+ rb_define_method(cTermInfo, "setupterm", rt_setupterm, 2);
415
+ rb_define_method(cTermInfo, "tigetflag", rt_tigetflag, 1);
416
+ rb_define_method(cTermInfo, "tigetnum", rt_tigetnum, 1);
417
+ rb_define_method(cTermInfo, "tigetstr", rt_tigetstr, 1);
418
+ rb_define_method(cTermInfo, "tparm", rt_tparm, -1);
419
+ rb_define_method(cTermInfo, "tputs", rt_tputs, 2);
420
+
421
+ rb_define_module_function(cTermInfo, "tiocgwinsz", rt_tiocgwinsz, 1);
422
+ rb_define_module_function(cTermInfo, "tiocswinsz", rt_tiocswinsz, 3);
423
+
424
+ rb_define_module_function(cTermInfo, "ctermid", rt_ctermid, 0);
425
+
426
+ rb_define_module_function(cTermInfo, "wcswidth", rt_wcswidth, 1);
427
+ }
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-terminfo-r3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Tanaka Akira
8
+ - Claus Rasmussen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2022-07-20 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: terminfo binding for Ruby-3. Derives from the ruby-terminfo package
18
+ email: akr@fsij.org
19
+ executables: []
20
+
21
+ extensions:
22
+ - extconf.rb
23
+ extra_rdoc_files:
24
+ - README
25
+ - ChangeLog
26
+ files:
27
+ - README
28
+ - ChangeLog
29
+ - lib/terminfo.rb
30
+ - terminfo.c
31
+ - extconf.rb
32
+ - make_gem
33
+ has_rdoc: true
34
+ homepage: http://ruby-terminfo.rubyforge.org
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --title
40
+ - ruby-terminfo documentation
41
+ - --charset
42
+ - utf-8
43
+ - --opname
44
+ - index.html
45
+ - --line-numbers
46
+ - --main
47
+ - README
48
+ - --inline-source
49
+ - --exclude
50
+ - ^(examples|extras)/
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: ruby-terminfo
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: terminfo binding for Ruby-3
72
+ test_files: []
73
+