From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30847 invoked by alias); 26 Aug 2002 22:52:39 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 30840 invoked from network); 26 Aug 2002 22:52:38 -0000 Received: from unknown (HELO localhost.redhat.com) (66.30.197.194) by sources.redhat.com with SMTP; 26 Aug 2002 22:52:38 -0000 Received: by localhost.redhat.com (Postfix, from userid 469) id BD1A610AAA; Mon, 26 Aug 2002 18:50:43 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15722.45251.205480.778379@localhost.redhat.com> Date: Mon, 26 Aug 2002 15:52:00 -0000 To: Stephane Carrez Cc: gdb-patches@sources.redhat.com Subject: Re: [RFA]: Make gdb_do_one_event public and fix uiout setting for TUI In-Reply-To: <3D6AB1C8.5050403@nerim.fr> References: <3D6AB1C8.5050403@nerim.fr> X-SW-Source: 2002-08/txt/msg00870.txt.bz2 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 > > * event-loop.c (gdb_do_one_event): Make public. > * event-loop.h (gdb_do_one_event): Declare. > > tui/ChangeLog > > 2002-08-27 Stephane Carrez > > * 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 > #include > #include > > @@ -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)