From 7578bc35f9b6a2e88f43a5c48dc1b209fc972eaa Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 22 Oct 2023 11:52:15 +0900 Subject: [PATCH] [ruby/io-console] Intersperse Win32 and termios implementations So that the both sources appear in RDoc generated HTMLs. https://github.com/ruby/io-console/commit/beec164a47 --- ext/io/console/console.c | 265 ++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 141 deletions(-) diff --git a/ext/io/console/console.c b/ext/io/console/console.c index e852d68eed..f4257446c8 100644 --- a/ext/io/console/console.c +++ b/ext/io/console/console.c @@ -1010,67 +1010,6 @@ mode_in_range(VALUE val, int high, const char *modename) } #if defined _WIN32 -static VALUE -console_goto(VALUE io, VALUE y, VALUE x) -{ - COORD pos; - int fd = GetWriteFD(io); - pos.X = NUM2UINT(x); - pos.Y = NUM2UINT(y); - if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - -static VALUE -console_cursor_pos(VALUE io) -{ - rb_console_size_t ws; - int fd = GetWriteFD(io); - if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X)); -} - -static VALUE -console_move(VALUE io, int y, int x) -{ - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - pos->X += x; - pos->Y += y; - if (!SetConsoleCursorPosition(h, *pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - -static VALUE -console_goto_column(VALUE io, VALUE val) -{ - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - pos->X = NUM2INT(val); - if (!SetConsoleCursorPosition(h, *pos)) { - rb_syserr_fail(LAST_ERROR, 0); - } - return io; -} - static void constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) { @@ -1080,74 +1019,6 @@ constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) FillConsoleOutputCharacterW(handle, L' ', len, pos, &written); } -static VALUE -console_erase_line(VALUE io, VALUE val) -{ - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - DWORD w; - int mode = mode_in_range(val, 2, "line erase"); - - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - w = winsize_col(&ws); - switch (mode) { - case 0: /* after cursor */ - w -= pos->X; - break; - case 1: /* before *and* cursor */ - w = pos->X + 1; - pos->X = 0; - break; - case 2: /* entire line */ - pos->X = 0; - break; - } - constat_clear(h, ws.wAttributes, w, *pos); - return io; -} - -static VALUE -console_erase_screen(VALUE io, VALUE val) -{ - HANDLE h; - rb_console_size_t ws; - COORD *pos = &ws.dwCursorPosition; - DWORD w; - int mode = mode_in_range(val, 3, "screen erase"); - - h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); - if (!GetConsoleScreenBufferInfo(h, &ws)) { - rb_syserr_fail(LAST_ERROR, 0); - } - w = winsize_col(&ws); - switch (mode) { - case 0: /* erase after cursor */ - w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X); - break; - case 1: /* erase before *and* cursor */ - w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1); - pos->X = 0; - pos->Y = ws.srWindow.Top; - break; - case 2: /* erase entire screen */ - w = (w * winsize_row(&ws)); - pos->X = 0; - pos->Y = ws.srWindow.Top; - break; - case 3: /* erase entire screen */ - w = (w * ws.dwSize.Y); - pos->X = 0; - pos->Y = 0; - break; - } - constat_clear(h, ws.wAttributes, w, *pos); - return io; -} - static VALUE console_scroll(VALUE io, int line) { @@ -1267,9 +1138,31 @@ console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qa return ret; } +static VALUE +console_scroll(VALUE io, int line) +{ + if (line) { + VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line, + line < 0 ? 'T' : 'S'); + rb_io_write(io, s); + } + return io; +} + +# define console_key_pressed_p rb_f_notimplement +#endif + static VALUE console_cursor_pos(VALUE io) { +#ifdef _WIN32 + rb_console_size_t ws; + int fd = GetWriteFD(io); + if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X)); +#else static const struct query_args query = {"\033[6n", 0}; VALUE resp = console_vt_response(0, 0, io, &query); VALUE row, column, term; @@ -1286,18 +1179,44 @@ console_cursor_pos(VALUE io) RARRAY_ASET(resp, 0, INT2NUM(r)); RARRAY_ASET(resp, 1, INT2NUM(c)); return resp; +#endif } static VALUE console_goto(VALUE io, VALUE y, VALUE x) { +#ifdef _WIN32 + COORD pos; + int fd = GetWriteFD(io); + pos.X = NUM2UINT(x); + pos.Y = NUM2UINT(y); + if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else rb_io_write(io, rb_sprintf("\x1b[%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); +#endif return io; } static VALUE console_move(VALUE io, int y, int x) { +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X += x; + pos->Y += y; + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else if (x || y) { VALUE s = rb_str_new_cstr(""); if (y) rb_str_catf(s, "\x1b[%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); @@ -1305,13 +1224,29 @@ console_move(VALUE io, int y, int x) rb_io_write(io, s); rb_io_flush(io); } +#endif return io; } static VALUE console_goto_column(VALUE io, VALUE val) { +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X = NUM2INT(val); + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else rb_io_write(io, rb_sprintf("\x1b[%dG", NUM2UINT(val)+1)); +#endif return io; } @@ -1319,7 +1254,34 @@ static VALUE console_erase_line(VALUE io, VALUE val) { int mode = mode_in_range(val, 2, "line erase"); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + w = winsize_col(&ws); + switch (mode) { + case 0: /* after cursor */ + w -= pos->X; + break; + case 1: /* before *and* cursor */ + w = pos->X + 1; + pos->X = 0; + break; + case 2: /* entire line */ + pos->X = 0; + break; + } + constat_clear(h, ws.wAttributes, w, *pos); + return io; +#else rb_io_write(io, rb_sprintf("\x1b[%dK", mode)); +#endif return io; } @@ -1327,22 +1289,43 @@ static VALUE console_erase_screen(VALUE io, VALUE val) { int mode = mode_in_range(val, 3, "screen erase"); - rb_io_write(io, rb_sprintf("\x1b[%dJ", mode)); - return io; -} +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; -static VALUE -console_scroll(VALUE io, int line) -{ - if (line) { - VALUE s = rb_sprintf("\x1b[%d%c", line < 0 ? -line : line, - line < 0 ? 'T' : 'S'); - rb_io_write(io, s); + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); } + w = winsize_col(&ws); + switch (mode) { + case 0: /* erase after cursor */ + w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X); + break; + case 1: /* erase before *and* cursor */ + w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 2: /* erase entire screen */ + w = (w * winsize_row(&ws)); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 3: /* erase entire screen */ + w = (w * ws.dwSize.Y); + pos->X = 0; + pos->Y = 0; + break; + } + constat_clear(h, ws.wAttributes, w, *pos); +#else + rb_io_write(io, rb_sprintf("\x1b[%dJ", mode)); +#endif return io; } -# define console_key_pressed_p rb_f_notimplement -#endif static VALUE console_cursor_set(VALUE io, VALUE cpos)