From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27817 invoked by alias); 26 Aug 2002 20:55:10 -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 27810 invoked from network); 26 Aug 2002 20:55:09 -0000 Received: from unknown (HELO mallaury.noc.nerim.net) (62.4.17.82) by sources.redhat.com with SMTP; 26 Aug 2002 20:55:09 -0000 Received: from nerim.fr (stcarrez.net1.nerim.net [62.212.108.40]) by mallaury.noc.nerim.net (Postfix) with ESMTP id F24D862D26; Mon, 26 Aug 2002 22:55:04 +0200 (CEST) Message-ID: <3D6AB1C8.5050403@nerim.fr> Date: Mon, 26 Aug 2002 14:22:00 -0000 From: Stephane Carrez User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4.1) Gecko/20020508 Netscape6/6.2.3 X-Accept-Language: en-us MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [RFA]: Make gdb_do_one_event public and fix uiout setting for TUI Content-Type: multipart/mixed; boundary="------------040301080707040205050104" X-SW-Source: 2002-08/txt/msg00867.txt.bz2 This is a multi-part message in MIME format. --------------040301080707040205050104 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1578 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 * 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. --------------040301080707040205050104 Content-Type: text/plain; name="tui-event-loop.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="tui-event-loop.diffs" Content-length: 7491 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) --------------040301080707040205050104--