* tui-hooks.c (tui_event_loop): New function.
authorStephane Carrez <stcarrez@nerim.fr>
Tue, 10 Sep 2002 19:59:31 +0000 (19:59 +0000)
committerStephane Carrez <stcarrez@nerim.fr>
Tue, 10 Sep 2002 19:59:31 +0000 (19:59 +0000)
(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.

gdb/tui/ChangeLog
gdb/tui/tui-hooks.c
gdb/tui/tuiIO.c
gdb/tui/tuiIO.h

index dbb9f54..9a54d50 100644 (file)
@@ -1,3 +1,13 @@
+2002-09-10  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.
+
 2002-09-04  Stephane Carrez  <stcarrez@nerim.fr>
 
        * tuiIO.c (tui_putc): New function to print one character.
index 35d7ce8..3beca39 100644 (file)
 #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)
@@ -329,6 +335,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
@@ -346,6 +432,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 01ebbe6..58df5d5 100644 (file)
 /* 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;
@@ -578,7 +578,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);
 
 #ifdef TUI_USE_PIPE_FOR_READLINE
   /* Temporary solution for readline writing to stdout:
index 49c26fd..40970b6 100644 (file)
@@ -41,6 +41,8 @@ extern int tui_getc (FILE*);
    changed the edited text.  */
 extern void tui_redisplay_readline (void);
 
+extern struct ui_out *tui_out;
+extern struct ui_out *tui_old_uiout;
 
 #define m_tuiStartNewLine       tuiStartNewLines(1)
 #define m_isStartSequence(ch)   (ch == 27)