This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: PATCH: operate-and-get-next


Tom Tromey writes:
 > >>>>> "Elena" == Elena Zannoni <ezannoni@cygnus.com> writes:
 > 
 > Elena> It looks to me that prompt_just_set is always 1, after it is
 > Elena> set the very first time. So it doesn't really help.
 > 
 > Quite right, sorry.
 > 
 > Elena> Instead of having this global variable, could it be possible to
 > Elena> play with installing and un-installing the hook itself?  And
 > Elena> then have rl_callback_read_char_wrapper do a check
 > 
 > Ok, I implemented this.  And it does make things cleaner.  Thanks.
 > 
 > I don't really like the hook name I chose but I was unable to think of
 > a better one.  I can rename it to whatever you like.
 > 
 > The new patch is appended.


Ok, much claner. The only thing I wonder now about is, is it necessary
to have operate_saved_history be checked in the
gdb_rl_operate_and_get_next_completion () function. It looks like it
would be always != -1 when that function is called, bacause of the way
the hooks are installed. The hooks are not null while the var is not
-1. It still needs to be a global, though.

 > 
 > It has one very ugly thing, namely the call to
 > after_char_processing_hook in start_event_loop.  Without this call,
 > if the user entered a command that caused an error, then the
 > C-o binding wouldn't work.
 > 
 > For instance I tested it like this:
 > 
 >     output 1\n    <- gives an error
 >     p 1
 >     C-p C-p       <- move up history
 >     C-o           <- re-accept the error line
 > 
 > This would fail to put `p 1' into the editing buffer.
 > 
 > The reason is that the error causes us to unwind past the call to
 > after_char_processing_hook.
 > 
 > I tried calling the hook from a cleanup in rl_callback_read_char_wrapper,
 > but that didn't work.  The problem is that the error unwinding leaves
 > the readline in a state that we can't anticipate -- the where_history()
 > value is wrong, so the operate-and-get-next completion code doesn't
 > work.
 > 
 > What I'd really like is a hook which is called at the right point
 > after the prompt is printed.  It doesn't need to be called for every
 > character (that is the conceptual problem, I think, with the appended).
 > Unfortunately calling the hook in display_gdb_prompt won't work, for
 > reasons mentioned in my first patch.
 > 
 > I guess I could try to put an `after_prompt_hook' into start_event_loop.
 > This might work ok.  What would you think of that?  Or is there
 > another approach you'd like me to try?
 > 

I cannot think of another approach at the moment. But I agree that a
different hook in start_event_loop could be used. The
after_char_processing_hook seems a bit out of place there.

Elena


 > Thanks,
 > Tom
 > 
 > 
 > Index: ChangeLog
 > from  Tom Tromey  <tromey@redhat.com>
 > 
 > 	* event-loop.c (start_event_loop): Call
 > 	after_char_processing_hook.
 > 	* event-top.h (after_char_processing_hook): Declare.
 > 	* event-top.c (rl_callback_read_char_wrapper): Call
 > 	after_char_processing_hook.
 > 	(after_char_processing_hook): New global.
 > 	* top.c (operate_saved_history): New global.
 > 	(gdb_rl_operate_and_get_next): New function.
 > 	(init_main): Add the operate-and-get-next defun.
 > 	(gdb_rl_operate_and_get_next_completion): New function.
 > 
 > Index: event-loop.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/event-loop.c,v
 > retrieving revision 1.16
 > diff -u -r1.16 event-loop.c
 > --- event-loop.c 2001/03/27 20:36:23 1.16
 > +++ event-loop.c 2001/10/13 17:11:13
 > @@ -402,6 +402,14 @@
 >  	     interface specific, because interfaces can display the
 >  	     prompt in their own way. */
 >  	  display_gdb_prompt (0);
 > +	  /* This call looks bizarre, but it is required.  If the user
 > +	     entered a command that caused an error,
 > +	     after_char_processing_hook won't be called from
 > +	     rl_callback_read_char_wrapper.  Using a cleanup there
 > +	     won't work, since we want this function to be called
 > +	     after a new prompt is printed.  */
 > +	  if (after_char_processing_hook)
 > +	    (*after_char_processing_hook) ();
 >  	  /* Maybe better to set a flag to be checked somewhere as to
 >  	     whether display the prompt or not. */
 >  	}
 > Index: event-top.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/event-top.c,v
 > retrieving revision 1.16
 > diff -u -r1.16 event-top.c
 > --- event-top.c 2001/08/27 22:39:55 1.16
 > +++ event-top.c 2001/10/13 17:11:15
 > @@ -153,6 +153,10 @@
 >      char *linebuffer_ptr;
 >    }
 >  readline_input_state;
 > +
 > +/* This hook is called by rl_callback_read_char_wrapper after each
 > +   character is processed.  */
 > +void (*after_char_processing_hook) ();
 >  
 >  
 >  /* Wrapper function for calling into the readline library. The event
 > @@ -162,6 +166,8 @@
 >  rl_callback_read_char_wrapper (gdb_client_data client_data)
 >  {
 >    rl_callback_read_char ();
 > +  if (after_char_processing_hook)
 > +    (*after_char_processing_hook) ();
 >  }
 >  
 >  /* Initialize all the necessary variables, start the event loop,
 > Index: event-top.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/event-top.h,v
 > retrieving revision 1.3
 > diff -u -r1.3 event-top.h
 > --- event-top.h 2001/04/20 14:25:59 1.3
 > +++ event-top.h 2001/10/13 17:11:15
 > @@ -108,3 +108,4 @@
 >  extern void (*call_readline) (void *);
 >  extern void (*input_handler) (char *);
 >  extern int input_fd;
 > +extern void (*after_char_processing_hook) (void);
 > Index: top.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/top.c,v
 > retrieving revision 1.45
 > diff -u -r1.45 top.c
 > --- top.c 2001/09/07 21:33:08 1.45
 > +++ top.c 2001/10/13 17:11:17
 > @@ -1032,6 +1032,55 @@
 >  #endif
 >  }
 >  
 > +/* The current saved history number from operate-and-get-next.
 > +   This is -1 if not valid.  */
 > +static int operate_saved_history = -1;
 > +
 > +/* This is put on the appropriate hook and helps operate-and-get-next
 > +   do its work.  */
 > + void
 > +gdb_rl_operate_and_get_next_completion ()
 > +{
 > +  if (operate_saved_history != -1)
 > +    {
 > +      int delta = where_history () - operate_saved_history;
 > +      /* The `key' argument to rl_get_previous_history is ignored.  */
 > +      rl_get_previous_history (delta, 0);
 > +      operate_saved_history = -1;
 > +
 > +      /* readline doesn't automatically update the display for us.  */
 > +      rl_redisplay ();
 > +
 > +      after_char_processing_hook = NULL;
 > +      rl_pre_input_hook = NULL;
 > +    }
 > +}
 > +
 > +/* This is a gdb-local readline command handler.  It accepts the
 > +   current command line (like RET does) and, if this command was taken
 > +   from the history, arranges for the next command in the history to
 > +   appear on the command line when the prompt returns.
 > +   We ignore the arguments.  */
 > +static int
 > +gdb_rl_operate_and_get_next (int count, int key)
 > +{
 > +  if (event_loop_p)
 > +    {
 > +      /* Use the async hook.  */
 > +      after_char_processing_hook = gdb_rl_operate_and_get_next_completion;
 > +    }
 > +  else
 > +    {
 > +      /* This hook only works correctly when we are using the
 > +	 synchronous readline.  */
 > +      rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion;
 > +    }
 > +
 > +  /* Add 1 because we eventually want the next line.  */
 > +  operate_saved_history = where_history () + 1;
 > +  return rl_newline (1, key);
 > +}
 > +
 >  /* Read one line from the command input stream `instream'
 >     into the local static buffer `linebuffer' (whose current length
 >     is `linelength').
 > @@ -1881,6 +1930,10 @@
 >  				 get_gdb_completer_word_break_characters ();
 >    rl_completer_quote_characters = get_gdb_completer_quote_characters ();
 >    rl_readline_name = "gdb";
 > +
 > +  /* The name for this defun comes from Bash, where it originated.
 > +     15 is Control-o, the same binding this function has in Bash.  */
 > +  rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15);
 >  
 >    /* The set prompt command is different depending whether or not the
 >       async version is run. NOTE: this difference is going to
 > Index: doc/ChangeLog
 > from  Tom Tromey  <tromey@redhat.com>
 > 
 > 	* gdb.texinfo (Command Syntax): Document C-o binding.
 > 
 > Index: doc/gdb.texinfo
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
 > retrieving revision 1.51
 > diff -u -r1.51 gdb.texinfo
 > --- doc/gdb.texinfo 2001/09/12 19:49:52 1.51
 > +++ doc/gdb.texinfo 2001/10/13 17:11:34
 > @@ -1190,6 +1190,13 @@
 >  nothing.  This is useful mainly in command files (@pxref{Command
 >  Files,,Command files}).
 >  
 > +@cindex repeating command sequences
 > +@kindex C-o @r{(operate-and-get-next)}
 > +The @kbd{C-o} binding is useful for repeating a complex sequence of
 > +commands.  This command accepts the current line, like @kbd{RET}, and
 > +then fetches the next line relative to the current line from the history
 > +for editing.
 > +
 >  @node Completion
 >  @section Command completion
 >  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]