io-console 0.5.11 → 0.7.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.
- checksums.yaml +4 -4
- data/.document +4 -0
- data/ext/io/console/console.c +344 -351
- data/ext/io/console/extconf.rb +12 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0517c379a2e97552cb42c62d4fab1439f2d974b4425e4502e5b4d139857aa8a
|
4
|
+
data.tar.gz: 6fda476f3b979b43419fb80e141b789ed6b2a17893c740b2f467490c3d304d18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd8d94a627d39b51285301bd46030252ef248f316fb7f56744f4d8752acf4b85462aaba0310d8a5dd5af8cd74fbb4d6a50f1530830cef8009b05af42ddbc97f4
|
7
|
+
data.tar.gz: 8a9ed2ef751ab2b15f832dc9c1ef8e97408505cc533b8dbf46946bb773f1454a9b502375a81a468efb18442ecbd6babe9b25551228cb7ca23714f778cc370816
|
data/.document
ADDED
data/ext/io/console/console.c
CHANGED
@@ -75,10 +75,8 @@ getattr(int fd, conmode *t)
|
|
75
75
|
#define SET_LAST_ERROR (0)
|
76
76
|
#endif
|
77
77
|
|
78
|
-
static ID id_getc, id_console, id_close
|
79
|
-
|
80
|
-
static ID id_gets, id_chomp_bang;
|
81
|
-
#endif
|
78
|
+
static ID id_getc, id_console, id_close;
|
79
|
+
static ID id_gets, id_flush, id_chomp_bang;
|
82
80
|
|
83
81
|
#if defined HAVE_RUBY_FIBER_SCHEDULER_H
|
84
82
|
# include "ruby/fiber/scheduler.h"
|
@@ -87,7 +85,41 @@ extern VALUE rb_scheduler_timeout(struct timeval *timeout);
|
|
87
85
|
# define rb_fiber_scheduler_make_timeout rb_scheduler_timeout
|
88
86
|
#endif
|
89
87
|
|
90
|
-
#
|
88
|
+
#ifndef HAVE_RB_IO_DESCRIPTOR
|
89
|
+
static int
|
90
|
+
io_descriptor_fallback(VALUE io)
|
91
|
+
{
|
92
|
+
rb_io_t *fptr;
|
93
|
+
GetOpenFile(io, fptr);
|
94
|
+
return fptr->fd;
|
95
|
+
}
|
96
|
+
#define rb_io_descriptor io_descriptor_fallback
|
97
|
+
#endif
|
98
|
+
|
99
|
+
#ifndef HAVE_RB_IO_PATH
|
100
|
+
static VALUE
|
101
|
+
io_path_fallback(VALUE io)
|
102
|
+
{
|
103
|
+
rb_io_t *fptr;
|
104
|
+
GetOpenFile(io, fptr);
|
105
|
+
return fptr->pathv;
|
106
|
+
}
|
107
|
+
#define rb_io_path io_path_fallback
|
108
|
+
#endif
|
109
|
+
|
110
|
+
#ifndef HAVE_RB_IO_GET_WRITE_IO
|
111
|
+
static VALUE
|
112
|
+
io_get_write_io_fallback(VALUE io)
|
113
|
+
{
|
114
|
+
rb_io_t *fptr;
|
115
|
+
GetOpenFile(io, fptr);
|
116
|
+
VALUE wio = fptr->tied_io_for_writing;
|
117
|
+
return wio ? wio : io;
|
118
|
+
}
|
119
|
+
#define rb_io_get_write_io io_get_write_io_fallback
|
120
|
+
#endif
|
121
|
+
|
122
|
+
#define sys_fail(io) rb_sys_fail_str(rb_io_path(io))
|
91
123
|
|
92
124
|
#ifndef HAVE_RB_F_SEND
|
93
125
|
#ifndef RB_PASS_CALLED_KEYWORDS
|
@@ -112,18 +144,34 @@ rb_f_send(int argc, VALUE *argv, VALUE recv)
|
|
112
144
|
}
|
113
145
|
#endif
|
114
146
|
|
147
|
+
enum rawmode_opt_ids {
|
148
|
+
kwd_min,
|
149
|
+
kwd_time,
|
150
|
+
kwd_intr,
|
151
|
+
rawmode_opt_id_count
|
152
|
+
};
|
153
|
+
static ID rawmode_opt_ids[rawmode_opt_id_count];
|
154
|
+
|
115
155
|
typedef struct {
|
116
156
|
int vmin;
|
117
157
|
int vtime;
|
118
158
|
int intr;
|
119
159
|
} rawmode_arg_t;
|
120
160
|
|
161
|
+
#ifndef UNDEF_P
|
162
|
+
# define UNDEF_P(obj) ((obj) == Qundef)
|
163
|
+
#endif
|
164
|
+
#ifndef NIL_OR_UNDEF_P
|
165
|
+
# define NIL_OR_UNDEF_P(obj) (NIL_P(obj) || UNDEF_P(obj))
|
166
|
+
#endif
|
167
|
+
|
121
168
|
static rawmode_arg_t *
|
122
169
|
rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts)
|
123
170
|
{
|
124
171
|
int argc = *argcp;
|
125
172
|
rawmode_arg_t *optp = NULL;
|
126
173
|
VALUE vopts = Qnil;
|
174
|
+
VALUE optvals[rawmode_opt_id_count];
|
127
175
|
#ifdef RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
|
128
176
|
argc = rb_scan_args(argc, argv, "*:", NULL, &vopts);
|
129
177
|
#else
|
@@ -138,19 +186,20 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *
|
|
138
186
|
}
|
139
187
|
#endif
|
140
188
|
rb_check_arity(argc, min_argc, max_argc);
|
141
|
-
if (
|
142
|
-
|
143
|
-
VALUE
|
144
|
-
VALUE
|
189
|
+
if (rb_get_kwargs(vopts, rawmode_opt_ids,
|
190
|
+
0, rawmode_opt_id_count, optvals)) {
|
191
|
+
VALUE vmin = optvals[kwd_min];
|
192
|
+
VALUE vtime = optvals[kwd_time];
|
193
|
+
VALUE intr = optvals[kwd_intr];
|
145
194
|
/* default values by `stty raw` */
|
146
195
|
opts->vmin = 1;
|
147
196
|
opts->vtime = 0;
|
148
197
|
opts->intr = 0;
|
149
|
-
if (!
|
198
|
+
if (!NIL_OR_UNDEF_P(vmin)) {
|
150
199
|
opts->vmin = NUM2INT(vmin);
|
151
200
|
optp = opts;
|
152
201
|
}
|
153
|
-
if (!
|
202
|
+
if (!NIL_OR_UNDEF_P(vtime)) {
|
154
203
|
VALUE v10 = INT2FIX(10);
|
155
204
|
vtime = rb_funcall3(vtime, '*', 1, &v10);
|
156
205
|
opts->vtime = NUM2INT(vtime);
|
@@ -165,6 +214,7 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *
|
|
165
214
|
opts->intr = 0;
|
166
215
|
optp = opts;
|
167
216
|
break;
|
217
|
+
case Qundef:
|
168
218
|
case Qnil:
|
169
219
|
break;
|
170
220
|
default:
|
@@ -275,33 +325,21 @@ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg)
|
|
275
325
|
return setattr(fd, &r);
|
276
326
|
}
|
277
327
|
|
278
|
-
#define GetReadFD(
|
279
|
-
|
280
|
-
static inline int
|
281
|
-
get_write_fd(const rb_io_t *fptr)
|
282
|
-
{
|
283
|
-
VALUE wio = fptr->tied_io_for_writing;
|
284
|
-
rb_io_t *ofptr;
|
285
|
-
if (!wio) return fptr->fd;
|
286
|
-
GetOpenFile(wio, ofptr);
|
287
|
-
return ofptr->fd;
|
288
|
-
}
|
289
|
-
#define GetWriteFD(fptr) get_write_fd(fptr)
|
328
|
+
#define GetReadFD(io) rb_io_descriptor(io)
|
329
|
+
#define GetWriteFD(io) rb_io_descriptor(rb_io_get_write_io(io))
|
290
330
|
|
291
331
|
#define FD_PER_IO 2
|
292
332
|
|
293
333
|
static VALUE
|
294
334
|
ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
|
295
335
|
{
|
296
|
-
rb_io_t *fptr;
|
297
336
|
int status = -1;
|
298
337
|
int error = 0;
|
299
338
|
int fd[FD_PER_IO];
|
300
339
|
conmode t[FD_PER_IO];
|
301
340
|
VALUE result = Qnil;
|
302
341
|
|
303
|
-
|
304
|
-
fd[0] = GetReadFD(fptr);
|
342
|
+
fd[0] = GetReadFD(io);
|
305
343
|
if (fd[0] != -1) {
|
306
344
|
if (set_ttymode(fd[0], t+0, setter, arg)) {
|
307
345
|
status = 0;
|
@@ -311,7 +349,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo
|
|
311
349
|
fd[0] = -1;
|
312
350
|
}
|
313
351
|
}
|
314
|
-
fd[1] = GetWriteFD(
|
352
|
+
fd[1] = GetWriteFD(io);
|
315
353
|
if (fd[1] != -1 && fd[1] != fd[0]) {
|
316
354
|
if (set_ttymode(fd[1], t+1, setter, arg)) {
|
317
355
|
status = 0;
|
@@ -324,14 +362,13 @@ ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, vo
|
|
324
362
|
if (status == 0) {
|
325
363
|
result = rb_protect(func, farg, &status);
|
326
364
|
}
|
327
|
-
|
328
|
-
if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
|
365
|
+
if (fd[0] != -1 && fd[0] == GetReadFD(io)) {
|
329
366
|
if (!setattr(fd[0], t+0)) {
|
330
367
|
error = errno;
|
331
368
|
status = -1;
|
332
369
|
}
|
333
370
|
}
|
334
|
-
if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(
|
371
|
+
if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(io)) {
|
335
372
|
if (!setattr(fd[1], t+1)) {
|
336
373
|
error = errno;
|
337
374
|
status = -1;
|
@@ -417,15 +454,11 @@ static VALUE
|
|
417
454
|
console_set_raw(int argc, VALUE *argv, VALUE io)
|
418
455
|
{
|
419
456
|
conmode t;
|
420
|
-
rb_io_t *fptr;
|
421
|
-
int fd;
|
422
457
|
rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
|
423
|
-
|
424
|
-
|
425
|
-
fd = GetReadFD(fptr);
|
426
|
-
if (!getattr(fd, &t)) sys_fail_fptr(fptr);
|
458
|
+
int fd = GetReadFD(io);
|
459
|
+
if (!getattr(fd, &t)) sys_fail(io);
|
427
460
|
set_rawmode(&t, optp);
|
428
|
-
if (!setattr(fd, &t))
|
461
|
+
if (!setattr(fd, &t)) sys_fail(io);
|
429
462
|
return io;
|
430
463
|
}
|
431
464
|
|
@@ -461,14 +494,10 @@ static VALUE
|
|
461
494
|
console_set_cooked(VALUE io)
|
462
495
|
{
|
463
496
|
conmode t;
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
GetOpenFile(io, fptr);
|
468
|
-
fd = GetReadFD(fptr);
|
469
|
-
if (!getattr(fd, &t)) sys_fail_fptr(fptr);
|
497
|
+
int fd = GetReadFD(io);
|
498
|
+
if (!getattr(fd, &t)) sys_fail(io);
|
470
499
|
set_cookedmode(&t, NULL);
|
471
|
-
if (!setattr(fd, &t))
|
500
|
+
if (!setattr(fd, &t)) sys_fail(io);
|
472
501
|
return io;
|
473
502
|
}
|
474
503
|
|
@@ -620,17 +649,17 @@ static VALUE
|
|
620
649
|
console_set_echo(VALUE io, VALUE f)
|
621
650
|
{
|
622
651
|
conmode t;
|
623
|
-
|
624
|
-
|
652
|
+
int fd = GetReadFD(io);
|
653
|
+
|
654
|
+
if (!getattr(fd, &t)) sys_fail(io);
|
625
655
|
|
626
|
-
GetOpenFile(io, fptr);
|
627
|
-
fd = GetReadFD(fptr);
|
628
|
-
if (!getattr(fd, &t)) sys_fail_fptr(fptr);
|
629
656
|
if (RTEST(f))
|
630
|
-
|
657
|
+
set_echo(&t, NULL);
|
631
658
|
else
|
632
|
-
|
633
|
-
|
659
|
+
set_noecho(&t, NULL);
|
660
|
+
|
661
|
+
if (!setattr(fd, &t)) sys_fail(io);
|
662
|
+
|
634
663
|
return io;
|
635
664
|
}
|
636
665
|
|
@@ -646,12 +675,9 @@ static VALUE
|
|
646
675
|
console_echo_p(VALUE io)
|
647
676
|
{
|
648
677
|
conmode t;
|
649
|
-
|
650
|
-
int fd;
|
678
|
+
int fd = GetReadFD(io);
|
651
679
|
|
652
|
-
|
653
|
-
fd = GetReadFD(fptr);
|
654
|
-
if (!getattr(fd, &t)) sys_fail_fptr(fptr);
|
680
|
+
if (!getattr(fd, &t)) sys_fail(io);
|
655
681
|
return echo_p(&t) ? Qtrue : Qfalse;
|
656
682
|
}
|
657
683
|
|
@@ -730,12 +756,9 @@ static VALUE
|
|
730
756
|
console_conmode_get(VALUE io)
|
731
757
|
{
|
732
758
|
conmode t;
|
733
|
-
|
734
|
-
int fd;
|
759
|
+
int fd = GetReadFD(io);
|
735
760
|
|
736
|
-
|
737
|
-
fd = GetReadFD(fptr);
|
738
|
-
if (!getattr(fd, &t)) sys_fail_fptr(fptr);
|
761
|
+
if (!getattr(fd, &t)) sys_fail(io);
|
739
762
|
|
740
763
|
return conmode_new(cConmode, &t);
|
741
764
|
}
|
@@ -752,14 +775,12 @@ static VALUE
|
|
752
775
|
console_conmode_set(VALUE io, VALUE mode)
|
753
776
|
{
|
754
777
|
conmode *t, r;
|
755
|
-
|
756
|
-
int fd;
|
778
|
+
int fd = GetReadFD(io);
|
757
779
|
|
758
780
|
TypedData_Get_Struct(mode, conmode, &conmode_type, t);
|
759
781
|
r = *t;
|
760
|
-
|
761
|
-
fd
|
762
|
-
if (!setattr(fd, &r)) sys_fail_fptr(fptr);
|
782
|
+
|
783
|
+
if (!setattr(fd, &r)) sys_fail(io);
|
763
784
|
|
764
785
|
return mode;
|
765
786
|
}
|
@@ -795,13 +816,9 @@ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t;
|
|
795
816
|
static VALUE
|
796
817
|
console_winsize(VALUE io)
|
797
818
|
{
|
798
|
-
rb_io_t *fptr;
|
799
|
-
int fd;
|
800
819
|
rb_console_size_t ws;
|
801
|
-
|
802
|
-
|
803
|
-
fd = GetWriteFD(fptr);
|
804
|
-
if (!getwinsize(fd, &ws)) sys_fail_fptr(fptr);
|
820
|
+
int fd = GetWriteFD(io);
|
821
|
+
if (!getwinsize(fd, &ws)) sys_fail(io);
|
805
822
|
return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws)));
|
806
823
|
}
|
807
824
|
|
@@ -817,7 +834,6 @@ console_winsize(VALUE io)
|
|
817
834
|
static VALUE
|
818
835
|
console_set_winsize(VALUE io, VALUE size)
|
819
836
|
{
|
820
|
-
rb_io_t *fptr;
|
821
837
|
rb_console_size_t ws;
|
822
838
|
#if defined _WIN32
|
823
839
|
HANDLE wh;
|
@@ -826,20 +842,17 @@ console_set_winsize(VALUE io, VALUE size)
|
|
826
842
|
#endif
|
827
843
|
VALUE row, col, xpixel, ypixel;
|
828
844
|
const VALUE *sz;
|
829
|
-
int fd;
|
830
845
|
long sizelen;
|
846
|
+
int fd;
|
831
847
|
|
832
|
-
GetOpenFile(io, fptr);
|
833
848
|
size = rb_Array(size);
|
834
849
|
if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) {
|
835
|
-
|
836
|
-
"wrong number of arguments (given %ld, expected 2 or 4)",
|
837
|
-
sizelen);
|
850
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen);
|
838
851
|
}
|
839
852
|
sz = RARRAY_CONST_PTR(size);
|
840
853
|
row = sz[0], col = sz[1], xpixel = ypixel = Qnil;
|
841
854
|
if (sizelen == 4) xpixel = sz[2], ypixel = sz[3];
|
842
|
-
fd = GetWriteFD(
|
855
|
+
fd = GetWriteFD(io);
|
843
856
|
#if defined TIOCSWINSZ
|
844
857
|
ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0;
|
845
858
|
#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
|
@@ -848,7 +861,7 @@ console_set_winsize(VALUE io, VALUE size)
|
|
848
861
|
SET(xpixel);
|
849
862
|
SET(ypixel);
|
850
863
|
#undef SET
|
851
|
-
if (!setwinsize(fd, &ws))
|
864
|
+
if (!setwinsize(fd, &ws)) sys_fail(io);
|
852
865
|
#elif defined _WIN32
|
853
866
|
wh = (HANDLE)rb_w32_get_osfhandle(fd);
|
854
867
|
#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m)
|
@@ -886,12 +899,10 @@ console_set_winsize(VALUE io, VALUE size)
|
|
886
899
|
static VALUE
|
887
900
|
console_check_winsize_changed(VALUE io)
|
888
901
|
{
|
889
|
-
rb_io_t *fptr;
|
890
902
|
HANDLE h;
|
891
903
|
DWORD num;
|
892
904
|
|
893
|
-
|
894
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(fptr));
|
905
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io));
|
895
906
|
while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) {
|
896
907
|
INPUT_RECORD rec;
|
897
908
|
if (ReadConsoleInput(h, &rec, 1, &num)) {
|
@@ -917,15 +928,11 @@ console_check_winsize_changed(VALUE io)
|
|
917
928
|
static VALUE
|
918
929
|
console_iflush(VALUE io)
|
919
930
|
{
|
920
|
-
rb_io_t *fptr;
|
921
|
-
int fd;
|
922
|
-
|
923
|
-
GetOpenFile(io, fptr);
|
924
|
-
fd = GetReadFD(fptr);
|
925
931
|
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
926
|
-
|
932
|
+
int fd = GetReadFD(io);
|
933
|
+
if (tcflush(fd, TCIFLUSH)) sys_fail(io);
|
927
934
|
#endif
|
928
|
-
|
935
|
+
|
929
936
|
return io;
|
930
937
|
}
|
931
938
|
|
@@ -940,13 +947,9 @@ console_iflush(VALUE io)
|
|
940
947
|
static VALUE
|
941
948
|
console_oflush(VALUE io)
|
942
949
|
{
|
943
|
-
|
944
|
-
int fd;
|
945
|
-
|
946
|
-
GetOpenFile(io, fptr);
|
947
|
-
fd = GetWriteFD(fptr);
|
950
|
+
int fd = GetWriteFD(io);
|
948
951
|
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
949
|
-
if (tcflush(fd, TCOFLUSH))
|
952
|
+
if (tcflush(fd, TCOFLUSH)) sys_fail(io);
|
950
953
|
#endif
|
951
954
|
(void)fd;
|
952
955
|
return io;
|
@@ -963,40 +966,30 @@ console_oflush(VALUE io)
|
|
963
966
|
static VALUE
|
964
967
|
console_ioflush(VALUE io)
|
965
968
|
{
|
966
|
-
rb_io_t *fptr;
|
967
969
|
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
968
|
-
int fd1
|
969
|
-
|
970
|
+
int fd1 = GetReadFD(io);
|
971
|
+
int fd2 = GetWriteFD(io);
|
970
972
|
|
971
|
-
GetOpenFile(io, fptr);
|
972
|
-
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
|
973
|
-
fd1 = GetReadFD(fptr);
|
974
|
-
fd2 = GetWriteFD(fptr);
|
975
973
|
if (fd2 != -1 && fd1 != fd2) {
|
976
|
-
|
977
|
-
|
974
|
+
if (tcflush(fd1, TCIFLUSH)) sys_fail(io);
|
975
|
+
if (tcflush(fd2, TCOFLUSH)) sys_fail(io);
|
978
976
|
}
|
979
977
|
else {
|
980
|
-
|
978
|
+
if (tcflush(fd1, TCIOFLUSH)) sys_fail(io);
|
981
979
|
}
|
982
980
|
#endif
|
981
|
+
|
983
982
|
return io;
|
984
983
|
}
|
985
984
|
|
986
985
|
static VALUE
|
987
986
|
console_beep(VALUE io)
|
988
987
|
{
|
989
|
-
rb_io_t *fptr;
|
990
|
-
int fd;
|
991
|
-
|
992
|
-
GetOpenFile(io, fptr);
|
993
|
-
fd = GetWriteFD(fptr);
|
994
988
|
#ifdef _WIN32
|
995
|
-
(void)fd;
|
996
989
|
MessageBeep(0);
|
997
990
|
#else
|
998
|
-
|
999
|
-
|
991
|
+
int fd = GetWriteFD(io);
|
992
|
+
if (write(fd, "\a", 1) < 0) sys_fail(io);
|
1000
993
|
#endif
|
1001
994
|
return io;
|
1002
995
|
}
|
@@ -1017,79 +1010,6 @@ mode_in_range(VALUE val, int high, const char *modename)
|
|
1017
1010
|
}
|
1018
1011
|
|
1019
1012
|
#if defined _WIN32
|
1020
|
-
static VALUE
|
1021
|
-
console_goto(VALUE io, VALUE y, VALUE x)
|
1022
|
-
{
|
1023
|
-
rb_io_t *fptr;
|
1024
|
-
int fd;
|
1025
|
-
COORD pos;
|
1026
|
-
|
1027
|
-
GetOpenFile(io, fptr);
|
1028
|
-
fd = GetWriteFD(fptr);
|
1029
|
-
pos.X = NUM2UINT(x);
|
1030
|
-
pos.Y = NUM2UINT(y);
|
1031
|
-
if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
|
1032
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1033
|
-
}
|
1034
|
-
return io;
|
1035
|
-
}
|
1036
|
-
|
1037
|
-
static VALUE
|
1038
|
-
console_cursor_pos(VALUE io)
|
1039
|
-
{
|
1040
|
-
rb_io_t *fptr;
|
1041
|
-
int fd;
|
1042
|
-
rb_console_size_t ws;
|
1043
|
-
|
1044
|
-
GetOpenFile(io, fptr);
|
1045
|
-
fd = GetWriteFD(fptr);
|
1046
|
-
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
|
1047
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1048
|
-
}
|
1049
|
-
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
|
1050
|
-
}
|
1051
|
-
|
1052
|
-
static VALUE
|
1053
|
-
console_move(VALUE io, int y, int x)
|
1054
|
-
{
|
1055
|
-
rb_io_t *fptr;
|
1056
|
-
HANDLE h;
|
1057
|
-
rb_console_size_t ws;
|
1058
|
-
COORD *pos = &ws.dwCursorPosition;
|
1059
|
-
|
1060
|
-
GetOpenFile(io, fptr);
|
1061
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
|
1062
|
-
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1063
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1064
|
-
}
|
1065
|
-
pos->X += x;
|
1066
|
-
pos->Y += y;
|
1067
|
-
if (!SetConsoleCursorPosition(h, *pos)) {
|
1068
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1069
|
-
}
|
1070
|
-
return io;
|
1071
|
-
}
|
1072
|
-
|
1073
|
-
static VALUE
|
1074
|
-
console_goto_column(VALUE io, VALUE val)
|
1075
|
-
{
|
1076
|
-
rb_io_t *fptr;
|
1077
|
-
HANDLE h;
|
1078
|
-
rb_console_size_t ws;
|
1079
|
-
COORD *pos = &ws.dwCursorPosition;
|
1080
|
-
|
1081
|
-
GetOpenFile(io, fptr);
|
1082
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
|
1083
|
-
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1084
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1085
|
-
}
|
1086
|
-
pos->X = NUM2INT(val);
|
1087
|
-
if (!SetConsoleCursorPosition(h, *pos)) {
|
1088
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1089
|
-
}
|
1090
|
-
return io;
|
1091
|
-
}
|
1092
|
-
|
1093
1013
|
static void
|
1094
1014
|
constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
|
1095
1015
|
{
|
@@ -1099,87 +1019,13 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos)
|
|
1099
1019
|
FillConsoleOutputCharacterW(handle, L' ', len, pos, &written);
|
1100
1020
|
}
|
1101
1021
|
|
1102
|
-
static VALUE
|
1103
|
-
console_erase_line(VALUE io, VALUE val)
|
1104
|
-
{
|
1105
|
-
rb_io_t *fptr;
|
1106
|
-
HANDLE h;
|
1107
|
-
rb_console_size_t ws;
|
1108
|
-
COORD *pos = &ws.dwCursorPosition;
|
1109
|
-
DWORD w;
|
1110
|
-
int mode = mode_in_range(val, 2, "line erase");
|
1111
|
-
|
1112
|
-
GetOpenFile(io, fptr);
|
1113
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
|
1114
|
-
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1115
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1116
|
-
}
|
1117
|
-
w = winsize_col(&ws);
|
1118
|
-
switch (mode) {
|
1119
|
-
case 0: /* after cursor */
|
1120
|
-
w -= pos->X;
|
1121
|
-
break;
|
1122
|
-
case 1: /* before *and* cursor */
|
1123
|
-
w = pos->X + 1;
|
1124
|
-
pos->X = 0;
|
1125
|
-
break;
|
1126
|
-
case 2: /* entire line */
|
1127
|
-
pos->X = 0;
|
1128
|
-
break;
|
1129
|
-
}
|
1130
|
-
constat_clear(h, ws.wAttributes, w, *pos);
|
1131
|
-
return io;
|
1132
|
-
}
|
1133
|
-
|
1134
|
-
static VALUE
|
1135
|
-
console_erase_screen(VALUE io, VALUE val)
|
1136
|
-
{
|
1137
|
-
rb_io_t *fptr;
|
1138
|
-
HANDLE h;
|
1139
|
-
rb_console_size_t ws;
|
1140
|
-
COORD *pos = &ws.dwCursorPosition;
|
1141
|
-
DWORD w;
|
1142
|
-
int mode = mode_in_range(val, 3, "screen erase");
|
1143
|
-
|
1144
|
-
GetOpenFile(io, fptr);
|
1145
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
|
1146
|
-
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1147
|
-
rb_syserr_fail(LAST_ERROR, 0);
|
1148
|
-
}
|
1149
|
-
w = winsize_col(&ws);
|
1150
|
-
switch (mode) {
|
1151
|
-
case 0: /* erase after cursor */
|
1152
|
-
w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
|
1153
|
-
break;
|
1154
|
-
case 1: /* erase before *and* cursor */
|
1155
|
-
w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
|
1156
|
-
pos->X = 0;
|
1157
|
-
pos->Y = ws.srWindow.Top;
|
1158
|
-
break;
|
1159
|
-
case 2: /* erase entire screen */
|
1160
|
-
w = (w * winsize_row(&ws));
|
1161
|
-
pos->X = 0;
|
1162
|
-
pos->Y = ws.srWindow.Top;
|
1163
|
-
break;
|
1164
|
-
case 3: /* erase entire screen */
|
1165
|
-
w = (w * ws.dwSize.Y);
|
1166
|
-
pos->X = 0;
|
1167
|
-
pos->Y = 0;
|
1168
|
-
break;
|
1169
|
-
}
|
1170
|
-
constat_clear(h, ws.wAttributes, w, *pos);
|
1171
|
-
return io;
|
1172
|
-
}
|
1173
|
-
|
1174
1022
|
static VALUE
|
1175
1023
|
console_scroll(VALUE io, int line)
|
1176
1024
|
{
|
1177
|
-
rb_io_t *fptr;
|
1178
1025
|
HANDLE h;
|
1179
1026
|
rb_console_size_t ws;
|
1180
1027
|
|
1181
|
-
|
1182
|
-
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(fptr));
|
1028
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
|
1183
1029
|
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1184
1030
|
rb_syserr_fail(LAST_ERROR, 0);
|
1185
1031
|
}
|
@@ -1238,23 +1084,11 @@ static int
|
|
1238
1084
|
direct_query(VALUE io, const struct query_args *query)
|
1239
1085
|
{
|
1240
1086
|
if (RB_TYPE_P(io, T_FILE)) {
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
VALUE s = rb_str_new_cstr(query->qstr);
|
1247
|
-
rb_io_write(wio, s);
|
1248
|
-
rb_io_flush(wio);
|
1249
|
-
return 1;
|
1250
|
-
}
|
1251
|
-
if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) {
|
1252
|
-
return 1;
|
1253
|
-
}
|
1254
|
-
if (fptr->fd == 0 &&
|
1255
|
-
write(1, query->qstr, strlen(query->qstr)) != -1) {
|
1256
|
-
return 1;
|
1257
|
-
}
|
1087
|
+
VALUE wio = rb_io_get_write_io(io);
|
1088
|
+
VALUE s = rb_str_new_cstr(query->qstr);
|
1089
|
+
rb_io_write(wio, s);
|
1090
|
+
rb_io_flush(wio);
|
1091
|
+
return 1;
|
1258
1092
|
}
|
1259
1093
|
return 0;
|
1260
1094
|
}
|
@@ -1304,9 +1138,41 @@ console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qa
|
|
1304
1138
|
return ret;
|
1305
1139
|
}
|
1306
1140
|
|
1141
|
+
static VALUE
|
1142
|
+
console_scroll(VALUE io, int line)
|
1143
|
+
{
|
1144
|
+
if (line) {
|
1145
|
+
VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
|
1146
|
+
line < 0 ? 'T' : 'S');
|
1147
|
+
rb_io_write(io, s);
|
1148
|
+
}
|
1149
|
+
return io;
|
1150
|
+
}
|
1151
|
+
|
1152
|
+
# define console_key_pressed_p rb_f_notimplement
|
1153
|
+
#endif
|
1154
|
+
|
1155
|
+
/*
|
1156
|
+
* call-seq:
|
1157
|
+
* io.cursor -> [row, column]
|
1158
|
+
*
|
1159
|
+
* Returns the current cursor position as a two-element array of integers (row, column)
|
1160
|
+
*
|
1161
|
+
* io.cursor # => [3, 5]
|
1162
|
+
*
|
1163
|
+
* You must require 'io/console' to use this method.
|
1164
|
+
*/
|
1307
1165
|
static VALUE
|
1308
1166
|
console_cursor_pos(VALUE io)
|
1309
1167
|
{
|
1168
|
+
#ifdef _WIN32
|
1169
|
+
rb_console_size_t ws;
|
1170
|
+
int fd = GetWriteFD(io);
|
1171
|
+
if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) {
|
1172
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1173
|
+
}
|
1174
|
+
return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X));
|
1175
|
+
#else
|
1310
1176
|
static const struct query_args query = {"\033[6n", 0};
|
1311
1177
|
VALUE resp = console_vt_response(0, 0, io, &query);
|
1312
1178
|
VALUE row, column, term;
|
@@ -1323,18 +1189,44 @@ console_cursor_pos(VALUE io)
|
|
1323
1189
|
RARRAY_ASET(resp, 0, INT2NUM(r));
|
1324
1190
|
RARRAY_ASET(resp, 1, INT2NUM(c));
|
1325
1191
|
return resp;
|
1192
|
+
#endif
|
1326
1193
|
}
|
1327
1194
|
|
1328
1195
|
static VALUE
|
1329
1196
|
console_goto(VALUE io, VALUE y, VALUE x)
|
1330
1197
|
{
|
1198
|
+
#ifdef _WIN32
|
1199
|
+
COORD pos;
|
1200
|
+
int fd = GetWriteFD(io);
|
1201
|
+
pos.X = NUM2UINT(x);
|
1202
|
+
pos.Y = NUM2UINT(y);
|
1203
|
+
if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) {
|
1204
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1205
|
+
}
|
1206
|
+
#else
|
1331
1207
|
rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1));
|
1208
|
+
#endif
|
1332
1209
|
return io;
|
1333
1210
|
}
|
1334
1211
|
|
1335
1212
|
static VALUE
|
1336
1213
|
console_move(VALUE io, int y, int x)
|
1337
1214
|
{
|
1215
|
+
#ifdef _WIN32
|
1216
|
+
HANDLE h;
|
1217
|
+
rb_console_size_t ws;
|
1218
|
+
COORD *pos = &ws.dwCursorPosition;
|
1219
|
+
|
1220
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
|
1221
|
+
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1222
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1223
|
+
}
|
1224
|
+
pos->X += x;
|
1225
|
+
pos->Y += y;
|
1226
|
+
if (!SetConsoleCursorPosition(h, *pos)) {
|
1227
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1228
|
+
}
|
1229
|
+
#else
|
1338
1230
|
if (x || y) {
|
1339
1231
|
VALUE s = rb_str_new_cstr("");
|
1340
1232
|
if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B');
|
@@ -1342,13 +1234,29 @@ console_move(VALUE io, int y, int x)
|
|
1342
1234
|
rb_io_write(io, s);
|
1343
1235
|
rb_io_flush(io);
|
1344
1236
|
}
|
1237
|
+
#endif
|
1345
1238
|
return io;
|
1346
1239
|
}
|
1347
1240
|
|
1348
1241
|
static VALUE
|
1349
1242
|
console_goto_column(VALUE io, VALUE val)
|
1350
1243
|
{
|
1244
|
+
#ifdef _WIN32
|
1245
|
+
HANDLE h;
|
1246
|
+
rb_console_size_t ws;
|
1247
|
+
COORD *pos = &ws.dwCursorPosition;
|
1248
|
+
|
1249
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
|
1250
|
+
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1251
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1252
|
+
}
|
1253
|
+
pos->X = NUM2INT(val);
|
1254
|
+
if (!SetConsoleCursorPosition(h, *pos)) {
|
1255
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1256
|
+
}
|
1257
|
+
#else
|
1351
1258
|
rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1));
|
1259
|
+
#endif
|
1352
1260
|
return io;
|
1353
1261
|
}
|
1354
1262
|
|
@@ -1356,7 +1264,34 @@ static VALUE
|
|
1356
1264
|
console_erase_line(VALUE io, VALUE val)
|
1357
1265
|
{
|
1358
1266
|
int mode = mode_in_range(val, 2, "line erase");
|
1267
|
+
#ifdef _WIN32
|
1268
|
+
HANDLE h;
|
1269
|
+
rb_console_size_t ws;
|
1270
|
+
COORD *pos = &ws.dwCursorPosition;
|
1271
|
+
DWORD w;
|
1272
|
+
|
1273
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
|
1274
|
+
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1275
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1276
|
+
}
|
1277
|
+
w = winsize_col(&ws);
|
1278
|
+
switch (mode) {
|
1279
|
+
case 0: /* after cursor */
|
1280
|
+
w -= pos->X;
|
1281
|
+
break;
|
1282
|
+
case 1: /* before *and* cursor */
|
1283
|
+
w = pos->X + 1;
|
1284
|
+
pos->X = 0;
|
1285
|
+
break;
|
1286
|
+
case 2: /* entire line */
|
1287
|
+
pos->X = 0;
|
1288
|
+
break;
|
1289
|
+
}
|
1290
|
+
constat_clear(h, ws.wAttributes, w, *pos);
|
1291
|
+
return io;
|
1292
|
+
#else
|
1359
1293
|
rb_io_write(io, rb_sprintf("\x1b[%dK", mode));
|
1294
|
+
#endif
|
1360
1295
|
return io;
|
1361
1296
|
}
|
1362
1297
|
|
@@ -1364,22 +1299,43 @@ static VALUE
|
|
1364
1299
|
console_erase_screen(VALUE io, VALUE val)
|
1365
1300
|
{
|
1366
1301
|
int mode = mode_in_range(val, 3, "screen erase");
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1302
|
+
#ifdef _WIN32
|
1303
|
+
HANDLE h;
|
1304
|
+
rb_console_size_t ws;
|
1305
|
+
COORD *pos = &ws.dwCursorPosition;
|
1306
|
+
DWORD w;
|
1370
1307
|
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1308
|
+
h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io));
|
1309
|
+
if (!GetConsoleScreenBufferInfo(h, &ws)) {
|
1310
|
+
rb_syserr_fail(LAST_ERROR, 0);
|
1311
|
+
}
|
1312
|
+
w = winsize_col(&ws);
|
1313
|
+
switch (mode) {
|
1314
|
+
case 0: /* erase after cursor */
|
1315
|
+
w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X);
|
1316
|
+
break;
|
1317
|
+
case 1: /* erase before *and* cursor */
|
1318
|
+
w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1);
|
1319
|
+
pos->X = 0;
|
1320
|
+
pos->Y = ws.srWindow.Top;
|
1321
|
+
break;
|
1322
|
+
case 2: /* erase entire screen */
|
1323
|
+
w = (w * winsize_row(&ws));
|
1324
|
+
pos->X = 0;
|
1325
|
+
pos->Y = ws.srWindow.Top;
|
1326
|
+
break;
|
1327
|
+
case 3: /* erase entire screen */
|
1328
|
+
w = (w * ws.dwSize.Y);
|
1329
|
+
pos->X = 0;
|
1330
|
+
pos->Y = 0;
|
1331
|
+
break;
|
1378
1332
|
}
|
1333
|
+
constat_clear(h, ws.wAttributes, w, *pos);
|
1334
|
+
#else
|
1335
|
+
rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
|
1336
|
+
#endif
|
1379
1337
|
return io;
|
1380
1338
|
}
|
1381
|
-
# define console_key_pressed_p rb_f_notimplement
|
1382
|
-
#endif
|
1383
1339
|
|
1384
1340
|
static VALUE
|
1385
1341
|
console_cursor_set(VALUE io, VALUE cpos)
|
@@ -1433,6 +1389,38 @@ console_clear_screen(VALUE io)
|
|
1433
1389
|
return io;
|
1434
1390
|
}
|
1435
1391
|
|
1392
|
+
#ifndef HAVE_RB_IO_OPEN_DESCRIPTOR
|
1393
|
+
static VALUE
|
1394
|
+
io_open_descriptor_fallback(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, void *encoding)
|
1395
|
+
{
|
1396
|
+
rb_update_max_fd(descriptor);
|
1397
|
+
|
1398
|
+
VALUE arguments[2] = {
|
1399
|
+
INT2NUM(descriptor),
|
1400
|
+
INT2FIX(mode),
|
1401
|
+
};
|
1402
|
+
|
1403
|
+
VALUE self = rb_class_new_instance(2, arguments, klass);
|
1404
|
+
|
1405
|
+
rb_io_t *fptr;
|
1406
|
+
GetOpenFile(self, fptr);
|
1407
|
+
fptr->pathv = path;
|
1408
|
+
fptr->mode |= mode;
|
1409
|
+
|
1410
|
+
return self;
|
1411
|
+
}
|
1412
|
+
#define rb_io_open_descriptor io_open_descriptor_fallback
|
1413
|
+
#endif
|
1414
|
+
|
1415
|
+
#ifndef HAVE_RB_IO_CLOSED_P
|
1416
|
+
static VALUE
|
1417
|
+
rb_io_closed_p(VALUE io)
|
1418
|
+
{
|
1419
|
+
rb_io_t *fptr = RFILE(io)->fptr;
|
1420
|
+
return fptr->fd == -1 ? Qtrue : Qfalse;
|
1421
|
+
}
|
1422
|
+
#endif
|
1423
|
+
|
1436
1424
|
/*
|
1437
1425
|
* call-seq:
|
1438
1426
|
* IO.console -> #<File:/dev/tty>
|
@@ -1450,34 +1438,37 @@ static VALUE
|
|
1450
1438
|
console_dev(int argc, VALUE *argv, VALUE klass)
|
1451
1439
|
{
|
1452
1440
|
VALUE con = 0;
|
1453
|
-
rb_io_t *fptr;
|
1454
1441
|
VALUE sym = 0;
|
1455
1442
|
|
1456
1443
|
rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS);
|
1444
|
+
|
1457
1445
|
if (argc) {
|
1458
|
-
|
1446
|
+
Check_Type(sym = argv[0], T_SYMBOL);
|
1459
1447
|
}
|
1448
|
+
|
1449
|
+
// Force the class to be File.
|
1460
1450
|
if (klass == rb_cIO) klass = rb_cFile;
|
1451
|
+
|
1461
1452
|
if (rb_const_defined(klass, id_console)) {
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
}
|
1453
|
+
con = rb_const_get(klass, id_console);
|
1454
|
+
if (!RB_TYPE_P(con, T_FILE) || RTEST(rb_io_closed_p(con))) {
|
1455
|
+
rb_const_remove(klass, id_console);
|
1456
|
+
con = 0;
|
1457
|
+
}
|
1468
1458
|
}
|
1459
|
+
|
1469
1460
|
if (sym) {
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1461
|
+
if (sym == ID2SYM(id_close) && argc == 1) {
|
1462
|
+
if (con) {
|
1463
|
+
rb_io_close(con);
|
1464
|
+
rb_const_remove(klass, id_console);
|
1465
|
+
con = 0;
|
1466
|
+
}
|
1467
|
+
return Qnil;
|
1468
|
+
}
|
1478
1469
|
}
|
1470
|
+
|
1479
1471
|
if (!con) {
|
1480
|
-
VALUE args[2];
|
1481
1472
|
#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H
|
1482
1473
|
# define CONSOLE_DEVICE "/dev/tty"
|
1483
1474
|
#elif defined _WIN32
|
@@ -1489,44 +1480,36 @@ console_dev(int argc, VALUE *argv, VALUE klass)
|
|
1489
1480
|
# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE
|
1490
1481
|
#endif
|
1491
1482
|
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
1492
|
-
|
1493
|
-
|
1483
|
+
VALUE out;
|
1484
|
+
rb_io_t *ofptr;
|
1494
1485
|
#endif
|
1495
|
-
|
1486
|
+
int fd;
|
1487
|
+
VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
|
1496
1488
|
|
1497
1489
|
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
args[1] = INT2FIX(O_WRONLY);
|
1502
|
-
args[0] = INT2NUM(fd);
|
1503
|
-
out = rb_class_new_instance(2, args, klass);
|
1490
|
+
fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
|
1491
|
+
if (fd < 0) return Qnil;
|
1492
|
+
out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL);
|
1504
1493
|
#endif
|
1505
|
-
|
1506
|
-
|
1494
|
+
fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
|
1495
|
+
if (fd < 0) {
|
1507
1496
|
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
1508
|
-
|
1497
|
+
rb_io_close(out);
|
1509
1498
|
#endif
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
args[0] = INT2NUM(fd);
|
1515
|
-
con = rb_class_new_instance(2, args, klass);
|
1516
|
-
GetOpenFile(con, fptr);
|
1517
|
-
fptr->pathv = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
|
1499
|
+
return Qnil;
|
1500
|
+
}
|
1501
|
+
|
1502
|
+
con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL);
|
1518
1503
|
#ifdef CONSOLE_DEVICE_FOR_WRITING
|
1519
|
-
|
1520
|
-
ofptr->pathv = fptr->pathv;
|
1521
|
-
fptr->tied_io_for_writing = out;
|
1522
|
-
ofptr->mode |= FMODE_SYNC;
|
1504
|
+
rb_io_set_write_io(con, out);
|
1523
1505
|
#endif
|
1524
|
-
|
1525
|
-
rb_const_set(klass, id_console, con);
|
1506
|
+
rb_const_set(klass, id_console, con);
|
1526
1507
|
}
|
1508
|
+
|
1527
1509
|
if (sym) {
|
1528
|
-
|
1510
|
+
return rb_f_send(argc, argv, con);
|
1529
1511
|
}
|
1512
|
+
|
1530
1513
|
return con;
|
1531
1514
|
}
|
1532
1515
|
|
@@ -1542,13 +1525,18 @@ io_getch(int argc, VALUE *argv, VALUE io)
|
|
1542
1525
|
return rb_funcallv(io, id_getc, argc, argv);
|
1543
1526
|
}
|
1544
1527
|
|
1545
|
-
#if ENABLE_IO_GETPASS
|
1546
1528
|
static VALUE
|
1547
1529
|
puts_call(VALUE io)
|
1548
1530
|
{
|
1549
1531
|
return rb_io_write(io, rb_default_rs);
|
1550
1532
|
}
|
1551
1533
|
|
1534
|
+
static VALUE
|
1535
|
+
gets_call(VALUE io)
|
1536
|
+
{
|
1537
|
+
return rb_funcallv(io, id_gets, 0, 0);
|
1538
|
+
}
|
1539
|
+
|
1552
1540
|
static VALUE
|
1553
1541
|
getpass_call(VALUE io)
|
1554
1542
|
{
|
@@ -1569,7 +1557,8 @@ static VALUE
|
|
1569
1557
|
str_chomp(VALUE str)
|
1570
1558
|
{
|
1571
1559
|
if (!NIL_P(str)) {
|
1572
|
-
|
1560
|
+
const VALUE rs = rb_default_rs; /* rvalue in TruffleRuby */
|
1561
|
+
rb_funcallv(str, id_chomp_bang, 1, &rs);
|
1573
1562
|
}
|
1574
1563
|
return str;
|
1575
1564
|
}
|
@@ -1586,6 +1575,12 @@ str_chomp(VALUE str)
|
|
1586
1575
|
* see String#chomp!.
|
1587
1576
|
*
|
1588
1577
|
* You must require 'io/console' to use this method.
|
1578
|
+
*
|
1579
|
+
* require 'io/console'
|
1580
|
+
* IO::console.getpass("Enter password:")
|
1581
|
+
* Enter password:
|
1582
|
+
* # => "mypassword"
|
1583
|
+
*
|
1589
1584
|
*/
|
1590
1585
|
static VALUE
|
1591
1586
|
console_getpass(int argc, VALUE *argv, VALUE io)
|
@@ -1596,6 +1591,7 @@ console_getpass(int argc, VALUE *argv, VALUE io)
|
|
1596
1591
|
wio = rb_io_get_write_io(io);
|
1597
1592
|
if (wio == io && io == rb_stdin) wio = rb_stderr;
|
1598
1593
|
prompt(argc, argv, wio);
|
1594
|
+
rb_io_flush(wio);
|
1599
1595
|
str = rb_ensure(getpass_call, io, puts_call, wio);
|
1600
1596
|
return str_chomp(str);
|
1601
1597
|
}
|
@@ -1613,11 +1609,10 @@ io_getpass(int argc, VALUE *argv, VALUE io)
|
|
1613
1609
|
|
1614
1610
|
rb_check_arity(argc, 0, 1);
|
1615
1611
|
prompt(argc, argv, io);
|
1616
|
-
|
1617
|
-
|
1618
|
-
return str;
|
1612
|
+
rb_check_funcall(io, id_flush, 0, 0);
|
1613
|
+
str = rb_ensure(gets_call, io, puts_call, io);
|
1614
|
+
return str_chomp(str);
|
1619
1615
|
}
|
1620
|
-
#endif
|
1621
1616
|
|
1622
1617
|
/*
|
1623
1618
|
* IO console methods
|
@@ -1627,15 +1622,16 @@ Init_console(void)
|
|
1627
1622
|
{
|
1628
1623
|
#undef rb_intern
|
1629
1624
|
id_getc = rb_intern("getc");
|
1630
|
-
#if ENABLE_IO_GETPASS
|
1631
1625
|
id_gets = rb_intern("gets");
|
1626
|
+
id_flush = rb_intern("flush");
|
1632
1627
|
id_chomp_bang = rb_intern("chomp!");
|
1633
|
-
#endif
|
1634
1628
|
id_console = rb_intern("console");
|
1635
1629
|
id_close = rb_intern("close");
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1630
|
+
#define init_rawmode_opt_id(name) \
|
1631
|
+
rawmode_opt_ids[kwd_##name] = rb_intern(#name)
|
1632
|
+
init_rawmode_opt_id(min);
|
1633
|
+
init_rawmode_opt_id(time);
|
1634
|
+
init_rawmode_opt_id(intr);
|
1639
1635
|
#ifndef HAVE_RB_F_SEND
|
1640
1636
|
id___send__ = rb_intern("__send__");
|
1641
1637
|
#endif
|
@@ -1676,20 +1672,17 @@ InitVM_console(void)
|
|
1676
1672
|
rb_define_method(rb_cIO, "clear_screen", console_clear_screen, 0);
|
1677
1673
|
rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1);
|
1678
1674
|
rb_define_method(rb_cIO, "check_winsize_changed", console_check_winsize_changed, 0);
|
1679
|
-
#if ENABLE_IO_GETPASS
|
1680
1675
|
rb_define_method(rb_cIO, "getpass", console_getpass, -1);
|
1681
|
-
#endif
|
1682
1676
|
rb_define_singleton_method(rb_cIO, "console", console_dev, -1);
|
1683
1677
|
{
|
1684
1678
|
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
|
1685
1679
|
rb_define_method(mReadable, "getch", io_getch, -1);
|
1686
|
-
#if ENABLE_IO_GETPASS
|
1687
1680
|
rb_define_method(mReadable, "getpass", io_getpass, -1);
|
1688
|
-
#endif
|
1689
1681
|
}
|
1690
1682
|
{
|
1691
1683
|
/* :stopdoc: */
|
1692
1684
|
cConmode = rb_define_class_under(rb_cIO, "ConsoleMode", rb_cObject);
|
1685
|
+
rb_define_const(cConmode, "VERSION", rb_str_new_cstr(STRINGIZE(IO_CONSOLE_VERSION)));
|
1693
1686
|
rb_define_alloc_func(cConmode, conmode_alloc);
|
1694
1687
|
rb_undef_method(cConmode, "initialize");
|
1695
1688
|
rb_define_method(cConmode, "initialize_copy", conmode_init_copy, 1);
|
data/ext/io/console/extconf.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
require 'mkmf'
|
3
3
|
|
4
|
+
version = ["../../..", "."].find do |dir|
|
5
|
+
break File.read(File.join(__dir__, dir, "io-console.gemspec"))[/^_VERSION\s*=\s*"(.*?)"/, 1]
|
6
|
+
rescue
|
7
|
+
end
|
8
|
+
|
9
|
+
have_func("rb_io_path")
|
10
|
+
have_func("rb_io_descriptor")
|
11
|
+
have_func("rb_io_get_write_io")
|
12
|
+
have_func("rb_io_closed_p")
|
13
|
+
have_func("rb_io_open_descriptor")
|
14
|
+
|
4
15
|
ok = true if RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
|
5
16
|
hdr = nil
|
6
17
|
case
|
@@ -29,7 +40,7 @@ when true
|
|
29
40
|
elsif have_func("rb_scheduler_timeout") # 3.0
|
30
41
|
have_func("rb_io_wait")
|
31
42
|
end
|
32
|
-
$defs << "-D""
|
43
|
+
$defs << "-D""IO_CONSOLE_VERSION=#{version}"
|
33
44
|
create_makefile("io/console") {|conf|
|
34
45
|
conf << "\n""VK_HEADER = #{vk_header}\n"
|
35
46
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-console
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nobu Nakada
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: add console capabilities to IO instances.
|
14
14
|
email: nobu@ruby-lang.org
|
@@ -17,6 +17,7 @@ extensions:
|
|
17
17
|
- ext/io/console/extconf.rb
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- ".document"
|
20
21
|
- LICENSE.txt
|
21
22
|
- README.md
|
22
23
|
- ext/io/console/console.c
|
@@ -44,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
45
|
- !ruby/object:Gem::Version
|
45
46
|
version: '0'
|
46
47
|
requirements: []
|
47
|
-
rubygems_version: 3.
|
48
|
+
rubygems_version: 3.5.0.dev
|
48
49
|
signing_key:
|
49
50
|
specification_version: 4
|
50
51
|
summary: Console interface
|