* tuiIO.c (tui_putc): New function to print one character.

(printable_part): New function from readline/complete.c.
	(PUTX): New macro, likewise.
	(print_filename): New function, likewise.
	(get_y_or_n): New function, likewise and adapted for TUI.
	(tui_rl_display_match_list): New function from readline/complete.c
	and writes on TUI command window.
	(tui_setup_io): Install or remove the readline hook
	rl_completion_display_matches_hook so that completion is written
	directly in TUI command window instead of in the TUI pipe.
	(tui_initialize_io): Use #ifdef TUI_USE_PIPE_FOR_READLINE for the
	TUI redirection pipe.
	(tui_getc): Likewise for call to tui_readline_output.
	(tui_readline_output): Likewise for function.
	* tui.c (tui_rl_startup_hook): Always take care of gdb prompt.
This commit is contained in:
Stephane Carrez 2002-09-03 20:47:48 +00:00
parent 38fc42c80d
commit 8cee930b67
3 changed files with 248 additions and 14 deletions

View File

@ -1,3 +1,21 @@
2002-09-04 Stephane Carrez <stcarrez@nerim.fr>
* tuiIO.c (tui_putc): New function to print one character.
(printable_part): New function from readline/complete.c.
(PUTX): New macro, likewise.
(print_filename): New function, likewise.
(get_y_or_n): New function, likewise and adapted for TUI.
(tui_rl_display_match_list): New function from readline/complete.c
and writes on TUI command window.
(tui_setup_io): Install or remove the readline hook
rl_completion_display_matches_hook so that completion is written
directly in TUI command window instead of in the TUI pipe.
(tui_initialize_io): Use #ifdef TUI_USE_PIPE_FOR_READLINE for the
TUI redirection pipe.
(tui_getc): Likewise for call to tui_readline_output.
(tui_readline_output): Likewise for function.
* tui.c (tui_rl_startup_hook): Always take care of gdb prompt.
2002-09-02 Stephane Carrez <stcarrez@nerim.fr>
* tuiWin.c (_newHeightOk): Fix compilation warnings.

View File

@ -270,12 +270,10 @@ tui_rl_next_keymap (void)
static int
tui_rl_startup_hook ()
{
rl_already_prompted = (tui_current_key_mode != tui_command_mode);
if (rl_already_prompted)
{
tui_set_key_mode (tui_single_key_mode);
tui_redisplay_readline ();
}
rl_already_prompted = 1;
if (tui_current_key_mode != tui_command_mode)
tui_set_key_mode (tui_single_key_mode);
tui_redisplay_readline ();
return 0;
}

View File

@ -80,14 +80,24 @@
is as if TUI is not used. Readline also uses its original getc()
function with stdin.
Note: the current readline is not clean in its management of the output.
Even if we install a redisplay handler, it sometimes writes on a stdout
file. It is important to redirect every output produced by readline,
otherwise the curses window will be garbled. This is implemented with
a pipe that TUI reads and readline writes to. A gdb input handler
Note SCz/2001-07-21: the current readline is not clean in its management of
the output. Even if we install a redisplay handler, it sometimes writes on
a stdout file. It is important to redirect every output produced by
readline, otherwise the curses window will be garbled. This is implemented
with a pipe that TUI reads and readline writes to. A gdb input handler
is created so that reading the pipe is handled automatically.
This will probably not work on non-Unix platforms. The best fix is
to make readline clean enougth so that is never write on stdout. */
to make readline clean enougth so that is never write on stdout.
Note SCz/2002-09-01: we now use more readline hooks and it seems that
with them we don't need the pipe anymore (verified by creating the pipe
and closing its end so that write causes a SIGPIPE). The old pipe code
is still there and can be conditionally removed by
#undef TUI_USE_PIPE_FOR_READLINE. */
/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */
#define TUI_USE_PIPE_FOR_READLINE
/*#undef TUI_USE_PIPE_FOR_READLINE*/
/* TUI output files. */
static struct ui_file *tui_stdout;
@ -110,10 +120,21 @@ static int tui_old_readline_echoing_p;
Should be removed when readline is clean. */
static FILE *tui_rl_outstream;
static FILE *tui_old_rl_outstream;
#ifdef TUI_USE_PIPE_FOR_READLINE
static int tui_readline_pipe[2];
#endif
static unsigned int _tuiHandleResizeDuringIO (unsigned int);
static void
tui_putc (char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
tui_puts (buf);
}
/* Print the string in the curses command window. */
void
@ -243,6 +264,7 @@ tui_deprep_terminal (void)
{
}
#ifdef TUI_USE_PIPE_FOR_READLINE
/* Read readline output pipe and feed the command window with it.
Should be removed when readline is clean. */
static void
@ -258,6 +280,193 @@ tui_readline_output (int code, gdb_client_data data)
tui_puts (buf);
}
}
#endif
/* Return the portion of PATHNAME that should be output when listing
possible completions. If we are hacking filename completion, we
are only interested in the basename, the portion following the
final slash. Otherwise, we return what we were passed.
Comes from readline/complete.c */
static char *
printable_part (pathname)
char *pathname;
{
char *temp;
temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL;
#if defined (__MSDOS__)
if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':')
temp = pathname + 1;
#endif
return (temp ? ++temp : pathname);
}
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
are using it, check for and output a single character for `special'
filenames. Return the number of characters we output. */
#define PUTX(c) \
do { \
if (CTRL_CHAR (c)) \
{ \
tui_puts ("^"); \
tui_putc (UNCTRL (c)); \
printed_len += 2; \
} \
else if (c == RUBOUT) \
{ \
tui_puts ("^?"); \
printed_len += 2; \
} \
else \
{ \
tui_putc (c); \
printed_len++; \
} \
} while (0)
static int
print_filename (to_print, full_pathname)
char *to_print, *full_pathname;
{
int printed_len = 0;
char *s;
for (s = to_print; *s; s++)
{
PUTX (*s);
}
return printed_len;
}
/* The user must press "y" or "n". Non-zero return means "y" pressed.
Comes from readline/complete.c */
static int
get_y_or_n ()
{
extern int _rl_abort_internal ();
int c;
for (;;)
{
c = rl_read_key ();
if (c == 'y' || c == 'Y' || c == ' ')
return (1);
if (c == 'n' || c == 'N' || c == RUBOUT)
return (0);
if (c == ABORT_CHAR)
_rl_abort_internal ();
beep ();
}
}
/* A convenience function for displaying a list of strings in
columnar format on readline's output stream. MATCHES is the list
of strings, in argv format, LEN is the number of strings in MATCHES,
and MAX is the length of the longest string in MATCHES.
Comes from readline/complete.c and modified to write in
the TUI command window using tui_putc/tui_puts. */
static void
tui_rl_display_match_list (matches, len, max)
char **matches;
int len, max;
{
typedef int QSFUNC (const void *, const void *);
extern int _rl_qsort_string_compare (const void*, const void*);
extern int _rl_print_completions_horizontally;
int count, limit, printed_len;
int i, j, k, l;
char *temp;
/* Screen dimension correspond to the TUI command window. */
int screenwidth = cmdWin->generic.width;
/* If there are many items, then ask the user if she really wants to
see them all. */
if (len >= rl_completion_query_items)
{
char msg[256];
sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len);
tui_puts (msg);
if (get_y_or_n () == 0)
{
tui_puts ("\n");
return;
}
}
/* How many items of MAX length can we fit in the screen window? */
max += 2;
limit = screenwidth / max;
if (limit != 1 && (limit * max == screenwidth))
limit--;
/* Avoid a possible floating exception. If max > screenwidth,
limit will be 0 and a divide-by-zero fault will result. */
if (limit == 0)
limit = 1;
/* How many iterations of the printing loop? */
count = (len + (limit - 1)) / limit;
/* Watch out for special case. If LEN is less than LIMIT, then
just do the inner printing loop.
0 < len <= limit implies count = 1. */
/* Sort the items if they are not already sorted. */
if (rl_ignore_completion_duplicates == 0)
qsort (matches + 1, len, sizeof (char *),
(QSFUNC *)_rl_qsort_string_compare);
tui_putc ('\n');
if (_rl_print_completions_horizontally == 0)
{
/* Print the sorted items, up-and-down alphabetically, like ls. */
for (i = 1; i <= count; i++)
{
for (j = 0, l = i; j < limit; j++)
{
if (l > len || matches[l] == 0)
break;
else
{
temp = printable_part (matches[l]);
printed_len = print_filename (temp, matches[l]);
if (j + 1 < limit)
for (k = 0; k < max - printed_len; k++)
tui_putc (' ');
}
l += count;
}
tui_putc ('\n');
}
}
else
{
/* Print the sorted items, across alphabetically, like ls -x. */
for (i = 1; matches[i]; i++)
{
temp = printable_part (matches[i]);
printed_len = print_filename (temp, matches[i]);
/* Have we reached the end of this line? */
if (matches[i+1])
{
if (i && (limit > 1) && (i % limit) == 0)
tui_putc ('\n');
else
for (k = 0; k < max - printed_len; k++)
tui_putc (' ');
}
}
tui_putc ('\n');
}
}
/* Setup the IO for curses or non-curses mode.
- In non-curses mode, readline and gdb use the standard input and
@ -288,6 +497,8 @@ tui_setup_io (int mode)
readline_echoing_p = 0;
rl_outstream = tui_rl_outstream;
rl_prompt = 0;
rl_completion_display_matches_hook = tui_rl_display_match_list;
rl_already_prompted = 0;
/* Keep track of previous gdb output. */
tui_old_stdout = gdb_stdout;
@ -319,7 +530,9 @@ tui_setup_io (int mode)
rl_prep_term_function = tui_old_rl_prep_terminal;
rl_getc_function = tui_old_rl_getc_function;
rl_outstream = tui_old_rl_outstream;
rl_completion_display_matches_hook = 0;
readline_echoing_p = tui_old_readline_echoing_p;
rl_already_prompted = 1;
/* Save tty for SIGCONT. */
savetty ();
@ -367,6 +580,7 @@ tui_initialize_io ()
a init_ui_hook. */
uiout = cli_out_new (gdb_stdout);
#ifdef TUI_USE_PIPE_FOR_READLINE
/* Temporary solution for readline writing to stdout:
redirect readline output in a pipe, read that pipe and
output the content in the curses command window. */
@ -390,8 +604,10 @@ tui_initialize_io ()
(void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
#endif
#endif
add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
#else
tui_rl_outstream = stdout;
#endif
}
/* Get a character from the command window. This is called from the readline
@ -404,9 +620,11 @@ tui_getc (FILE *fp)
w = cmdWin->generic.handle;
#ifdef TUI_USE_PIPE_FOR_READLINE
/* Flush readline output. */
tui_readline_output (GDB_READABLE, 0);
#endif
ch = wgetch (w);
ch = _tuiHandleResizeDuringIO (ch);