Versions: 4.1, one bundled with gdb-5.0

Platform: does not matter

rlconf.h: vanilla one; in particular, READLINE_CALLBACKS is defined

fix: patch included

The problem displays itself in incremental search behavior.

Applications using readline() behave like this:

C-r <type symbols to search>

matching line displayed

RET

matching line passed to app.

gdb (which uses rl_callback_read_char) behaves differently:

C-r

<symbols>

matching line displayed

RET

no response

RET

two lines passed to gdb: first is found one, second is empty.

Here is what happens inside gdb.  It waits for input from, generally
speaking, several file descriptors.  If it finds that input from stdin
is available, it calls rl_callback_read_char which should read
(generally) single character from input and handle it.  Handling
involves calling app callback when entire line is read (rl_done is
set).

When rl_callback_read_char reads C-r, its handling involves waiting
for more user input up to and including first RET.  Instead of
handling RET, it is left in rl_pending_input.  So user gets no
response to his RET.

gdb has to wait for one more input character (in this case it is a
second RET) to continue its work.  When it comes, gdb invokes
rl_callback_read_char, which sees that rl_pending_input is set,
empties it and handles first RET.  Second RET is left intact in stdin
system buffer.

After handling first RET gdb sees that there is still data available
from stdin.  Again it invokes rl_callback_read_char, which reads and
handles second RET.  So all entered input is handled eventually.

Perhaps that is gdb that should test for rl_pending_input in its input
event waiting routine.  Another solution is requiring
rl_callback_read_char to handle all input it reads (and makes
unavailable for common methods of reading from fd's).  The latter
solution is implemented by this patch.

*** callback.c  2000/07/01 10:01:12     1.1
--- callback.c  2000/07/01 10:15:45     1.2
***************
*** 102,126 ****
  
    eof = readline_internal_char ();
  
!   if (rl_done)
      {
!       line = readline_internal_teardown (eof);
  
!       (*rl_deprep_term_function) ();
  #if defined (HANDLE_SIGNALS)
!       rl_clear_signals ();
  #endif
!       in_handler = 0;
!       (*rl_linefunc) (line);
  
!     /* If the user did not clear out the line, do it for him. */
!     if (rl_line_buffer[0])
!       _rl_init_line_state ();
  
!     /* Redisplay the prompt if readline_handler_{install,remove} not called. */
!       if (in_handler == 0 && rl_linefunc)
!       _rl_callback_newline ();
!     }
  }
  
  /* Remove the handler, and make sure the terminal is in its normal state. */
--- 102,134 ----
  
    eof = readline_internal_char ();
  
!   do
      {
!       if (rl_done)
!       {
!         line = readline_internal_teardown (eof);
  
!         (*rl_deprep_term_function) ();
  #if defined (HANDLE_SIGNALS)
!         rl_clear_signals ();
  #endif
!         in_handler = 0;
!         (*rl_linefunc) (line);
  
!         /* If the user did not clear out the line, do it for him. */
!         if (rl_line_buffer[0])
!           _rl_init_line_state ();
  
!         /* Redisplay the prompt if readline_handler_{install,remove} not called. */
!         if (in_handler == 0 && rl_linefunc)
!           _rl_callback_newline ();
!       }
! 
!       if (rl_pending_input)
!       eof = readline_internal_char ();
!       else
!       break;
!     } while (1);
  }
  
  /* Remove the handler, and make sure the terminal is in its normal state. */

Reply via email to