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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a402e8ba6c8522b3b423e828a4575da34a084c97a5e6d27cbed65e35695a9c9e
4
- data.tar.gz: 50fa0e88472bcdd8f3242c3957c8ed7c39d5f6c6f41f3d7db48a0eaf73cc64f2
3
+ metadata.gz: e0517c379a2e97552cb42c62d4fab1439f2d974b4425e4502e5b4d139857aa8a
4
+ data.tar.gz: 6fda476f3b979b43419fb80e141b789ed6b2a17893c740b2f467490c3d304d18
5
5
  SHA512:
6
- metadata.gz: 6b190b4fb0d1dedaccc0613754d8c656f65dfa3766ac04624d0a0fd1943339a61aee118beed8be1274de764bfc8404697a303da30300377381d521fbc2d77acf
7
- data.tar.gz: 70a62bd336c53ccd8ae25bacc7bb5a8d7a26d0d5eabcd26ee9541137f8d86345159f134d5f04bde13be0486d057ab7bdbbf2a3667d88b92b6350b6543de12c11
6
+ metadata.gz: fd8d94a627d39b51285301bd46030252ef248f316fb7f56744f4d8752acf4b85462aaba0310d8a5dd5af8cd74fbb4d6a50f1530830cef8009b05af42ddbc97f4
7
+ data.tar.gz: 8a9ed2ef751ab2b15f832dc9c1ef8e97408505cc533b8dbf46946bb773f1454a9b502375a81a468efb18442ecbd6babe9b25551228cb7ca23714f778cc370816
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ LICENSE.txt
2
+ README.md
3
+ ext/
4
+ lib/io/console/size.rb
@@ -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, id_min, id_time, id_intr;
79
- #if ENABLE_IO_GETPASS
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
- #define sys_fail_fptr(fptr) rb_sys_fail_str((fptr)->pathv)
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 (!NIL_P(vopts)) {
142
- VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
143
- VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
144
- VALUE intr = rb_hash_aref(vopts, ID2SYM(id_intr));
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 (!NIL_P(vmin)) {
198
+ if (!NIL_OR_UNDEF_P(vmin)) {
150
199
  opts->vmin = NUM2INT(vmin);
151
200
  optp = opts;
152
201
  }
153
- if (!NIL_P(vtime)) {
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(fptr) ((fptr)->fd)
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
- GetOpenFile(io, fptr);
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(fptr);
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
- GetOpenFile(io, fptr);
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(fptr)) {
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
- GetOpenFile(io, fptr);
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)) sys_fail_fptr(fptr);
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
- rb_io_t *fptr;
465
- int fd;
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)) sys_fail_fptr(fptr);
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
- rb_io_t *fptr;
624
- int fd;
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
- set_echo(&t, NULL);
657
+ set_echo(&t, NULL);
631
658
  else
632
- set_noecho(&t, NULL);
633
- if (!setattr(fd, &t)) sys_fail_fptr(fptr);
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
- rb_io_t *fptr;
650
- int fd;
678
+ int fd = GetReadFD(io);
651
679
 
652
- GetOpenFile(io, fptr);
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
- rb_io_t *fptr;
734
- int fd;
759
+ int fd = GetReadFD(io);
735
760
 
736
- GetOpenFile(io, fptr);
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
- rb_io_t *fptr;
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
- GetOpenFile(io, fptr);
761
- fd = GetReadFD(fptr);
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
- GetOpenFile(io, fptr);
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
- rb_raise(rb_eArgError,
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(fptr);
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)) sys_fail_fptr(fptr);
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
- GetOpenFile(io, fptr);
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
- if (tcflush(fd, TCIFLUSH)) sys_fail_fptr(fptr);
932
+ int fd = GetReadFD(io);
933
+ if (tcflush(fd, TCIFLUSH)) sys_fail(io);
927
934
  #endif
928
- (void)fd;
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
- rb_io_t *fptr;
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)) sys_fail_fptr(fptr);
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, fd2;
969
- #endif
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
- if (tcflush(fd1, TCIFLUSH)) sys_fail_fptr(fptr);
977
- if (tcflush(fd2, TCOFLUSH)) sys_fail_fptr(fptr);
974
+ if (tcflush(fd1, TCIFLUSH)) sys_fail(io);
975
+ if (tcflush(fd2, TCOFLUSH)) sys_fail(io);
978
976
  }
979
977
  else {
980
- if (tcflush(fd1, TCIOFLUSH)) sys_fail_fptr(fptr);
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
- if (write(fd, "\a", 1) < 0)
999
- sys_fail_fptr(fptr);
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
- GetOpenFile(io, fptr);
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
- rb_io_t *fptr;
1242
- VALUE wio;
1243
- GetOpenFile(io, fptr);
1244
- wio = fptr->tied_io_for_writing;
1245
- if (wio) {
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
- rb_io_write(io, rb_sprintf("\x1b[%dJ", mode));
1368
- return io;
1369
- }
1302
+ #ifdef _WIN32
1303
+ HANDLE h;
1304
+ rb_console_size_t ws;
1305
+ COORD *pos = &ws.dwCursorPosition;
1306
+ DWORD w;
1370
1307
 
1371
- static VALUE
1372
- console_scroll(VALUE io, int line)
1373
- {
1374
- if (line) {
1375
- VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line,
1376
- line < 0 ? 'T' : 'S');
1377
- rb_io_write(io, s);
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
- Check_Type(sym = argv[0], T_SYMBOL);
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
- con = rb_const_get(klass, id_console);
1463
- if (!RB_TYPE_P(con, T_FILE) ||
1464
- (!(fptr = RFILE(con)->fptr) || GetReadFD(fptr) == -1)) {
1465
- rb_const_remove(klass, id_console);
1466
- con = 0;
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
- if (sym == ID2SYM(id_close) && argc == 1) {
1471
- if (con) {
1472
- rb_io_close(con);
1473
- rb_const_remove(klass, id_console);
1474
- con = 0;
1475
- }
1476
- return Qnil;
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
- VALUE out;
1493
- rb_io_t *ofptr;
1483
+ VALUE out;
1484
+ rb_io_t *ofptr;
1494
1485
  #endif
1495
- int fd;
1486
+ int fd;
1487
+ VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE));
1496
1488
 
1497
1489
  #ifdef CONSOLE_DEVICE_FOR_WRITING
1498
- fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0);
1499
- if (fd < 0) return Qnil;
1500
- rb_update_max_fd(fd);
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
- fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
1506
- if (fd < 0) {
1494
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
1495
+ if (fd < 0) {
1507
1496
  #ifdef CONSOLE_DEVICE_FOR_WRITING
1508
- rb_io_close(out);
1497
+ rb_io_close(out);
1509
1498
  #endif
1510
- return Qnil;
1511
- }
1512
- rb_update_max_fd(fd);
1513
- args[1] = INT2FIX(O_RDWR);
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
- GetOpenFile(out, ofptr);
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
- fptr->mode |= FMODE_SYNC;
1525
- rb_const_set(klass, id_console, con);
1506
+ rb_const_set(klass, id_console, con);
1526
1507
  }
1508
+
1527
1509
  if (sym) {
1528
- return rb_f_send(argc, argv, con);
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
- rb_funcallv(str, id_chomp_bang, 0, 0);
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
- str = str_chomp(rb_funcallv(io, id_gets, 0, 0));
1617
- puts_call(io);
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
- id_min = rb_intern("min");
1637
- id_time = rb_intern("time");
1638
- id_intr = rb_intern("intr");
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);
@@ -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""ENABLE_IO_GETPASS=1"
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.5.11
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: 2021-12-29 00:00:00.000000000 Z
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.2.32
48
+ rubygems_version: 3.5.0.dev
48
49
  signing_key:
49
50
  specification_version: 4
50
51
  summary: Console interface