1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/io-console] Defer creating VT query string

https://github.com/ruby/io-console/commit/3d69c577a4
This commit is contained in:
Nobuyoshi Nakada 2019-09-26 09:54:24 +09:00
parent 9b10698705
commit 5357ceb1ca
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60

View file

@ -1151,8 +1151,13 @@ console_key_pressed_p(VALUE io, VALUE k)
return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse;
}
#else
struct query_args {
const char *qstr;
int opt;
};
static int
direct_query(VALUE io, VALUE query)
direct_query(VALUE io, const struct query_args *query)
{
if (RB_TYPE_P(io, T_FILE)) {
rb_io_t *fptr;
@ -1160,15 +1165,16 @@ direct_query(VALUE io, VALUE query)
GetOpenFile(io, fptr);
wio = fptr->tied_io_for_writing;
if (wio) {
rb_io_write(wio, query);
VALUE s = rb_str_new_cstr(query->qstr);
rb_io_write(wio, s);
rb_io_flush(wio);
return 1;
}
if (write(fptr->fd, RSTRING_PTR(query), RSTRING_LEN(query)) != -1) {
if (write(fptr->fd, query->qstr, strlen(query->qstr)) != -1) {
return 1;
}
if (fptr->fd == 0 &&
write(1, RSTRING_PTR(query), RSTRING_LEN(query)) != -1) {
write(1, query->qstr, strlen(query->qstr)) != -1) {
return 1;
}
}
@ -1178,9 +1184,14 @@ direct_query(VALUE io, VALUE query)
static VALUE
read_vt_response(VALUE io, VALUE query)
{
struct query_args *qargs = (struct query_args *)query;
VALUE result, b;
int opt = 0;
int num = 0;
if (!NIL_P(query) && !direct_query(io, query)) return Qnil;
if (qargs) {
opt = qargs->opt;
if (!direct_query(io, qargs)) return Qnil;
}
if (rb_io_getbyte(io) != INT2FIX(0x1b)) return Qnil;
if (rb_io_getbyte(io) != INT2FIX('[')) return Qnil;
result = rb_ary_new();
@ -1193,6 +1204,9 @@ read_vt_response(VALUE io, VALUE query)
else if (ISDIGIT(c)) {
num = num * 10 + c - '0';
}
else if (opt && c == opt) {
opt = 0;
}
else {
char last = (char)c;
rb_ary_push(result, INT2NUM(num));
@ -1204,10 +1218,10 @@ read_vt_response(VALUE io, VALUE query)
}
static VALUE
console_vt_response(int argc, VALUE *argv, VALUE io)
console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qargs)
{
rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 1, &opts);
VALUE query = argc ? argv[0] : Qnil;
VALUE query = (VALUE)qargs;
VALUE ret = ttymode_with_io(io, read_vt_response, query, set_rawmode, optp);
return ret;
}
@ -1215,8 +1229,8 @@ console_vt_response(int argc, VALUE *argv, VALUE io)
static VALUE
console_cursor_pos(VALUE io)
{
VALUE query = rb_str_new_cstr("\033[6n");
VALUE resp = console_vt_response(1, &query, io);
static const struct query_args query = {"\033[6n", 0};
VALUE resp = console_vt_response(0, 0, io, &query);
VALUE row, column, term;
unsigned int r, c;
if (!RB_TYPE_P(resp, T_ARRAY) || RARRAY_LEN(resp) != 3) return Qnil;