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]

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


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).

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]