io-console 0.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/console.c +166 -31
  3. metadata +10 -11
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 325b97fec58e062aaca201458a4bfe69f8fd6f10
4
+ data.tar.gz: bf95ec75f4252e9628d023906439e352a40bcdf7
5
+ SHA512:
6
+ metadata.gz: aff1c59c522eab1b58220f5d6d597d801207cf3fa595283ee2932ecb0fcc0e25163d41d96a1b8c0a4f14a69d03ef66e1f741bf38075fed0d79234753b031bfb4
7
+ data.tar.gz: 01a283fdff673b555bbb2b151117ca049de53b18631a63c256eec7fb0b919b94885040532d7ef78d25126824987c72dd915d74f1b5d32477728816b8f8045268
data/console.c CHANGED
@@ -91,16 +91,46 @@ getattr(int fd, conmode *t)
91
91
 
92
92
  static ID id_getc, id_console;
93
93
 
94
+ typedef struct {
95
+ int vmin;
96
+ int vtime;
97
+ } rawmode_arg_t;
98
+
99
+ static rawmode_arg_t *
100
+ rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
101
+ {
102
+ rawmode_arg_t *optp = NULL;
103
+ VALUE vopts;
104
+ rb_scan_args(argc, argv, "0:", &vopts);
105
+ if (!NIL_P(vopts)) {
106
+ VALUE vmin = rb_hash_aref(vopts, ID2SYM(rb_intern("min")));
107
+ VALUE vtime = rb_hash_aref(vopts, ID2SYM(rb_intern("time")));
108
+ opts->vmin = 0;
109
+ opts->vtime = 0;
110
+ if (!NIL_P(vmin)) {
111
+ opts->vmin = NUM2INT(vmin);
112
+ optp = opts;
113
+ }
114
+ if (!NIL_P(vtime)) {
115
+ VALUE v10 = INT2FIX(10);
116
+ vtime = rb_funcall3(vtime, '*', 1, &v10);
117
+ opts->vtime = NUM2INT(vtime);
118
+ optp = opts;
119
+ }
120
+ }
121
+ return optp;
122
+ }
123
+
94
124
  static void
95
- set_rawmode(conmode *t)
125
+ set_rawmode(conmode *t, void *arg)
96
126
  {
97
127
  #ifdef HAVE_CFMAKERAW
98
128
  cfmakeraw(t);
99
- #else
100
- #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
129
+ t->c_lflag &= ~(ECHOE|ECHOK);
130
+ #elif defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
101
131
  t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
102
132
  t->c_oflag &= ~OPOST;
103
- t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
133
+ t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN);
104
134
  t->c_cflag &= ~(CSIZE|PARENB);
105
135
  t->c_cflag |= CS8;
106
136
  #elif defined HAVE_SGTTY_H
@@ -109,11 +139,32 @@ set_rawmode(conmode *t)
109
139
  #elif defined _WIN32
110
140
  *t = 0;
111
141
  #endif
142
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
143
+ if (arg) {
144
+ const rawmode_arg_t *r = arg;
145
+ if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin;
146
+ if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime;
147
+ }
112
148
  #endif
113
149
  }
114
150
 
115
151
  static void
116
- set_noecho(conmode *t)
152
+ set_cookedmode(conmode *t, void *arg)
153
+ {
154
+ #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
155
+ t->c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON);
156
+ t->c_oflag |= OPOST;
157
+ t->c_lflag |= (ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN);
158
+ #elif defined HAVE_SGTTY_H
159
+ t->sg_flags |= ECHO;
160
+ t->sg_flags &= ~RAW;
161
+ #elif defined _WIN32
162
+ *t |= ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT;
163
+ #endif
164
+ }
165
+
166
+ static void
167
+ set_noecho(conmode *t, void *arg)
117
168
  {
118
169
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
119
170
  t->c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
@@ -125,7 +176,7 @@ set_noecho(conmode *t)
125
176
  }
126
177
 
127
178
  static void
128
- set_echo(conmode *t)
179
+ set_echo(conmode *t, void *arg)
129
180
  {
130
181
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
131
182
  t->c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL);
@@ -140,7 +191,7 @@ static int
140
191
  echo_p(conmode *t)
141
192
  {
142
193
  #if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H
143
- return (t->c_lflag & (ECHO | ECHOE | ECHOK | ECHONL)) != 0;
194
+ return (t->c_lflag & (ECHO | ECHONL)) != 0;
144
195
  #elif defined HAVE_SGTTY_H
145
196
  return (t->sg_flags & ECHO) != 0;
146
197
  #elif defined _WIN32
@@ -149,12 +200,12 @@ echo_p(conmode *t)
149
200
  }
150
201
 
151
202
  static int
152
- set_ttymode(int fd, conmode *t, void (*setter)(conmode *))
203
+ set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg)
153
204
  {
154
205
  conmode r;
155
206
  if (!getattr(fd, t)) return 0;
156
207
  r = *t;
157
- setter(&r);
208
+ setter(&r, arg);
158
209
  return setattr(fd, &r);
159
210
  }
160
211
 
@@ -182,7 +233,7 @@ get_write_fd(const rb_io_t *fptr)
182
233
  #define FD_PER_IO 2
183
234
 
184
235
  static VALUE
185
- ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
236
+ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void *arg)
186
237
  {
187
238
  rb_io_t *fptr;
188
239
  int status = -1;
@@ -194,7 +245,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
194
245
  GetOpenFile(io, fptr);
195
246
  fd[0] = GetReadFD(fptr);
196
247
  if (fd[0] != -1) {
197
- if (set_ttymode(fd[0], t+0, setter)) {
248
+ if (set_ttymode(fd[0], t+0, setter, arg)) {
198
249
  status = 0;
199
250
  }
200
251
  else {
@@ -204,7 +255,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
204
255
  }
205
256
  fd[1] = GetWriteFD(fptr);
206
257
  if (fd[1] != -1 && fd[1] != fd[0]) {
207
- if (set_ttymode(fd[1], t+1, setter)) {
258
+ if (set_ttymode(fd[1], t+1, setter, arg)) {
208
259
  status = 0;
209
260
  }
210
261
  else {
@@ -240,30 +291,79 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
240
291
 
241
292
  /*
242
293
  * call-seq:
243
- * io.raw {|io| }
294
+ * io.raw(min: nil, time: nil) {|io| }
244
295
  *
245
296
  * Yields +self+ within raw mode.
246
297
  *
247
298
  * STDIN.raw(&:gets)
248
299
  *
249
- * will read and return a line with echo back and line editing.
300
+ * will read and return a line without echo back and line editing.
301
+ *
302
+ * You must require 'io/console' to use this method.
250
303
  */
251
304
  static VALUE
252
- console_raw(VALUE io)
305
+ console_raw(int argc, VALUE *argv, VALUE io)
253
306
  {
254
- return ttymode(io, rb_yield, set_rawmode);
307
+ rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
308
+ return ttymode(io, rb_yield, set_rawmode, optp);
255
309
  }
256
310
 
257
311
  /*
258
312
  * call-seq:
259
- * io.raw!
313
+ * io.raw!(min: nil, time: nil)
260
314
  *
261
315
  * Enables raw mode.
262
316
  *
263
317
  * If the terminal mode needs to be back, use io.raw { ... }.
318
+ *
319
+ * You must require 'io/console' to use this method.
320
+ */
321
+ static VALUE
322
+ console_set_raw(int argc, VALUE *argv, VALUE io)
323
+ {
324
+ conmode t;
325
+ rb_io_t *fptr;
326
+ int fd;
327
+ rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
328
+
329
+ GetOpenFile(io, fptr);
330
+ fd = GetReadFD(fptr);
331
+ if (!getattr(fd, &t)) rb_sys_fail(0);
332
+ set_rawmode(&t, optp);
333
+ if (!setattr(fd, &t)) rb_sys_fail(0);
334
+ return io;
335
+ }
336
+
337
+ /*
338
+ * call-seq:
339
+ * io.cooked {|io| }
340
+ *
341
+ * Yields +self+ within cooked mode.
342
+ *
343
+ * STDIN.cooked(&:gets)
344
+ *
345
+ * will read and return a line with echo back and line editing.
346
+ *
347
+ * You must require 'io/console' to use this method.
264
348
  */
265
349
  static VALUE
266
- console_set_raw(VALUE io)
350
+ console_cooked(VALUE io)
351
+ {
352
+ return ttymode(io, rb_yield, set_cookedmode, NULL);
353
+ }
354
+
355
+ /*
356
+ * call-seq:
357
+ * io.cooked!
358
+ *
359
+ * Enables cooked mode.
360
+ *
361
+ * If the terminal mode needs to be back, use io.cooked { ... }.
362
+ *
363
+ * You must require 'io/console' to use this method.
364
+ */
365
+ static VALUE
366
+ console_set_cooked(VALUE io)
267
367
  {
268
368
  conmode t;
269
369
  rb_io_t *fptr;
@@ -272,7 +372,7 @@ console_set_raw(VALUE io)
272
372
  GetOpenFile(io, fptr);
273
373
  fd = GetReadFD(fptr);
274
374
  if (!getattr(fd, &t)) rb_sys_fail(0);
275
- set_rawmode(&t);
375
+ set_cookedmode(&t, NULL);
276
376
  if (!setattr(fd, &t)) rb_sys_fail(0);
277
377
  return io;
278
378
  }
@@ -285,14 +385,17 @@ getc_call(VALUE io)
285
385
 
286
386
  /*
287
387
  * call-seq:
288
- * io.getch -> char
388
+ * io.getch(min: nil, time: nil) -> char
289
389
  *
290
390
  * Reads and returns a character in raw mode.
391
+ *
392
+ * You must require 'io/console' to use this method.
291
393
  */
292
394
  static VALUE
293
- console_getch(VALUE io)
395
+ console_getch(int argc, VALUE *argv, VALUE io)
294
396
  {
295
- return ttymode(io, getc_call, set_rawmode);
397
+ rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
398
+ return ttymode(io, getc_call, set_rawmode, optp);
296
399
  }
297
400
 
298
401
  /*
@@ -304,11 +407,13 @@ console_getch(VALUE io)
304
407
  * STDIN.noecho(&:gets)
305
408
  *
306
409
  * will read and return a line without echo back.
410
+ *
411
+ * You must require 'io/console' to use this method.
307
412
  */
308
413
  static VALUE
309
414
  console_noecho(VALUE io)
310
415
  {
311
- return ttymode(io, rb_yield, set_noecho);
416
+ return ttymode(io, rb_yield, set_noecho, NULL);
312
417
  }
313
418
 
314
419
  /*
@@ -316,6 +421,10 @@ console_noecho(VALUE io)
316
421
  * io.echo = flag
317
422
  *
318
423
  * Enables/disables echo back.
424
+ * On some platforms, all combinations of this flags and raw/cooked
425
+ * mode may not be valid.
426
+ *
427
+ * You must require 'io/console' to use this method.
319
428
  */
320
429
  static VALUE
321
430
  console_set_echo(VALUE io, VALUE f)
@@ -328,9 +437,9 @@ console_set_echo(VALUE io, VALUE f)
328
437
  fd = GetReadFD(fptr);
329
438
  if (!getattr(fd, &t)) rb_sys_fail(0);
330
439
  if (RTEST(f))
331
- set_echo(&t);
440
+ set_echo(&t, NULL);
332
441
  else
333
- set_noecho(&t);
442
+ set_noecho(&t, NULL);
334
443
  if (!setattr(fd, &t)) rb_sys_fail(0);
335
444
  return io;
336
445
  }
@@ -340,6 +449,8 @@ console_set_echo(VALUE io, VALUE f)
340
449
  * io.echo? -> true or false
341
450
  *
342
451
  * Returns +true+ if echo back is enabled.
452
+ *
453
+ * You must require 'io/console' to use this method.
343
454
  */
344
455
  static VALUE
345
456
  console_echo_p(VALUE io)
@@ -379,6 +490,8 @@ typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t;
379
490
  * io.winsize -> [rows, columns]
380
491
  *
381
492
  * Returns console size.
493
+ *
494
+ * You must require 'io/console' to use this method.
382
495
  */
383
496
  static VALUE
384
497
  console_winsize(VALUE io)
@@ -399,6 +512,8 @@ console_winsize(VALUE io)
399
512
  *
400
513
  * Tries to set console size. The effect depends on the platform and
401
514
  * the running environment.
515
+ *
516
+ * You must require 'io/console' to use this method.
402
517
  */
403
518
  static VALUE
404
519
  console_set_winsize(VALUE io, VALUE size)
@@ -458,6 +573,8 @@ console_set_winsize(VALUE io, VALUE size)
458
573
  * io.iflush
459
574
  *
460
575
  * Flushes input buffer in kernel.
576
+ *
577
+ * You must require 'io/console' to use this method.
461
578
  */
462
579
  static VALUE
463
580
  console_iflush(VALUE io)
@@ -478,6 +595,8 @@ console_iflush(VALUE io)
478
595
  * io.oflush
479
596
  *
480
597
  * Flushes output buffer in kernel.
598
+ *
599
+ * You must require 'io/console' to use this method.
481
600
  */
482
601
  static VALUE
483
602
  console_oflush(VALUE io)
@@ -498,6 +617,8 @@ console_oflush(VALUE io)
498
617
  * io.ioflush
499
618
  *
500
619
  * Flushes input and output buffers in kernel.
620
+ *
621
+ * You must require 'io/console' to use this method.
501
622
  */
502
623
  static VALUE
503
624
  console_ioflush(VALUE io)
@@ -527,6 +648,8 @@ console_ioflush(VALUE io)
527
648
  * IO.console -> #<File:/dev/tty>
528
649
  *
529
650
  * Returns an File instance opened console.
651
+ *
652
+ * You must require 'io/console' to use this method.
530
653
  */
531
654
  static VALUE
532
655
  console_dev(VALUE klass)
@@ -537,7 +660,7 @@ console_dev(VALUE klass)
537
660
  if (klass == rb_cIO) klass = rb_cFile;
538
661
  if (rb_const_defined(klass, id_console)) {
539
662
  con = rb_const_get(klass, id_console);
540
- if (TYPE(con) == T_FILE) {
663
+ if (RB_TYPE_P(con, T_FILE)) {
541
664
  if ((fptr = RFILE(con)->fptr) && GetReadFD(fptr) != -1)
542
665
  return con;
543
666
  }
@@ -562,14 +685,14 @@ console_dev(VALUE klass)
562
685
  int fd;
563
686
 
564
687
  #ifdef CONSOLE_DEVICE_FOR_WRITING
565
- fd = open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY);
688
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY, 0);
566
689
  if (fd < 0) return Qnil;
567
690
  rb_update_max_fd(fd);
568
691
  args[1] = INT2FIX(O_WRONLY);
569
692
  args[0] = INT2NUM(fd);
570
693
  out = rb_class_new_instance(2, args, klass);
571
694
  #endif
572
- fd = open(CONSOLE_DEVICE_FOR_READING, O_RDWR);
695
+ fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0);
573
696
  if (fd < 0) {
574
697
  #ifdef CONSOLE_DEVICE_FOR_WRITING
575
698
  rb_io_close(out);
@@ -599,6 +722,12 @@ console_dev(VALUE klass)
599
722
  return con;
600
723
  }
601
724
 
725
+ static VALUE
726
+ io_getch(int argc, VALUE *argv, VALUE io)
727
+ {
728
+ return rb_funcall2(io, rb_intern("getc"), argc, argv);
729
+ }
730
+
602
731
  /*
603
732
  * IO console methods
604
733
  */
@@ -613,9 +742,11 @@ Init_console(void)
613
742
  void
614
743
  InitVM_console(void)
615
744
  {
616
- rb_define_method(rb_cIO, "raw", console_raw, 0);
617
- rb_define_method(rb_cIO, "raw!", console_set_raw, 0);
618
- rb_define_method(rb_cIO, "getch", console_getch, 0);
745
+ rb_define_method(rb_cIO, "raw", console_raw, -1);
746
+ rb_define_method(rb_cIO, "raw!", console_set_raw, -1);
747
+ rb_define_method(rb_cIO, "cooked", console_cooked, 0);
748
+ rb_define_method(rb_cIO, "cooked!", console_set_cooked, 0);
749
+ rb_define_method(rb_cIO, "getch", console_getch, -1);
619
750
  rb_define_method(rb_cIO, "echo=", console_set_echo, 1);
620
751
  rb_define_method(rb_cIO, "echo?", console_echo_p, 0);
621
752
  rb_define_method(rb_cIO, "noecho", console_noecho, 0);
@@ -625,4 +756,8 @@ InitVM_console(void)
625
756
  rb_define_method(rb_cIO, "oflush", console_oflush, 0);
626
757
  rb_define_method(rb_cIO, "ioflush", console_ioflush, 0);
627
758
  rb_define_singleton_method(rb_cIO, "console", console_dev, 0);
759
+ {
760
+ VALUE mReadable = rb_define_module_under(rb_cIO, "readable");
761
+ rb_define_method(mReadable, "getch", io_getch, -1);
762
+ }
628
763
  }
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-console
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
5
- prerelease:
4
+ version: 0.4.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nobu Nakada
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-06-24 00:00:00.000000000 Z
11
+ date: 2013-02-04 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: add console capabilities to IO instances.
15
14
  email: nobu@ruby-lang.org
@@ -22,27 +21,27 @@ files:
22
21
  - extconf.rb
23
22
  - lib/console/size.rb
24
23
  homepage: http://www.ruby-lang.org
25
- licenses: []
24
+ licenses:
25
+ - ruby
26
+ metadata: {}
26
27
  post_install_message:
27
28
  rdoc_options: []
28
29
  require_paths:
29
- - .
30
+ - "."
30
31
  required_ruby_version: !ruby/object:Gem::Requirement
31
- none: false
32
32
  requirements:
33
- - - ! '>='
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: '0'
36
36
  required_rubygems_version: !ruby/object:Gem::Requirement
37
- none: false
38
37
  requirements:
39
- - - ! '>='
38
+ - - ">="
40
39
  - !ruby/object:Gem::Version
41
40
  version: '0'
42
41
  requirements: []
43
42
  rubyforge_project:
44
- rubygems_version: 1.8.10
43
+ rubygems_version: 2.0.0.rc.2
45
44
  signing_key:
46
- specification_version: 3
45
+ specification_version: 4
47
46
  summary: Console interface
48
47
  test_files: []