1130803Smarcel/* TUI Interpreter definitions for GDB, the GNU debugger. 2130803Smarcel 3130803Smarcel Copyright 2003 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "interps.h" 24130803Smarcel#include "top.h" 25130803Smarcel#include "event-top.h" 26130803Smarcel#include "event-loop.h" 27130803Smarcel#include "ui-out.h" 28130803Smarcel#include "cli-out.h" 29130803Smarcel#include "tui/tui-data.h" 30130803Smarcel#include "readline/readline.h" 31130803Smarcel#include "tui/tui-win.h" 32130803Smarcel#include "tui/tui.h" 33130803Smarcel#include "tui/tui-io.h" 34130803Smarcel 35130803Smarcel/* Set to 1 when the TUI mode must be activated when we first start gdb. */ 36130803Smarcelstatic int tui_start_enabled = 0; 37130803Smarcel 38130803Smarcel/* Cleanup the tui before exiting. */ 39130803Smarcel 40130803Smarcelstatic void 41130803Smarceltui_exit (void) 42130803Smarcel{ 43130803Smarcel /* Disable the tui. Curses mode is left leaving the screen 44130803Smarcel in a clean state (see endwin()). */ 45130803Smarcel tui_disable (); 46130803Smarcel} 47130803Smarcel 48130803Smarcel/* These implement the TUI interpreter. */ 49130803Smarcel 50130803Smarcelstatic void * 51130803Smarceltui_init (void) 52130803Smarcel{ 53130803Smarcel /* Install exit handler to leave the screen in a good shape. */ 54130803Smarcel atexit (tui_exit); 55130803Smarcel 56130803Smarcel tui_initialize_static_data (); 57130803Smarcel 58130803Smarcel tui_initialize_io (); 59130803Smarcel tui_initialize_readline (); 60130803Smarcel 61130803Smarcel return NULL; 62130803Smarcel} 63130803Smarcel 64130803Smarcelstatic int 65130803Smarceltui_resume (void *data) 66130803Smarcel{ 67130803Smarcel struct ui_file *stream; 68130803Smarcel 69130803Smarcel /* gdb_setup_readline will change gdb_stdout. If the TUI was previously 70130803Smarcel writing to gdb_stdout, then set it to the new gdb_stdout afterwards. */ 71130803Smarcel 72130803Smarcel stream = cli_out_set_stream (tui_old_uiout, gdb_stdout); 73130803Smarcel if (stream != gdb_stdout) 74130803Smarcel { 75130803Smarcel cli_out_set_stream (tui_old_uiout, stream); 76130803Smarcel stream = NULL; 77130803Smarcel } 78130803Smarcel 79130803Smarcel gdb_setup_readline (); 80130803Smarcel 81130803Smarcel if (stream != NULL) 82130803Smarcel cli_out_set_stream (tui_old_uiout, gdb_stdout); 83130803Smarcel 84130803Smarcel if (tui_start_enabled) 85130803Smarcel tui_enable (); 86130803Smarcel return 1; 87130803Smarcel} 88130803Smarcel 89130803Smarcelstatic int 90130803Smarceltui_suspend (void *data) 91130803Smarcel{ 92130803Smarcel tui_start_enabled = tui_active; 93130803Smarcel tui_disable (); 94130803Smarcel return 1; 95130803Smarcel} 96130803Smarcel 97130803Smarcel/* Display the prompt if we are silent. */ 98130803Smarcel 99130803Smarcelstatic int 100130803Smarceltui_display_prompt_p (void *data) 101130803Smarcel{ 102130803Smarcel if (interp_quiet_p (NULL)) 103130803Smarcel return 0; 104130803Smarcel else 105130803Smarcel return 1; 106130803Smarcel} 107130803Smarcel 108130803Smarcelstatic int 109130803Smarceltui_exec (void *data, const char *command_str) 110130803Smarcel{ 111130803Smarcel internal_error (__FILE__, __LINE__, "tui_exec called"); 112130803Smarcel} 113130803Smarcel 114130803Smarcel 115130803Smarcel/* Initialize all the necessary variables, start the event loop, 116130803Smarcel register readline, and stdin, start the loop. */ 117130803Smarcel 118130803Smarcelstatic void 119130803Smarceltui_command_loop (void *data) 120130803Smarcel{ 121130803Smarcel int length; 122130803Smarcel char *a_prompt; 123130803Smarcel char *gdb_prompt = get_prompt (); 124130803Smarcel 125130803Smarcel /* If we are using readline, set things up and display the first 126130803Smarcel prompt, otherwise just print the prompt. */ 127130803Smarcel if (async_command_editing_p) 128130803Smarcel { 129130803Smarcel /* Tell readline what the prompt to display is and what function 130130803Smarcel it will need to call after a whole line is read. This also 131130803Smarcel displays the first prompt. */ 132130803Smarcel length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1; 133130803Smarcel a_prompt = (char *) xmalloc (length); 134130803Smarcel strcpy (a_prompt, PREFIX (0)); 135130803Smarcel strcat (a_prompt, gdb_prompt); 136130803Smarcel strcat (a_prompt, SUFFIX (0)); 137130803Smarcel rl_callback_handler_install (a_prompt, input_handler); 138130803Smarcel } 139130803Smarcel else 140130803Smarcel display_gdb_prompt (0); 141130803Smarcel 142130803Smarcel /* Loop until there is nothing to do. This is the entry point to the 143130803Smarcel event loop engine. gdb_do_one_event, called via catch_errors() 144130803Smarcel will process one event for each invocation. It blocks waits for 145130803Smarcel an event and then processes it. >0 when an event is processed, 0 146130803Smarcel when catch_errors() caught an error and <0 when there are no 147130803Smarcel longer any event sources registered. */ 148130803Smarcel while (1) 149130803Smarcel { 150130803Smarcel int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); 151130803Smarcel if (result < 0) 152130803Smarcel break; 153130803Smarcel 154130803Smarcel /* Update gdb output according to TUI mode. Since catch_errors 155130803Smarcel preserves the uiout from changing, this must be done at top 156130803Smarcel level of event loop. */ 157130803Smarcel if (tui_active) 158130803Smarcel uiout = tui_out; 159130803Smarcel else 160130803Smarcel uiout = tui_old_uiout; 161130803Smarcel 162130803Smarcel if (result == 0) 163130803Smarcel { 164130803Smarcel /* FIXME: this should really be a call to a hook that is 165130803Smarcel interface specific, because interfaces can display the 166130803Smarcel prompt in their own way. */ 167130803Smarcel display_gdb_prompt (0); 168130803Smarcel /* This call looks bizarre, but it is required. If the user 169130803Smarcel entered a command that caused an error, 170130803Smarcel after_char_processing_hook won't be called from 171130803Smarcel rl_callback_read_char_wrapper. Using a cleanup there 172130803Smarcel won't work, since we want this function to be called 173130803Smarcel after a new prompt is printed. */ 174130803Smarcel if (after_char_processing_hook) 175130803Smarcel (*after_char_processing_hook) (); 176130803Smarcel /* Maybe better to set a flag to be checked somewhere as to 177130803Smarcel whether display the prompt or not. */ 178130803Smarcel } 179130803Smarcel } 180130803Smarcel 181130803Smarcel /* We are done with the event loop. There are no more event sources 182130803Smarcel to listen to. So we exit GDB. */ 183130803Smarcel return; 184130803Smarcel} 185130803Smarcel 186130803Smarcelvoid 187130803Smarcel_initialize_tui_interp (void) 188130803Smarcel{ 189130803Smarcel static const struct interp_procs procs = { 190130803Smarcel tui_init, 191130803Smarcel tui_resume, 192130803Smarcel tui_suspend, 193130803Smarcel tui_exec, 194130803Smarcel tui_display_prompt_p, 195130803Smarcel tui_command_loop, 196130803Smarcel }; 197130803Smarcel struct interp *tui_interp; 198130803Smarcel 199130803Smarcel /* Create a default uiout builder for the TUI. */ 200130803Smarcel tui_out = tui_out_new (gdb_stdout); 201130803Smarcel interp_add (interp_new ("tui", NULL, tui_out, &procs)); 202130803Smarcel if (interpreter_p && strcmp (interpreter_p, "tui") == 0) 203130803Smarcel tui_start_enabled = 1; 204130803Smarcel 205130803Smarcel if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0) 206130803Smarcel { 207130803Smarcel xfree (interpreter_p); 208130803Smarcel interpreter_p = xstrdup ("tui"); 209130803Smarcel } 210130803Smarcel} 211