summaryrefslogtreecommitdiff
path: root/gdb/cli
diff options
context:
space:
mode:
authorAndrew Stubbs <andrew.stubbs@st.com>2006-07-21 14:46:56 +0000
committerAndrew Stubbs <andrew.stubbs@st.com>2006-07-21 14:46:56 +0000
commit7369ed58187d25a77129346a3c2c13db30e21290 (patch)
tree24f022f8af19399e44c1d8930952ca4756548032 /gdb/cli
parentae89e6dfda349afcfc6ddfab7bde1b43fe8f2a30 (diff)
downloadgdb-7369ed58187d25a77129346a3c2c13db30e21290.tar.gz
2006-07-21 Andrew Stubbs <andrew.stubbs@st.com>
* cli/cli-cmds.c (source_verbose, trace_commands): New variables. (source_script): New function. (source_verbose_cleanup): New function. (source_command): Move old contents to source_script. Make function static. Parse -v option and call source_script. (init_cli_cmds): Update source command help. Add 'set trace-commands' command. * cli/cli-script.c (command_next_depth): New static variable. (suppress_next_print_command_trace): New static variable. (reset_command_nest_depth): New function. (print_command_trace): New function. (execute_control_command): Split the continue_control and break_control cases, add calls to print_command_trace and count the nest depth. (while_command): Set suppress_next_print_command_trace. (if_command): Likewise. * top.c (execute_command): Call print_command_trace. * cli/cli-cmds.h (source_verbose, trace_commands): New extern variables. (source_command): Change to source_script. * main.c (captued_main): Use source_script instead of source_command. * top.h (source_command): Change to source_script. * event-top.c (display_gdb_prompt): Call reset_command_nest_depth. * cli/cli-script.h (print_command_trace): Export. (reset_command_nest_depth): Likewise. docs/ * gdb.texinfo (Optional warnings and messages): Add 'set/show trace-commands'. (Command files): Add '-v' to source command. testsuite/ * gdb.base/default.exp: Update source command error message. * gdb.base/help.exp: Update 'help source' message.
Diffstat (limited to 'gdb/cli')
-rw-r--r--gdb/cli/cli-cmds.c69
-rw-r--r--gdb/cli/cli-cmds.h7
-rw-r--r--gdb/cli/cli-script.c71
-rw-r--r--gdb/cli/cli-script.h8
4 files changed, 148 insertions, 7 deletions
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index f66abdeb077..fdff3942cfc 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -173,6 +173,11 @@ struct cmd_list_element *showdebuglist;
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
+
+/* Command tracing state. */
+
+int source_verbose = 0;
+int trace_commands = 0;
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
@@ -424,17 +429,16 @@ cd_command (char *dir, int from_tty)
}
void
-source_command (char *args, int from_tty)
+source_script (char *file, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
- char *file = args;
char *full_pathname = NULL;
int fd;
- if (file == NULL)
+ if (file == NULL || *file == 0)
{
- error (_("source command requires pathname of file to source."));
+ error (_("source command requires file name of file to source."));
}
file = tilde_expand (file);
@@ -465,6 +469,51 @@ source_command (char *args, int from_tty)
do_cleanups (old_cleanups);
}
+/* Return the source_verbose global variable to its previous state
+ on exit from the source command, by whatever means. */
+static void
+source_verbose_cleanup (void *old_value)
+{
+ source_verbose = *(int *)old_value;
+ xfree (old_value);
+}
+
+static void
+source_command (char *args, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *file = args;
+ int *old_source_verbose = xmalloc (sizeof(int));
+
+ *old_source_verbose = source_verbose;
+ old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose);
+
+ /* -v causes the source command to run in verbose mode.
+ We still have to be able to handle filenames with spaces in a
+ backward compatible way, so buildargv is not appropriate. */
+
+ if (args)
+ {
+ /* Make sure leading white space does not break the comparisons. */
+ while (isspace(args[0]))
+ args++;
+
+ /* Is -v the first thing in the string? */
+ if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+ {
+ source_verbose = 1;
+
+ /* Trim -v and whitespace from the filename. */
+ file = &args[3];
+ while (isspace (file[0]))
+ file++;
+ }
+ }
+
+ return source_script (file, from_tty);
+}
+
+
static void
echo_command (char *text, int from_tty)
{
@@ -1182,8 +1231,10 @@ Commands defined in this way may have up to ten arguments."));
source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\
+Optional -v switch (before the filename) causes each command in\n\
+FILE to be echoed as it is executed.\n\
Note that the file \"%s\" is read automatically in this way\n\
-when gdb is started."), gdbinit);
+when GDB is started."), gdbinit);
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
@@ -1364,4 +1415,12 @@ Show the max call depth for user-defined commands."), NULL,
NULL,
show_max_user_call_depth,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("trace-commands", no_class, &trace_commands, _("\
+Set tracing of GDB CLI commands."), _("\
+Show state of GDB CLI command tracing."), _("\
+When 'on', each command is displayed as it is executed."),
+ NULL,
+ NULL,
+ &setlist, &showlist);
}
diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
index 1aad0341202..228e6aaf163 100644
--- a/gdb/cli/cli-cmds.h
+++ b/gdb/cli/cli-cmds.h
@@ -115,11 +115,16 @@ extern void cd_command (char *, int);
extern void quit_command (char *, int);
-extern void source_command (char *, int);
+extern void source_script (char *, int);
/* Used everywhere whenever at least one parameter is required and
none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
+/* Command tracing state. */
+
+extern int source_verbose;
+extern int trace_commands;
+
#endif /* !defined (CLI_CMDS_H) */
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 643eb74933a..1b5d342b3ad 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -46,9 +46,15 @@ static struct cleanup * setup_user_args (char *p);
static void validate_comname (char *);
-/* Level of control structure. */
+/* Level of control structure when reading. */
static int control_level;
+/* Level of control structure when executing. */
+static int command_nest_depth = 1;
+
+/* This is to prevent certain commands being printed twice. */
+static int suppress_next_print_command_trace = 0;
+
/* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10
struct user_args
@@ -293,6 +299,46 @@ execute_user_command (struct cmd_list_element *c, char *args)
do_cleanups (old_chain);
}
+/* This function is called every time GDB prints a prompt.
+ It ensures that errors and the like to not confuse the command tracing. */
+
+void
+reset_command_nest_depth (void)
+{
+ command_nest_depth = 1;
+
+ /* Just in case. */
+ suppress_next_print_command_trace = 0;
+}
+
+/* Print the command, prefixed with '+' to represent the call depth.
+ This is slightly complicated because this function may be called
+ from execute_command and execute_control_command. Unfortunately
+ execute_command also prints the top level control commands.
+ In these cases execute_command will call execute_control_command
+ via while_command or if_command. Inner levels of 'if' and 'while'
+ are dealt with directly. Therefore we can use these functions
+ to determine whether the command has been printed already or not. */
+void
+print_command_trace (const char *cmd)
+{
+ int i;
+
+ if (suppress_next_print_command_trace)
+ {
+ suppress_next_print_command_trace = 0;
+ return;
+ }
+
+ if (!source_verbose && !trace_commands)
+ return;
+
+ for (i=0; i < command_nest_depth; i++)
+ printf_filtered ("+");
+
+ printf_filtered ("%s\n", cmd);
+}
+
enum command_control_type
execute_control_command (struct command_line *cmd)
{
@@ -322,7 +368,16 @@ execute_control_command (struct command_line *cmd)
break;
case continue_control:
+ print_command_trace ("loop_continue");
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ print_command_trace ("loop_break");
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
@@ -330,6 +385,10 @@ execute_control_command (struct command_line *cmd)
case while_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 7);
+ sprintf (buffer, "while %s", cmd->line);
+ print_command_trace (buffer);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
@@ -362,7 +421,9 @@ execute_control_command (struct command_line *cmd)
current = *cmd->body_list;
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, or a "break" command, then stop
looping. */
@@ -391,6 +452,10 @@ execute_control_command (struct command_line *cmd)
case if_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 4);
+ sprintf (buffer, "if %s", cmd->line);
+ print_command_trace (buffer);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
@@ -417,7 +482,9 @@ execute_control_command (struct command_line *cmd)
/* Execute commands in the given arm. */
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, get out. */
if (ret != simple_control)
@@ -454,6 +521,7 @@ while_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
@@ -472,6 +540,7 @@ if_command (char *arg, int from_tty)
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
diff --git a/gdb/cli/cli-script.h b/gdb/cli/cli-script.h
index 21a5f26548f..6f0fc9c2c53 100644
--- a/gdb/cli/cli-script.h
+++ b/gdb/cli/cli-script.h
@@ -53,4 +53,12 @@ struct cleanup *make_cleanup_free_command_lines (struct command_line **arg);
extern void execute_user_command (struct cmd_list_element *c, char *args);
+/* Exported to top.c */
+
+extern void print_command_trace (const char *cmd);
+
+/* Exported to event-top.c */
+
+extern void reset_command_nest_depth (void);
+
#endif /* !defined (CLI_SCRIPT_H) */