io-console 0.3 → 0.4.1

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