2006-07-07 Andrew Stubbs * 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 (execute_user_command): Set control_level. (execute_control_command): Add instrumentation for the source_verbose and trace_command modes. * top.c (execute_command): Likewise. * 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. docs/ * gdb.texinfo (Optional warnings and messages): Add 'set/show trace-commands'. (Command files): Add '-v' to source command. testsuite/ *gdb.base/help.exp: Update 'help source' message. Index: src/gdb/cli/cli-cmds.c =================================================================== --- src.orig/gdb/cli/cli-cmds.c 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/cli/cli-cmds.c 2006-07-07 16:30:26.000000000 +0100 @@ -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,15 +429,14 @@ 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 || strlen (file) == 0) { error (_("source command requires pathname of file to source.")); } @@ -465,6 +469,48 @@ 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; +} + +static void +source_command (char *args, int from_tty) +{ + struct cleanup *old_cleanups; + char *file = args; + + old_cleanups = make_cleanup (source_verbose_cleanup, (void *)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) { @@ -1183,7 +1229,8 @@ Commands defined in this way may have up source_help_text = xstrprintf (_("\ Read commands from a file named FILE.\n\ Note that the file \"%s\" is read automatically in this way\n\ -when gdb is started."), gdbinit); +when gdb is started.\n\ +Use -v to see the name of the commands issued."), gdbinit); c = add_cmd ("source", class_support, source_command, source_help_text, &cmdlist); set_cmd_completer (c, filename_completer); @@ -1364,4 +1411,12 @@ Show the max call depth for user-defined 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); } Index: src/gdb/cli/cli-script.c =================================================================== --- src.orig/gdb/cli/cli-script.c 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/cli/cli-script.c 2006-07-07 16:17:55.000000000 +0100 @@ -280,6 +280,10 @@ execute_user_command (struct cmd_list_el not confused with Insight. */ in_user_command = 1; + /* Set the control level to ensure that all control commands are + printed when trace_commands is set. */ + control_level = 2; + while (cmdlines) { ret = execute_control_command (cmdlines); @@ -322,7 +326,18 @@ execute_control_command (struct command_ break; case continue_control: + if (source_verbose || trace_commands) + printf_unfiltered (_("Command issued: loop_continue %s\n"), cmd->line); + + /* 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: + if (source_verbose || trace_commands) + printf_unfiltered (_("Command issued: loop_break %s\n"), cmd->line); + /* Return for "continue", and "break" so we can either continue the loop at the top, or break out. */ ret = cmd->control_type; @@ -330,6 +345,10 @@ execute_control_command (struct command_ case while_control: { + if ((source_verbose || trace_commands) + && control_level > 1) /* Top level printed in execute_command(). */ + printf_unfiltered (_("Command issued: while %s\n"), cmd->line); + /* Parse the loop control expression for the while statement. */ new_line = insert_args (cmd->line); if (!new_line) @@ -362,7 +381,9 @@ execute_control_command (struct command_ current = *cmd->body_list; while (current) { + control_level++; ret = execute_control_command (current); + control_level--; /* If we got an error, or a "break" command, then stop looping. */ @@ -391,6 +412,10 @@ execute_control_command (struct command_ case if_control: { + if ((source_verbose || trace_commands) + && control_level > 1) /* Top level printed in execute_command(). */ + printf_unfiltered (_("Command issued: if %s\n"), cmd->line); + new_line = insert_args (cmd->line); if (!new_line) break; @@ -417,7 +442,9 @@ execute_control_command (struct command_ /* Execute commands in the given arm. */ while (current) { + control_level++; ret = execute_control_command (current); + control_level--; /* If we got an error, get out. */ if (ret != simple_control) Index: src/gdb/top.c =================================================================== --- src.orig/gdb/top.c 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/top.c 2006-07-07 16:17:55.000000000 +0100 @@ -395,6 +395,11 @@ execute_command (char *p, int from_tty) while (*p == ' ' || *p == '\t') p++; + + if ((source_verbose || trace_commands) + && strlen (p) > 0) + printf_unfiltered (_("Command issued: %s\n"), p); + if (*p) { char *arg; Index: src/gdb/testsuite/gdb.base/help.exp =================================================================== --- src.orig/gdb/testsuite/gdb.base/help.exp 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/testsuite/gdb.base/help.exp 2006-07-07 16:17:55.000000000 +0100 @@ -533,7 +533,7 @@ gdb_test "help stepi" "Step one instruct gdb_test "help signal" "Continue program giving it signal.*" "help signal" # test help source # vxgdb reads .vxgdbinit -gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\." "help source" +gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when gdb is started\.\[\r\n\]+Use -v to see the name of the commands issued\." "help source" # test help stack gdb_test "help stack" "Examining the stack\..*\[\r\n\]+When the program being debugged stops, gdb selects the innermost frame\.\[\r\n\]+The commands below can be used to select other frames by number or address\.\[\r\n\]+List of commands:\[\r\n\]+backtrace -- Print backtrace of all stack frames\[\r\n\]+bt -- Print backtrace of all stack frames\[\r\n\]+down -- Select and print stack frame called by this one\[\r\n\]+frame -- Select and print a stack frame\[\r\n\]+return -- Make selected stack frame return to its caller\[\r\n\]+select-frame -- Select a stack frame without printing anything\[\r\n\]+up -- Select and print stack frame that called this one\[\r\n\]+Type \"help\" followed by command name for full documentation\.\[\r\n\]+Command name abbreviations are allowed if unambiguous\." "help stack" # test help status Index: src/gdb/cli/cli-cmds.h =================================================================== --- src.orig/gdb/cli/cli-cmds.h 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/cli/cli-cmds.h 2006-07-07 16:34:16.000000000 +0100 @@ -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) */ Index: src/gdb/doc/gdb.texinfo =================================================================== --- src.orig/gdb/doc/gdb.texinfo 2006-07-07 16:17:17.000000000 +0100 +++ src/gdb/doc/gdb.texinfo 2006-07-07 16:17:55.000000000 +0100 @@ -15999,6 +15999,20 @@ Displays state of confirmation requests. @end table +If you need to debug user-defined commands or sourced files you may find it +useful to enable command tracing. In this mode each command will be printed +as it is executed, prefixed with @samp{Command issued:}. + +@table @code +@kindex set debug commandtrace +@item set debug commandtrace on +Enable command tracing. +@item set debug commandtrace off +Disable command tracing. +@item show debug commandtrace +Display the current state of command tracing. +@end table + @node Debugging Output @section Optional messages about internal happenings @cindex optional debugging messages @@ -16347,7 +16361,7 @@ command: @table @code @kindex source @cindex execute commands from a file -@item source @var{filename} +@item source [@code{-v}] @var{filename} Execute the command file @var{filename}. @end table @@ -16360,6 +16374,10 @@ execution of the command file and contro @value{GDBN} searches for @var{filename} in the current directory and then on the search path (specified with the @samp{directory} command). +If @code{-v}, for verbose mode, is given then each command will +be displayed as it is executed. The option must be given before +@var{filename}, and will be interpreted as part of the filename anywhere else. + Commands that would ask for confirmation if used interactively proceed without asking when used in a command file. Many @value{GDBN} commands that normally print messages to say what they are doing omit the messages Index: src/gdb/main.c =================================================================== --- src.orig/gdb/main.c 2006-02-21 19:46:48.000000000 +0000 +++ src/gdb/main.c 2006-07-07 16:35:19.000000000 +0100 @@ -643,7 +643,7 @@ extern int gdbtk_test (char *); if (!inhibit_gdbinit) { - catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL); + catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL); } /* Do stats; no need to do them elsewhere since we'll only @@ -730,7 +730,7 @@ extern int gdbtk_test (char *); || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) if (!inhibit_gdbinit) { - catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL); + catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL); } for (i = 0; i < ncmd; i++) @@ -748,12 +748,12 @@ extern int gdbtk_test (char *); read_command_file (stdin); else #endif - source_command (cmdarg[i], !batch); + source_script (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } #endif if (cmdarg[i].type == CMDARG_FILE) - catch_command_errors (source_command, cmdarg[i].string, + catch_command_errors (source_script, cmdarg[i].string, !batch, RETURN_MASK_ALL); else /* cmdarg[i].type == CMDARG_COMMAND */ catch_command_errors (execute_command, cmdarg[i].string, Index: src/gdb/top.h =================================================================== --- src.orig/gdb/top.h 2006-03-29 23:53:33.000000000 +0100 +++ src/gdb/top.h 2006-07-07 16:33:50.000000000 +0100 @@ -36,7 +36,7 @@ extern char gdbinit[]; extern void print_gdb_version (struct ui_file *); -extern void source_command (char *, int); +extern void source_script (char *, int); extern void cd_command (char *, int); extern void read_command_file (FILE *); extern void init_history (void);