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]
Other format: [Raw text]

Re: [RFA]: Make gdb_do_one_event public and fix uiout setting for TUI


Stephane Carrez writes:
 > Hi!
 > 
 > The TUI relies on the modification of the 'uiout' to switch correctly
 > between TUI mode and normal mode.  It installs its own ui-out function to
 > catch the output and redirect it in the appropriate curses window.
 > It installs gdb's normal ui-out function when using the plain terminal
 > (non-TUI mode).


I am a bit confused here about the uiout switch. I see that it does it
when you start up the TUI, but there is also a mode switch with
tui_switch_mode.  How does this interact with your change?

Elena


 > 
 > Since 2001-09-07, the 'do_catch_errors' function preserve the 'uiout' (for safety
 > reasons I guess).  This breaks the TUI mode switching because the 'uiout' is
 > always restored to its origin.
 > 
 > To solve the problem it's necessary to update the 'uiout' according to the TUI
 > mode at the gdb top level.  The simplest way is to make TUI provide its own
 > command loop, install a 'command_loop_hook' and do its special 'uiout' management
 > there.  To do this we have everything except that 'gdb_do_one_event' is private.
 > (It makes sense to make it public, see 'XtAppProcessEvent' for example).
 > 
 > In short, I would like approval to make 'gdb_do_one_event' a public function.
 > 
 > Ok to commit?
 > 
 > 	Stephane
 > 
 > gdb/ChangeLog
 > 
 > 2002-08-27  Stephane Carrez  <stcarrez@nerim.fr>
 > 
 > 	* event-loop.c (gdb_do_one_event): Make public.
 > 	* event-loop.h (gdb_do_one_event): Declare.
 > 
 > tui/ChangeLog
 > 
 > 2002-08-27  Stephane Carrez  <stcarrez@nerim.fr>
 > 
 > 	* tui-hooks.c (tui_event_loop): New function.
 > 	(tui_command_loop): New function to override gdb loop and make sure
 > 	uiout is set according to TUI mode.
 > 	(tui_command_loop): Install the specific TUI command hook.
 > 	* tuiIO.c (tui_initialize_io): Initialize tui_old_uiout.
 > 	(tui_uiout, tui_old_uiout): Make public.
 > 	* tuiIO.h (tui_uiout, tui_old_uiout): Declare.
 > Index: event-loop.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/event-loop.c,v
 > retrieving revision 1.18
 > diff -u -p -r1.18 event-loop.c
 > --- event-loop.c	14 May 2002 15:21:10 -0000	1.18
 > +++ event-loop.c	26 Aug 2002 20:24:38 -0000
 > @@ -210,7 +210,6 @@ static void create_file_handler (int fd,
 >  static void invoke_async_signal_handler (void);
 >  static void handle_file_event (int event_file_desc);
 >  static int gdb_wait_for_event (void);
 > -static int gdb_do_one_event (void *data);
 >  static int check_async_ready (void);
 >  static void async_queue_event (gdb_event * event_ptr, queue_position position);
 >  static gdb_event *create_file_event (int fd);
 > @@ -346,7 +345,7 @@ process_event (void)
 >     can happen if there are no event sources to wait for).  If an error
 >     occurs catch_errors() which calls this function returns zero. */
 >  
 > -static int
 > +int
 >  gdb_do_one_event (void *data)
 >  {
 >    /* Any events already waiting in the queue? */
 > Index: event-loop.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/event-loop.h,v
 > retrieving revision 1.3
 > diff -u -p -r1.3 event-loop.h
 > --- event-loop.h	6 Mar 2001 08:21:07 -0000	1.3
 > +++ event-loop.h	26 Aug 2002 20:24:38 -0000
 > @@ -85,6 +85,7 @@ queue_position;
 >  /* Exported functions from event-loop.c */
 >  
 >  extern void start_event_loop (void);
 > +extern int gdb_do_one_event (void *data);
 >  extern void delete_file_handler (int fd);
 >  extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
 >  extern void mark_async_signal_handler (struct async_signal_handler *async_handler_ptr);
 > Index: tui/tui-hooks.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/tui/tui-hooks.c,v
 > retrieving revision 1.5
 > diff -u -p -r1.5 tui-hooks.c
 > --- tui/tui-hooks.c	25 Aug 2002 19:19:50 -0000	1.5
 > +++ tui/tui-hooks.c	26 Aug 2002 20:24:39 -0000
 > @@ -46,9 +46,13 @@
 >  #include "target.h"
 >  #include "gdbcore.h"
 >  #include "event-loop.h"
 > +#include "event-top.h"
 >  #include "frame.h"
 >  #include "breakpoint.h"
 >  #include "gdb-events.h"
 > +#include "ui-out.h"
 > +#include "top.h"
 > +#include <readline/readline.h>
 >  #include <unistd.h>
 >  #include <fcntl.h>
 >  
 > @@ -66,6 +70,8 @@ int tui_target_has_run = 0;
 >  
 >  static void (* tui_target_new_objfile_chain) (struct objfile*);
 >  extern void (*selected_frame_level_changed_hook) (int);
 > +static void tui_event_loop (void);
 > +static void tui_command_loop (void);
 >  
 >  static void
 >  tui_new_objfile_hook (struct objfile* objfile)
 > @@ -372,6 +378,86 @@ tui_exit (void)
 >    tui_disable ();
 >  }
 >  
 > +/* Initialize all the necessary variables, start the event loop,
 > +   register readline, and stdin, start the loop. */
 > +static void
 > +tui_command_loop (void)
 > +{
 > +  int length;
 > +  char *a_prompt;
 > +  char *gdb_prompt = get_prompt ();
 > +
 > +  /* If we are using readline, set things up and display the first
 > +     prompt, otherwise just print the prompt. */
 > +  if (async_command_editing_p)
 > +    {
 > +      /* Tell readline what the prompt to display is and what function it
 > +         will need to call after a whole line is read. This also displays
 > +         the first prompt. */
 > +      length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
 > +      a_prompt = (char *) xmalloc (length);
 > +      strcpy (a_prompt, PREFIX (0));
 > +      strcat (a_prompt, gdb_prompt);
 > +      strcat (a_prompt, SUFFIX (0));
 > +      rl_callback_handler_install (a_prompt, input_handler);
 > +    }
 > +  else
 > +    display_gdb_prompt (0);
 > +
 > +  /* Now it's time to start the event loop. */
 > +  tui_event_loop ();
 > +}
 > +
 > +/* Start up the event loop. This is the entry point to the event loop
 > +   from the command loop. */
 > +
 > +static void
 > +tui_event_loop (void)
 > +{
 > +  /* Loop until there is nothing to do. This is the entry point to the
 > +     event loop engine. gdb_do_one_event, called via catch_errors()
 > +     will process one event for each invocation.  It blocks waits for
 > +     an event and then processes it.  >0 when an event is processed, 0
 > +     when catch_errors() caught an error and <0 when there are no
 > +     longer any event sources registered. */
 > +  while (1)
 > +    {
 > +      int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
 > +      if (result < 0)
 > +	break;
 > +
 > +      /* Update gdb output according to TUI mode.  Since catch_errors
 > +         preserves the uiout from changing, this must be done at top
 > +         level of event loop.  */
 > +      if (tui_active)
 > +        uiout = tui_out;
 > +      else
 > +        uiout = tui_old_uiout;
 > +      
 > +      if (result == 0)
 > +	{
 > +	  /* FIXME: this should really be a call to a hook that is
 > +	     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. */
 > +	}
 > +    }
 > +
 > +  /* We are done with the event loop. There are no more event sources
 > +     to listen to.  So we exit GDB. */
 > +  return;
 > +}
 > +
 >  /* Initialize the tui by installing several gdb hooks, initializing
 >     the tui IO and preparing the readline with the kind binding.  */
 >  static void
 > @@ -388,6 +474,9 @@ tui_init_hook (char *argv0)
 >  
 >    tui_initialize_io ();
 >    tui_initialize_readline ();
 > +
 > +  /* Tell gdb to use the tui_command_loop as the main loop. */
 > +  command_loop_hook = tui_command_loop;
 >  
 >    /* Decide in which mode to start using GDB (based on -tui).  */
 >    if (tui_version)
 > Index: tui/tuiIO.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/tui/tuiIO.c,v
 > retrieving revision 1.12
 > diff -u -p -r1.12 tuiIO.c
 > --- tui/tuiIO.c	1 Mar 2002 06:19:28 -0000	1.12
 > +++ tui/tuiIO.c	26 Aug 2002 20:24:39 -0000
 > @@ -87,12 +87,12 @@
 >  /* TUI output files.  */
 >  static struct ui_file *tui_stdout;
 >  static struct ui_file *tui_stderr;
 > -static struct ui_out *tui_out;
 > +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;
 > -static struct ui_out *tui_old_uiout;
 > +struct ui_out *tui_old_uiout;
 >  
 >  /* Readline previous hooks.  */
 >  static Function *tui_old_rl_getc_function;
 > @@ -357,7 +357,7 @@ tui_initialize_io ()
 >  
 >    /* Create the default UI.  It is not created because we installed
 >       a init_ui_hook.  */
 > -  uiout = cli_out_new (gdb_stdout);
 > +  tui_old_uiout = uiout = cli_out_new (gdb_stdout);
 >  
 >    /* Temporary solution for readline writing to stdout:
 >       redirect readline output in a pipe, read that pipe and
 > Index: tui/tuiIO.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/tui/tuiIO.h,v
 > retrieving revision 1.4
 > diff -u -p -r1.4 tuiIO.h
 > --- tui/tuiIO.h	21 Jul 2001 19:56:54 -0000	1.4
 > +++ tui/tuiIO.h	26 Aug 2002 20:24:39 -0000
 > @@ -36,6 +36,8 @@ extern void tui_initialize_io (void);
 >  /* Get a character from the command window.  */
 >  extern int tui_getc (FILE*);
 >  
 > +extern struct ui_out *tui_out;
 > +extern struct ui_out *tui_old_uiout;
 >  
 >  #define m_tuiStartNewLine       tuiStartNewLines(1)
 >  #define m_isStartSequence(ch)   (ch == 27)


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