io-console 0.5.11 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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