[前][次][番号順一覧][スレッド一覧]

ruby-changes:57696

From: Nobuyoshi <ko1@a...>
Date: Tue, 10 Sep 2019 08:25:41 +0900 (JST)
Subject: [ruby-changes:57696] 803dc9e1e4 (master): [ruby/io-console] Added console_vt_response

https://git.ruby-lang.org/ruby.git/commit/?id=803dc9e1e4

From 803dc9e1e48325515bf7c5ce176cf2b5bc0792a9 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Mon, 9 Sep 2019 23:14:30 +0900
Subject: [ruby/io-console] Added console_vt_response

A function to query console info.

https://github.com/ruby/io-console/commit/db75a07fa3

diff --git a/ext/io/console/console.c b/ext/io/console/console.c
index c378726..b50a73e 100644
--- a/ext/io/console/console.c
+++ b/ext/io/console/console.c
@@ -104,11 +104,21 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L104
 } rawmode_arg_t;
 
 static rawmode_arg_t *
-rawmode_opt(int argc, VALUE *argv, rawmode_arg_t *opts)
+rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts)
 {
+    int argc = *argcp;
     rawmode_arg_t *optp = NULL;
-    VALUE vopts;
-    rb_scan_args(argc, argv, "0:", &vopts);
+    VALUE vopts = Qnil;
+    if (argc > min_argc)  {
+	vopts = rb_check_hash_type(argv[argc-1]);
+	if (!NIL_P(vopts)) {
+	    argv[argc-1] = vopts;
+	    vopts = rb_extract_keywords(&argv[argc-1]);
+	    if (!argv[argc-1]) *argcp = --argc;
+	    if (!vopts) vopts = Qnil;
+	}
+    }
+    rb_check_arity(argc, min_argc, max_argc);
     if (!NIL_P(vopts)) {
 	VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
 	VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
@@ -233,7 +243,7 @@ get_write_fd(const rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L243
 #define FD_PER_IO 2
 
 static VALUE
-ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void *arg)
+ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
 {
     rb_io_t *fptr;
     int status = -1;
@@ -264,7 +274,7 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L274
 	}
     }
     if (status == 0) {
-	result = rb_protect(func, io, &status);
+	result = rb_protect(func, farg, &status);
     }
     GetOpenFile(io, fptr);
     if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
@@ -288,6 +298,29 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L298
     return result;
 }
 
+struct ttymode_callback_args {
+    VALUE (*func)(VALUE, VALUE);
+    VALUE io;
+    VALUE farg;
+};
+
+static VALUE
+ttymode_callback(VALUE args)
+{
+    struct ttymode_callback_args *argp = (struct ttymode_callback_args *)args;
+    return argp->func(argp->io, argp->farg);
+}
+
+static VALUE
+ttymode_with_io(VALUE io, VALUE (*func)(VALUE, VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg)
+{
+    struct ttymode_callback_args cargs;
+    cargs.func = func;
+    cargs.io = io;
+    cargs.farg = farg;
+    return ttymode(io, ttymode_callback, (VALUE)&cargs, setter, arg);
+}
+
 /*
  * call-seq:
  *   io.raw(min: nil, time: nil) {|io| }
@@ -311,8 +344,8 @@ ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *, void *), void https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L344
 static VALUE
 console_raw(int argc, VALUE *argv, VALUE io)
 {
-    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
-    return ttymode(io, rb_yield, set_rawmode, optp);
+    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
+    return ttymode(io, rb_yield, io, set_rawmode, optp);
 }
 
 /*
@@ -333,7 +366,7 @@ console_set_raw(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L366
     conmode t;
     rb_io_t *fptr;
     int fd;
-    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
+    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
 
     GetOpenFile(io, fptr);
     fd = GetReadFD(fptr);
@@ -358,7 +391,7 @@ console_set_raw(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L391
 static VALUE
 console_cooked(VALUE io)
 {
-    return ttymode(io, rb_yield, set_cookedmode, NULL);
+    return ttymode(io, rb_yield, io, set_cookedmode, NULL);
 }
 
 /*
@@ -407,9 +440,9 @@ getc_call(VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L440
 static VALUE
 console_getch(int argc, VALUE *argv, VALUE io)
 {
-    rawmode_arg_t opts, *optp = rawmode_opt(argc, argv, &opts);
+    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts);
 #ifndef _WIN32
-    return ttymode(io, getc_call, set_rawmode, optp);
+    return ttymode(io, getc_call, io, set_rawmode, optp);
 #else
     rb_io_t *fptr;
     VALUE str;
@@ -468,7 +501,7 @@ console_getch(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L501
 static VALUE
 console_noecho(VALUE io)
 {
-    return ttymode(io, rb_yield, set_noecho, NULL);
+    return ttymode(io, rb_yield, io, set_noecho, NULL);
 }
 
 /*
@@ -805,6 +838,43 @@ console_key_pressed_p(VALUE io, VALUE k) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L838
 # define console_goto rb_f_notimplement
 # define console_cursor_pos rb_f_notimplement
 # define console_cursor_set rb_f_notimplement
+static VALUE
+read_vt_response(VALUE io, VALUE query)
+{
+    VALUE result, b;
+    int num = 0;
+    if (!NIL_P(query)) rb_io_write(io, query);
+    rb_io_flush(io);
+    if (rb_io_getbyte(io) != INT2FIX(0x1b)) return Qnil;
+    if (rb_io_getbyte(io) != INT2FIX('[')) return Qnil;
+    result = rb_ary_new();
+    while (!NIL_P(b = rb_io_getbyte(io))) {
+	int c = NUM2UINT(b);
+	if (c == ';') {
+	    rb_ary_push(result, INT2NUM(num));
+	    num = 0;
+	}
+	else if (ISDIGIT(c)) {
+	    num = num * 10 + c - '0';
+	}
+	else {
+	    char last = (char)c;
+	    rb_ary_push(result, INT2NUM(num));
+	    b = rb_str_new(&last, 1);
+	    break;
+	}
+    }
+    return rb_ary_push(result, b);
+}
+
+static VALUE
+console_vt_response(int argc, VALUE *argv, VALUE io)
+{
+    rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 1, &opts);
+    VALUE query = argc ? argv[0] : Qnil;
+    VALUE ret = ttymode_with_io(io, read_vt_response, query, set_rawmode, optp);
+    return ret;
+}
 # define console_key_pressed_p rb_f_notimplement
 #endif
 
@@ -927,7 +997,7 @@ puts_call(VALUE io) https://github.com/ruby/ruby/blob/trunk/ext/io/console/console.c#L997
 static VALUE
 getpass_call(VALUE io)
 {
-    return ttymode(io, rb_io_gets, set_noecho, NULL);
+    return ttymode(io, rb_io_gets, io, set_noecho, NULL);
 }
 
 static void
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]