X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-io.c;h=c7df50a4f24b8a7c4f2c9241f9ae0e856bcf105d;hb=e04caa70901ed44eb9537ccdbd286fe9b0a46ce2;hp=21b2a001f5d35b90cf7533b9375b227f31a0ec24;hpb=518be979d905d8e8708c70149fdb3207aba53aa1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c index 21b2a001f5..c7df50a4f2 100644 --- a/gdb/tui/tui-io.c +++ b/gdb/tui/tui-io.c @@ -1,6 +1,6 @@ /* TUI support I/O functions. - Copyright (C) 1998-2015 Free Software Foundation, Inc. + Copyright (C) 1998-2018 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. @@ -32,6 +32,7 @@ #include "tui/tui-win.h" #include "tui/tui-wingeneral.h" #include "tui/tui-file.h" +#include "tui/tui-out.h" #include "ui-out.h" #include "cli-out.h" #include @@ -63,17 +64,6 @@ key_is_backspace (int ch) return (ch == 8); } -int -key_is_command_char (int ch) -{ - return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE) - || (ch == KEY_LEFT) || (ch == KEY_RIGHT) - || (ch == KEY_UP) || (ch == KEY_DOWN) - || (ch == KEY_SF) || (ch == KEY_SR) - || (ch == (int)'\f') - || key_is_start_sequence (ch)); -} - /* Use definition from readline 4.3. */ #undef CTRL_CHAR #define CTRL_CHAR(c) \ @@ -125,7 +115,7 @@ struct ui_out *tui_out; /* GDB output files in non-curses mode. */ static struct ui_file *tui_old_stdout; static struct ui_file *tui_old_stderr; -struct ui_out *tui_old_uiout; +cli_ui_out *tui_old_uiout; /* Readline previous hooks. */ static rl_getc_func_t *tui_old_rl_getc_function; @@ -147,63 +137,94 @@ static int tui_readline_pipe[2]; This may be the main gdb prompt or a secondary prompt. */ static char *tui_rl_saved_prompt; -static int tui_handle_resize_during_io (int, int); +/* Print a character in the curses command window. The output is + buffered. It is up to the caller to refresh the screen if + necessary. */ + +static void +do_tui_putc (WINDOW *w, char c) +{ + static int tui_skip_line = -1; + + /* Catch annotation and discard them. We need two \032 and discard + until a \n is seen. */ + if (c == '\032') + { + tui_skip_line++; + } + else if (tui_skip_line != 1) + { + tui_skip_line = -1; + /* Expand TABs, since ncurses on MS-Windows doesn't. */ + if (c == '\t') + { + int col; + + col = getcurx (w); + do + { + waddch (w, ' '); + col++; + } + while ((col % 8) != 0); + } + else + waddch (w, c); + } + else if (c == '\n') + tui_skip_line = -1; +} + +/* Update the cached value of the command window's start line based on + the window's current Y coordinate. */ + +static void +update_cmdwin_start_line () +{ + TUI_CMD_WIN->detail.command_info.start_line + = getcury (TUI_CMD_WIN->generic.handle); +} + +/* Print a character in the curses command window. The output is + buffered. It is up to the caller to refresh the screen if + necessary. */ static void tui_putc (char c) { - char buf[2]; + WINDOW *w = TUI_CMD_WIN->generic.handle; - buf[0] = c; - buf[1] = 0; - tui_puts (buf); + do_tui_putc (w, c); + update_cmdwin_start_line (); } -/* Print the string in the curses command window. - The output is buffered. It is up to the caller to refresh the screen - if necessary. */ +/* Print LENGTH characters from the buffer pointed to by BUF to the + curses command window. The output is buffered. It is up to the + caller to refresh the screen if necessary. */ + +void +tui_write (const char *buf, size_t length) +{ + WINDOW *w = TUI_CMD_WIN->generic.handle; + + for (size_t i = 0; i < length; i++) + do_tui_putc (w, buf[i]); + update_cmdwin_start_line (); +} + +/* Print a string in the curses command window. The output is + buffered. It is up to the caller to refresh the screen if + necessary. */ void tui_puts (const char *string) { - static int tui_skip_line = -1; + WINDOW *w = TUI_CMD_WIN->generic.handle; char c; - WINDOW *w; - w = TUI_CMD_WIN->generic.handle; while ((c = *string++) != 0) - { - /* Catch annotation and discard them. We need two \032 and - discard until a \n is seen. */ - if (c == '\032') - { - tui_skip_line++; - } - else if (tui_skip_line != 1) - { - tui_skip_line = -1; - /* Expand TABs, since ncurses on MS-Windows doesn't. */ - if (c == '\t') - { - int line, col; - - getyx (w, line, col); - do - { - waddch (w, ' '); - col++; - } while ((col % 8) != 0); - } - else - waddch (w, c); - } - else if (c == '\n') - tui_skip_line = -1; - } - getyx (w, TUI_CMD_WIN->detail.command_info.cur_line, - TUI_CMD_WIN->detail.command_info.curch); - TUI_CMD_WIN->detail.command_info.start_line - = TUI_CMD_WIN->detail.command_info.cur_line; + do_tui_putc (w, c); + update_cmdwin_start_line (); } /* Readline callback. @@ -214,12 +235,12 @@ tui_redisplay_readline (void) { int prev_col; int height; - int col, line; + int col; int c_pos; int c_line; int in; WINDOW *w; - char *prompt; + const char *prompt; int start_line; /* Detect when we temporarily left SingleKey and now the readline @@ -228,7 +249,7 @@ tui_redisplay_readline (void) The command could call prompt_for_continue and we must not restore SingleKey so that the prompt and normal keymap are used. */ if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0 - && immediate_quit == 0) + && !gdb_in_secondary_prompt_p (current_ui)) tui_set_key_mode (TUI_SINGLE_KEY_MODE); if (tui_current_key_mode == TUI_SINGLE_KEY_MODE) @@ -246,7 +267,7 @@ tui_redisplay_readline (void) for (in = 0; prompt && prompt[in]; in++) { waddch (w, prompt[in]); - getyx (w, line, col); + col = getcurx (w); if (col <= prev_col) height++; prev_col = col; @@ -272,7 +293,7 @@ tui_redisplay_readline (void) else if (c == '\t') { /* Expand TABs, since ncurses on MS-Windows doesn't. */ - getyx (w, line, col); + col = getcurx (w); do { waddch (w, ' '); @@ -284,24 +305,16 @@ tui_redisplay_readline (void) waddch (w, c); } if (c == '\n') - { - getyx (w, TUI_CMD_WIN->detail.command_info.start_line, - TUI_CMD_WIN->detail.command_info.curch); - } - getyx (w, line, col); + TUI_CMD_WIN->detail.command_info.start_line = getcury (w); + col = getcurx (w); if (col < prev_col) height++; prev_col = col; } wclrtobot (w); - getyx (w, TUI_CMD_WIN->detail.command_info.start_line, - TUI_CMD_WIN->detail.command_info.curch); + TUI_CMD_WIN->detail.command_info.start_line = getcury (w); if (c_line >= 0) - { - wmove (w, c_line, c_pos); - TUI_CMD_WIN->detail.command_info.cur_line = c_line; - TUI_CMD_WIN->detail.command_info.curch = c_pos; - } + wmove (w, c_line, c_pos); TUI_CMD_WIN->detail.command_info.start_line -= height - 1; wrefresh (w); @@ -384,10 +397,11 @@ static void tui_mld_erase_entire_line (const struct match_list_displayer *displayer) { WINDOW *w = TUI_CMD_WIN->generic.handle; + int cur_y = getcury (w); - wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); + wmove (w, cur_y, 0); wclrtoeol (w); - wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); + wmove (w, cur_y, 0); } /* TUI version of displayer.beep. */ @@ -408,8 +422,6 @@ tui_mld_getc (FILE *fp) WINDOW *w = TUI_CMD_WIN->generic.handle; int c = wgetch (w); - c = tui_handle_resize_during_io (c, 1); - return c; } @@ -484,7 +496,8 @@ tui_setup_io (int mode) /* Keep track of previous gdb output. */ tui_old_stdout = gdb_stdout; tui_old_stderr = gdb_stderr; - tui_old_uiout = current_uiout; + tui_old_uiout = dynamic_cast (current_uiout); + gdb_assert (tui_old_uiout != nullptr); /* Reconfigure gdb output. */ gdb_stdout = tui_stdout; @@ -536,10 +549,6 @@ tui_cont_sig (int sig) /* Force a refresh of the screen. */ tui_refresh_all_win (); - /* Update cursor position on the screen. */ - wmove (TUI_CMD_WIN->generic.handle, - TUI_CMD_WIN->detail.command_info.start_line, - TUI_CMD_WIN->detail.command_info.curch); wrefresh (TUI_CMD_WIN->generic.handle); } signal (sig, tui_cont_sig); @@ -555,8 +564,8 @@ tui_initialize_io (void) #endif /* Create tui output streams. */ - tui_stdout = tui_fileopen (stdout); - tui_stderr = tui_fileopen (stderr); + tui_stdout = new tui_file (stdout); + tui_stderr = new tui_file (stderr); tui_out = tui_out_new (tui_stdout); /* Create the default UI. */ @@ -604,7 +613,6 @@ tui_getc (FILE *fp) #endif ch = wgetch (w); - ch = tui_handle_resize_during_io (ch, 0); /* The \n must be echoed because it will not be printed by readline. */ @@ -615,9 +623,9 @@ tui_getc (FILE *fp) with empty lines with gdb prompt at beginning. Instead of that, stay on the same line but provide a visual effect to show the user we recognized the command. */ - if (rl_end == 0) + if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui)) { - wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0); + wmove (w, getcury (w), 0); /* Clear the line. This will blink the gdb prompt since it will be redrawn at the same line. */ @@ -627,23 +635,26 @@ tui_getc (FILE *fp) } else { - wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, - TUI_CMD_WIN->detail.command_info.curch); - waddch (w, ch); + /* Move cursor to the end of the command line before emitting the + newline. We need to do so because when ncurses outputs a newline + it truncates any text that appears past the end of the cursor. */ + int px, py; + getyx (w, py, px); + px += rl_end - rl_point; + py += px / TUI_CMD_WIN->generic.width; + px %= TUI_CMD_WIN->generic.width; + wmove (w, py, px); + tui_putc ('\n'); } } - if (key_is_command_char (ch)) - { /* Handle prev/next/up/down here. */ - ch = tui_dispatch_ctrl_char (ch); - } + /* Handle prev/next/up/down here. */ + ch = tui_dispatch_ctrl_char (ch); - if (ch == '\n' || ch == '\r' || ch == '\f') - TUI_CMD_WIN->detail.command_info.curch = 0; if (ch == KEY_BACKSPACE) return '\b'; - if (async_command_editing_p && key_is_start_sequence (ch)) + if (current_ui->command_editing && key_is_start_sequence (ch)) { int ch_pending; @@ -679,43 +690,43 @@ tui_getc (FILE *fp) char * tui_expand_tabs (const char *string, int col) { - int n_adjust; + int n_adjust, ncol; const char *s; char *ret, *q; /* 1. How many additional characters do we need? */ - for (n_adjust = 0, s = string; s; ) + for (ncol = col, n_adjust = 0, s = string; s; ) { s = strpbrk (s, "\t"); if (s) { - col += (s - string) + n_adjust; + ncol += (s - string) + n_adjust; /* Adjustment for the next tab stop, minus one for the TAB we replace with spaces. */ - n_adjust += 8 - (col % 8) - 1; + n_adjust += 8 - (ncol % 8) - 1; s++; } } /* Allocate the copy. */ - ret = q = xmalloc (strlen (string) + n_adjust + 1); + ret = q = (char *) xmalloc (strlen (string) + n_adjust + 1); /* 2. Copy the original string while replacing TABs with spaces. */ - for (s = string; s; ) + for (ncol = col, s = string; s; ) { - char *s1 = strpbrk (s, "\t"); + const char *s1 = strpbrk (s, "\t"); if (s1) { if (s1 > s) { strncpy (q, s, s1 - s); q += s1 - s; - col += s1 - s; + ncol += s1 - s; } do { *q++ = ' '; - col++; - } while ((col % 8) != 0); + ncol++; + } while ((ncol % 8) != 0); s1++; } else @@ -725,24 +736,3 @@ tui_expand_tabs (const char *string, int col) return ret; } - -/* Cleanup when a resize has occured. - Returns the character that must be processed. */ - -static int -tui_handle_resize_during_io (int original_ch, int for_completion) -{ - if (tui_win_resized ()) - { - tui_resize_all (); - tui_refresh_all_win (); - tui_set_win_resized_to (FALSE); - if (!for_completion) - { - dont_repeat (); - return '\n'; - } - } - - return original_ch; -}