
This patch syncs our upstream copy of readline from version 6.2 to the latest version, 7.0 alpha (released July 10 2015). I essentially copied what was done the last time readline was synced, when Jan updated to readline 6.2 in 2011: http://sourceware.org/ml/gdb-patches/2011-05/msg00003.html Procedure: 1. I extracted the readline-7.0-alpha tarball on top of readline/. 2. I deleted all the new files under doc/ that were deliberately omitted before. 3. I regenerated readline/configure and readline/examples/rlfe/configure using autoconf 2.64. No other configure files need regenerating. 4. I updated the function gdb_printable_part in completer.c with a trivial change made to the readline function it is based off of, printable_part in readline/complete.c. There is more work to be done in completer.c to sync it with readline/complete.c, but it is non-trivial and should probably be done separately anyway. Local patches that had to be reapplied: None. readline 7.0 alpha contains all of our local readline patches. New files in readline/: colors.{c,h} examples/{hist_erasedups,hist_purgecmd,rl-callbacktest,rlbasic}.c parse-colors.{c,h} readline.pc.in configure.ac Deleted files in readline/: configure.in Regressions: After the sync there is one testsuite regression, the test "signal SIGINT" in gdb.gdb/selftest.exp which now FAILs. Previously, the readline 6.2 SIGINT handler would temporarily reinstall the underlying application's SIGINT handler and immediately re-raise SIGINT so that the orginal handler gets invoked. But now (since readline 6.3) its SIGINT handler does not re-raise SIGINT or directly invoke the original handler; it now sets a flag marking that SIGINT was raised, and waits until readline explicitly has control to call the application's SIGINT handler. Anyway, because SIGINT is no longer re-raised from within readline's SIGINT handler, doing "signal SIGINT" with a stopped inferior gdb process will no longer resume and then immediately stop the process (since there is no 2nd SIGINT to immediately catch). Instead, the inferior gdb process will now just print "Quit" and continue to run. So with this commit, this particular test case is adjusted to reflect this change in behavior (we now have to send a 2nd SIGINT manually to stop it). Aside from this one testsuite regression, I personally noticed no regression in user-visible behavior. Though I only tested on x86_64 and on i686 Debian Stretch. Getting this kind of change in at the start of the GDB 7.11 development cycle will allow us to get a lot of passive testing from developers and from bleeding-edge users. readline/ChangeLog.gdb: Import readline 7.0 alpha * configure: Regenerate. * examples/rlfe/configure: Regenerate. gdb/ChangeLog: * completer.c (gdb_printable_part): Sync with readline function it is based off of. gdb/testsuite/ChangeLog: * gdb.gdb/selftest.exp (test_with_self): Update test to now expect the GDB inferior to no longer immediately stop after being resumed with "signal SIGINT".
196 lines
5.7 KiB
C
196 lines
5.7 KiB
C
/*
|
|
From: Jeff Solomon <jsolomon@stanford.edu>
|
|
Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT)
|
|
To: chet@po.cwru.edu
|
|
Subject: new readline example
|
|
Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>
|
|
|
|
Chet,
|
|
|
|
I've been using readline 4.0. Specifically, I've been using the perl
|
|
version Term::ReadLine::Gnu. It works great.
|
|
|
|
Anyway, I've been playing around the alternate interface and I wanted
|
|
to contribute a little C program, callback.c, to you that you could
|
|
use as an example of the alternate interface in the /examples
|
|
directory of the readline distribution.
|
|
|
|
My example shows how, using the alternate interface, you can
|
|
interactively change the prompt (which is very nice imo). Also, I
|
|
point out that you must roll your own terminal setting when using the
|
|
alternate interface because readline depreps (using your parlance) the
|
|
terminal while in the user callback. I try to demostrate what I mean
|
|
with an example. I've included the program below.
|
|
|
|
To compile, I just put the program in the examples directory and made
|
|
the appropriate changes to the EXECUTABLES and OBJECTS line and added
|
|
an additional target 'callback'.
|
|
|
|
I compiled on my Sun Solaris2.6 box using Sun's cc.
|
|
|
|
Let me know what you think.
|
|
|
|
Jeff
|
|
*/
|
|
/*
|
|
Copyright (C) 1999 Jeff Solomon
|
|
*/
|
|
|
|
#if defined (HAVE_CONFIG_H)
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
#include <termios.h> /* xxx - should make this more general */
|
|
|
|
#ifdef READLINE_LIBRARY
|
|
# include "readline.h"
|
|
#else
|
|
# include <readline/readline.h>
|
|
#endif
|
|
|
|
#ifndef STDIN_FILENO
|
|
# define STDIN_FILENO 0
|
|
#endif
|
|
|
|
/* This little examples demonstrates the alternate interface to using readline.
|
|
* In the alternate interface, the user maintains control over program flow and
|
|
* only calls readline when STDIN is readable. Using the alternate interface,
|
|
* you can do anything else while still using readline (like talking to a
|
|
* network or another program) without blocking.
|
|
*
|
|
* Specifically, this program highlights two importants features of the
|
|
* alternate interface. The first is the ability to interactively change the
|
|
* prompt, which can't be done using the regular interface since rl_prompt is
|
|
* read-only.
|
|
*
|
|
* The second feature really highlights a subtle point when using the alternate
|
|
* interface. That is, readline will not alter the terminal when inside your
|
|
* callback handler. So let's so, your callback executes a user command that
|
|
* takes a non-trivial amount of time to complete (seconds). While your
|
|
* executing the command, the user continues to type keystrokes and expects them
|
|
* to be re-echoed on the new prompt when it returns. Unfortunately, the default
|
|
* terminal configuration doesn't do this. After the prompt returns, the user
|
|
* must hit one additional keystroke and then will see all of his previous
|
|
* keystrokes. To illustrate this, compile and run this program. Type "sleep" at
|
|
* the prompt and then type "bar" before the prompt returns (you have 3
|
|
* seconds). Notice how "bar" is re-echoed on the prompt after the prompt
|
|
* returns? This is what you expect to happen. Now comment out the 4 lines below
|
|
* the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
|
|
* the same thing. When the prompt returns, you should not see "bar". Now type
|
|
* "f", see how "barf" magically appears? This behavior is un-expected and not
|
|
* desired.
|
|
*/
|
|
|
|
void process_line(char *line);
|
|
int change_prompt(void);
|
|
char *get_prompt(void);
|
|
|
|
int prompt = 1;
|
|
char prompt_buf[40], line_buf[256];
|
|
tcflag_t old_lflag;
|
|
cc_t old_vtime;
|
|
struct termios term;
|
|
|
|
int
|
|
main()
|
|
{
|
|
fd_set fds;
|
|
|
|
/* Adjust the terminal slightly before the handler is installed. Disable
|
|
* canonical mode processing and set the input character time flag to be
|
|
* non-blocking.
|
|
*/
|
|
if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
|
|
perror("tcgetattr");
|
|
exit(1);
|
|
}
|
|
old_lflag = term.c_lflag;
|
|
old_vtime = term.c_cc[VTIME];
|
|
term.c_lflag &= ~ICANON;
|
|
term.c_cc[VTIME] = 1;
|
|
/* COMMENT LINE BELOW - see above */
|
|
if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
|
|
perror("tcsetattr");
|
|
exit(1);
|
|
}
|
|
|
|
rl_add_defun("change-prompt", change_prompt, CTRL('t'));
|
|
rl_callback_handler_install(get_prompt(), process_line);
|
|
|
|
while(1) {
|
|
FD_ZERO(&fds);
|
|
FD_SET(fileno(stdin), &fds);
|
|
|
|
if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
|
|
perror("select");
|
|
exit(1);
|
|
}
|
|
|
|
if( FD_ISSET(fileno(stdin), &fds) ) {
|
|
rl_callback_read_char();
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
process_line(char *line)
|
|
{
|
|
if( line == NULL ) {
|
|
fprintf(stderr, "\n", line);
|
|
|
|
/* reset the old terminal setting before exiting */
|
|
term.c_lflag = old_lflag;
|
|
term.c_cc[VTIME] = old_vtime;
|
|
if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
|
|
perror("tcsetattr");
|
|
exit(1);
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
if( strcmp(line, "sleep") == 0 ) {
|
|
sleep(3);
|
|
} else {
|
|
fprintf(stderr, "|%s|\n", line);
|
|
}
|
|
|
|
free (line);
|
|
}
|
|
|
|
int
|
|
change_prompt(void)
|
|
{
|
|
/* toggle the prompt variable */
|
|
prompt = !prompt;
|
|
|
|
/* save away the current contents of the line */
|
|
strcpy(line_buf, rl_line_buffer);
|
|
|
|
/* install a new handler which will change the prompt and erase the current line */
|
|
rl_callback_handler_install(get_prompt(), process_line);
|
|
|
|
/* insert the old text on the new line */
|
|
rl_insert_text(line_buf);
|
|
|
|
/* redraw the current line - this is an undocumented function. It invokes the
|
|
* redraw-current-line command.
|
|
*/
|
|
rl_refresh_line(0, 0);
|
|
}
|
|
|
|
char *
|
|
get_prompt(void)
|
|
{
|
|
/* The prompts can even be different lengths! */
|
|
sprintf(prompt_buf, "%s",
|
|
prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
|
|
return prompt_buf;
|
|
}
|