1 /* CLI Definitions for GDB, the GNU debugger. 2 3 Copyright (C) 2002-2015 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "interps.h" 22 #include "event-top.h" 23 #include "ui-out.h" 24 #include "cli-out.h" 25 #include "top.h" /* for "execute_command" */ 26 #include "infrun.h" 27 #include "observer.h" 28 29 /* These are the ui_out and the interpreter for the console 30 interpreter. */ 31 struct ui_out *cli_uiout; 32 static struct interp *cli_interp; 33 34 /* Longjmp-safe wrapper for "execute_command". */ 35 static struct gdb_exception safe_execute_command (struct ui_out *uiout, 36 char *command, 37 int from_tty); 38 39 /* Observers for several run control events. If the interpreter is 40 quiet (i.e., another interpreter is being run with 41 interpreter-exec), print nothing. */ 42 43 /* Observer for the signal_received notification. */ 44 45 static void 46 cli_on_signal_received (enum gdb_signal siggnal) 47 { 48 if (!interp_quiet_p (cli_interp)) 49 print_signal_received_reason (cli_uiout, siggnal); 50 } 51 52 /* Observer for the end_stepping_range notification. */ 53 54 static void 55 cli_on_end_stepping_range (void) 56 { 57 if (!interp_quiet_p (cli_interp)) 58 print_end_stepping_range_reason (cli_uiout); 59 } 60 61 /* Observer for the signalled notification. */ 62 63 static void 64 cli_on_signal_exited (enum gdb_signal siggnal) 65 { 66 if (!interp_quiet_p (cli_interp)) 67 print_signal_exited_reason (cli_uiout, siggnal); 68 } 69 70 /* Observer for the exited notification. */ 71 72 static void 73 cli_on_exited (int exitstatus) 74 { 75 if (!interp_quiet_p (cli_interp)) 76 print_exited_reason (cli_uiout, exitstatus); 77 } 78 79 /* Observer for the no_history notification. */ 80 81 static void 82 cli_on_no_history (void) 83 { 84 if (!interp_quiet_p (cli_interp)) 85 print_no_history_reason (cli_uiout); 86 } 87 88 /* Observer for the sync_execution_done notification. */ 89 90 static void 91 cli_on_sync_execution_done (void) 92 { 93 if (!interp_quiet_p (cli_interp)) 94 display_gdb_prompt (NULL); 95 } 96 97 /* Observer for the command_error notification. */ 98 99 static void 100 cli_on_command_error (void) 101 { 102 if (!interp_quiet_p (cli_interp)) 103 display_gdb_prompt (NULL); 104 } 105 106 /* These implement the cli out interpreter: */ 107 108 static void * 109 cli_interpreter_init (struct interp *self, int top_level) 110 { 111 /* If changing this, remember to update tui-interp.c as well. */ 112 observer_attach_end_stepping_range (cli_on_end_stepping_range); 113 observer_attach_signal_received (cli_on_signal_received); 114 observer_attach_signal_exited (cli_on_signal_exited); 115 observer_attach_exited (cli_on_exited); 116 observer_attach_no_history (cli_on_no_history); 117 observer_attach_sync_execution_done (cli_on_sync_execution_done); 118 observer_attach_command_error (cli_on_command_error); 119 120 return NULL; 121 } 122 123 static int 124 cli_interpreter_resume (void *data) 125 { 126 struct ui_file *stream; 127 128 /*sync_execution = 1; */ 129 130 /* gdb_setup_readline will change gdb_stdout. If the CLI was 131 previously writing to gdb_stdout, then set it to the new 132 gdb_stdout afterwards. */ 133 134 stream = cli_out_set_stream (cli_uiout, gdb_stdout); 135 if (stream != gdb_stdout) 136 { 137 cli_out_set_stream (cli_uiout, stream); 138 stream = NULL; 139 } 140 141 gdb_setup_readline (); 142 143 if (stream != NULL) 144 cli_out_set_stream (cli_uiout, gdb_stdout); 145 146 return 1; 147 } 148 149 static int 150 cli_interpreter_suspend (void *data) 151 { 152 gdb_disable_readline (); 153 return 1; 154 } 155 156 static struct gdb_exception 157 cli_interpreter_exec (void *data, const char *command_str) 158 { 159 struct ui_file *old_stream; 160 struct gdb_exception result; 161 162 /* FIXME: cagney/2003-02-01: Need to const char *propogate 163 safe_execute_command. */ 164 char *str = strcpy (alloca (strlen (command_str) + 1), command_str); 165 166 /* gdb_stdout could change between the time cli_uiout was 167 initialized and now. Since we're probably using a different 168 interpreter which has a new ui_file for gdb_stdout, use that one 169 instead of the default. 170 171 It is important that it gets reset everytime, since the user 172 could set gdb to use a different interpreter. */ 173 old_stream = cli_out_set_stream (cli_uiout, gdb_stdout); 174 result = safe_execute_command (cli_uiout, str, 1); 175 cli_out_set_stream (cli_uiout, old_stream); 176 return result; 177 } 178 179 static struct gdb_exception 180 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty) 181 { 182 struct gdb_exception e = exception_none; 183 struct ui_out *saved_uiout; 184 185 /* Save and override the global ``struct ui_out'' builder. */ 186 saved_uiout = current_uiout; 187 current_uiout = command_uiout; 188 189 TRY 190 { 191 execute_command (command, from_tty); 192 } 193 CATCH (exception, RETURN_MASK_ALL) 194 { 195 e = exception; 196 } 197 END_CATCH 198 199 /* Restore the global builder. */ 200 current_uiout = saved_uiout; 201 202 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the 203 caller should print the exception. */ 204 exception_print (gdb_stderr, e); 205 return e; 206 } 207 208 static struct ui_out * 209 cli_ui_out (struct interp *self) 210 { 211 return cli_uiout; 212 } 213 214 /* Standard gdb initialization hook. */ 215 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */ 216 217 void 218 _initialize_cli_interp (void) 219 { 220 static const struct interp_procs procs = { 221 cli_interpreter_init, /* init_proc */ 222 cli_interpreter_resume, /* resume_proc */ 223 cli_interpreter_suspend, /* suspend_proc */ 224 cli_interpreter_exec, /* exec_proc */ 225 cli_ui_out, /* ui_out_proc */ 226 NULL, /* set_logging_proc */ 227 cli_command_loop /* command_loop_proc */ 228 }; 229 230 /* Create a default uiout builder for the CLI. */ 231 cli_uiout = cli_out_new (gdb_stdout); 232 cli_interp = interp_new (INTERP_CONSOLE, &procs); 233 234 interp_add (cli_interp); 235 } 236