/* GDB CLI commands.
- Copyright (C) 2000-2013 Free Software Foundation, Inc.
+ Copyright (C) 2000-2015 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "exceptions.h"
#include "arch-utils.h"
#include "dyn-string.h"
#include "readline/readline.h"
#include "target.h" /* For baud_rate, remote_debug and remote_timeout. */
#include "gdb_wait.h" /* For shell escape implementation. */
#include "gdb_regex.h" /* Used by apropos_command. */
-#include "gdb_string.h"
#include "gdb_vfork.h"
#include "linespec.h"
#include "expression.h"
#include "source.h"
#include "disasm.h"
#include "tracepoint.h"
+#include "filestuff.h"
+#include "location.h"
#include "ui-out.h"
#include "cli/cli-script.h"
#include "cli/cli-setshow.h"
#include "cli/cli-cmds.h"
+#include "cli/cli-utils.h"
-#include "python/python.h"
+#include "extension.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et.al. */
struct cmd_list_element *disablelist;
-/* Chain containing all defined toggle subcommands. */
-
-struct cmd_list_element *togglelist;
-
/* Chain containing all defined stop subcommands. */
struct cmd_list_element *stoplist;
none is supplied. */
void
-error_no_arg (char *why)
+error_no_arg (const char *why)
{
error (_("Argument required (%s)."), why);
}
{
printf_unfiltered (_("\"info\" must be followed by "
"the name of an info command.\n"));
- help_list (infolist, "info ", -1, gdb_stdout);
+ help_list (infolist, "info ", all_commands, gdb_stdout);
}
/* The "show" command with no arguments shows all the settings. */
help_cmd (command, gdb_stdout);
}
\f
-/* The "complete" command is used by Emacs to implement completion. */
+/* Note: The "complete" command is used by Emacs to implement completion.
+ [Is that why this function writes output with *_unfiltered?] */
static void
complete_command (char *arg, int from_tty)
dont_repeat ();
+ if (max_completions == 0)
+ {
+ /* Only print this for non-mi frontends. An MI frontend may not
+ be able to handle this. */
+ if (!ui_out_is_mi_like_p (current_uiout))
+ {
+ printf_unfiltered (_("max-completions is zero,"
+ " completion is disabled.\n"));
+ }
+ return;
+ }
+
if (arg == NULL)
arg = "";
argpoint = strlen (arg);
point--;
}
- arg_prefix = alloca (point - arg + 1);
+ arg_prefix = (char *) alloca (point - arg + 1);
memcpy (arg_prefix, arg, point - arg);
arg_prefix[point - arg] = 0;
xfree (prev);
VEC_free (char_ptr, completions);
+
+ if (size == max_completions)
+ {
+ /* ARG_PREFIX and POINT are included in the output so that emacs
+ will include the message in the output. */
+ printf_unfiltered (_("%s%s %s\n"),
+ arg_prefix, point,
+ get_max_completions_reached_message ());
+ }
}
}
printf_filtered ("\n");
}
+static void
+show_configuration (char *args, int from_tty)
+{
+ print_gdb_configuration (gdb_stdout);
+}
+
/* Handle the quit command. */
void
if (!quit_confirm ())
error (_("Not confirmed."));
- disconnect_tracing (from_tty);
+ query_if_trace_running (from_tty);
quit_force (args, from_tty);
}
/* Found something other than leading repetitions of "/..". */
int found_real_path;
char *p;
+ struct cleanup *cleanup;
/* If the new directory is absolute, repeat is a no-op; if relative,
repeat might be useful but is more likely to be a mistake. */
dir = "~";
dir = tilde_expand (dir);
- make_cleanup (xfree, dir);
+ cleanup = make_cleanup (xfree, dir);
if (chdir (dir) < 0)
perror_with_name (dir);
if (from_tty)
pwd_command ((char *) 0, 1);
+
+ do_cleanups (cleanup);
}
\f
/* Show the current value of the 'script-extension' option. */
char *file;
int fd;
struct cleanup *old_cleanups;
- int search_flags = OPF_TRY_CWD_FIRST;
+ int search_flags = OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH;
file = tilde_expand (script_file);
old_cleanups = make_cleanup (xfree, file);
return 1;
}
-/* Load script FILE, which has already been opened as STREAM. */
+/* Load script FILE, which has already been opened as STREAM.
+ FILE_TO_OPEN is the form of FILE to use if one needs to open the file.
+ This is provided as FILE may have been found via the source search path.
+ An important thing to note here is that FILE may be a symlink to a file
+ with a different or non-existing suffix, and thus one cannot infer the
+ extension language from FILE_TO_OPEN. */
static void
-source_script_from_stream (FILE *stream, const char *file)
+source_script_from_stream (FILE *stream, const char *file,
+ const char *file_to_open)
{
- if (script_ext_mode != script_ext_off
- && strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
+ if (script_ext_mode != script_ext_off)
{
- volatile struct gdb_exception e;
+ const struct extension_language_defn *extlang
+ = get_ext_lang_of_file (file);
- TRY_CATCH (e, RETURN_MASK_ERROR)
- {
- source_python_script (stream, file);
- }
- if (e.reason < 0)
+ if (extlang != NULL)
{
- /* Should we fallback to ye olde GDB script mode? */
- if (script_ext_mode == script_ext_soft
- && e.reason == RETURN_ERROR && e.error == UNSUPPORTED_ERROR)
+ if (ext_lang_present_p (extlang))
{
- fseek (stream, 0, SEEK_SET);
- script_from_file (stream, (char*) file);
+ script_sourcer_func *sourcer
+ = ext_lang_script_sourcer (extlang);
+
+ gdb_assert (sourcer != NULL);
+ sourcer (extlang, stream, file_to_open);
+ return;
}
- else
+ else if (script_ext_mode == script_ext_soft)
{
- /* Nope, just punt. */
- throw_exception (e);
+ /* Assume the file is a gdb script.
+ This is handled below. */
}
+ else
+ throw_ext_lang_unsupported (extlang);
}
}
- else
- script_from_file (stream, file);
+
+ script_from_file (stream, file);
}
/* Worker to perform the "source" command.
/* The script wasn't found, or was otherwise inaccessible.
If the source command was invoked interactively, throw an
error. Otherwise (e.g. if it was invoked by a script),
- silently ignore the error. */
+ just emit a warning, rather than cause an error. */
if (from_tty)
perror_with_name (file);
else
- return;
+ {
+ perror_warning_with_name (file);
+ return;
+ }
}
old_cleanups = make_cleanup (xfree, full_path);
anyway so that error messages show the actual file used. But only do
this if we (may have) used search_path, as printing the full path in
errors for the non-search case can be more noise than signal. */
- source_script_from_stream (stream, search_path ? full_path : file);
+ source_script_from_stream (stream, file, search_path ? full_path : file);
do_cleanups (old_cleanups);
}
for use in loading .gdbinit scripts. */
void
-source_script (char *file, int from_tty)
+source_script (const char *file, int from_tty)
{
source_script_with_search (file, from_tty, 0);
}
{
struct cleanup *old_cleanups;
char *file = args;
- int *old_source_verbose = xmalloc (sizeof(int));
+ int *old_source_verbose = XNEW (int);
int search_path = 0;
*old_source_verbose = source_verbose;
{
/* Make sure leading white space does not break the
comparisons. */
- while (isspace(args[0]))
- args++;
+ args = skip_spaces (args);
if (args[0] != '-')
break;
break;
}
- while (isspace (args[0]))
- args++;
- file = args;
+ file = skip_spaces (args);
}
source_script_with_search (file, from_tty, search_path);
static void
echo_command (char *text, int from_tty)
{
- char *p = text;
+ const char *p = text;
int c;
if (text)
{
const char *p, *user_shell;
+ close_most_fds ();
+
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
user_shell = "/bin/sh";
struct symtabs_and_lines sals;
struct symtab_and_line sal;
struct symbol *sym;
- char *arg1;
char *editor;
char *p;
const char *fn;
}
else
{
- /* Now should only be one argument -- decode it in SAL. */
+ struct cleanup *cleanup;
+ struct event_location *location;
+ char *arg1;
+ /* Now should only be one argument -- decode it in SAL. */
arg1 = arg;
- sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
+ location = string_to_event_location (&arg1, current_language);
+ cleanup = make_cleanup_delete_event_location (location);
+ sals = decode_line_1 (location, DECODE_LINE_LIST_MODE, 0, 0);
filter_sals (&sals);
if (! sals.nelts)
{
/* C++ */
+ do_cleanups (cleanup);
return;
}
if (sals.nelts > 1)
{
ambiguous_line_spec (&sals);
xfree (sals.sals);
+ do_cleanups (cleanup);
return;
}
struct gdbarch *gdbarch;
if (sal.symtab == 0)
- /* FIXME-32x64--assumes sal.pc fits in long. */
error (_("No source file for address %s."),
- hex_string ((unsigned long) sal.pc));
+ paddress (get_current_arch (), sal.pc));
- gdbarch = get_objfile_arch (sal.symtab->objfile);
+ gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
sym = find_pc_function (sal.pc);
if (sym)
printf_filtered ("%s is in %s (%s:%d).\n",
if (sal.symtab == 0)
error (_("No line number known for %s."), arg);
+ do_cleanups (cleanup);
}
if ((editor = (char *) getenv ("EDITOR")) == NULL)
int dummy_beg = 0;
int linenum_beg = 0;
char *p;
+ struct cleanup *cleanup;
+
+ cleanup = make_cleanup (null_cleanup, NULL);
/* Pull in the current default source line if necessary. */
- if (arg == 0 || arg[0] == '+' || arg[0] == '-')
+ if (arg == NULL || ((arg[0] == '+' || arg[0] == '-') && arg[1] == '\0'))
{
set_default_source_symtab_and_line ();
cursal = get_current_source_symtab_and_line ();
- }
- /* "l" or "l +" lists next ten lines. */
+ /* If this is the first "list" since we've set the current
+ source line, center the listing around that line. */
+ if (get_first_line_listed () == 0)
+ {
+ int first;
- if (arg == 0 || strcmp (arg, "+") == 0)
- {
- print_source_lines (cursal.symtab, cursal.line,
- cursal.line + get_lines_to_list (), 0);
- return;
- }
+ first = max (cursal.line - get_lines_to_list () / 2, 1);
+
+ /* A small special case --- if listing backwards, and we
+ should list only one line, list the preceding line,
+ instead of the exact line we've just shown after e.g.,
+ stopping for a breakpoint. */
+ if (arg != NULL && arg[0] == '-'
+ && get_lines_to_list () == 1 && first > 1)
+ first -= 1;
+
+ print_source_lines (cursal.symtab, first,
+ first + get_lines_to_list (), 0);
+ }
+
+ /* "l" or "l +" lists next ten lines. */
+ else if (arg == NULL || arg[0] == '+')
+ print_source_lines (cursal.symtab, cursal.line,
+ cursal.line + get_lines_to_list (), 0);
+
+ /* "l -" lists previous ten lines, the ones before the ten just
+ listed. */
+ else if (arg[0] == '-')
+ print_source_lines (cursal.symtab,
+ max (get_first_line_listed ()
+ - get_lines_to_list (), 1),
+ get_first_line_listed (), 0);
- /* "l -" lists previous ten lines, the ones before the ten just
- listed. */
- if (strcmp (arg, "-") == 0)
- {
- print_source_lines (cursal.symtab,
- max (get_first_line_listed ()
- - get_lines_to_list (), 1),
- get_first_line_listed (), 0);
return;
}
dummy_beg = 1;
else
{
- sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
+ struct event_location *location;
+
+ location = string_to_event_location (&arg1, current_language);
+ make_cleanup_delete_event_location (location);
+ sals = decode_line_1 (location, DECODE_LINE_LIST_MODE, 0, 0);
filter_sals (&sals);
if (!sals.nelts)
- return; /* C++ */
+ {
+ /* C++ */
+ do_cleanups (cleanup);
+ return;
+ }
if (sals.nelts > 1)
{
ambiguous_line_spec (&sals);
xfree (sals.sals);
+ do_cleanups (cleanup);
return;
}
dummy_end = 1;
else
{
+ struct event_location *location;
+
+ location = string_to_event_location (&arg1, current_language);
+ make_cleanup_delete_event_location (location);
if (dummy_beg)
- sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
+ sals_end = decode_line_1 (location,
+ DECODE_LINE_LIST_MODE, 0, 0);
else
- sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE,
+ sals_end = decode_line_1 (location, DECODE_LINE_LIST_MODE,
sal.symtab, sal.line);
+
filter_sals (&sals_end);
if (sals_end.nelts == 0)
- return;
+ {
+ do_cleanups (cleanup);
+ return;
+ }
if (sals_end.nelts > 1)
{
ambiguous_line_spec (&sals_end);
xfree (sals_end.sals);
+ do_cleanups (cleanup);
return;
}
sal_end = sals_end.sals[0];
struct gdbarch *gdbarch;
if (sal.symtab == 0)
- /* FIXME-32x64--assumes sal.pc fits in long. */
error (_("No source file for address %s."),
- hex_string ((unsigned long) sal.pc));
+ paddress (get_current_arch (), sal.pc));
- gdbarch = get_objfile_arch (sal.symtab->objfile);
+ gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
sym = find_pc_function (sal.pc);
if (sym)
printf_filtered ("%s is in %s (%s:%d).\n",
? sal.line + get_lines_to_list ()
: sal_end.line + 1),
0);
+ do_cleanups (cleanup);
}
/* Subroutine of disassemble_command to simplify it.
/* Dump a specified section of assembly code.
Usage:
- disassemble [/mr]
+ disassemble [/mrs]
- dump the assembly code for the function of the current pc
- disassemble [/mr] addr
+ disassemble [/mrs] addr
- dump the assembly code for the function at ADDR
- disassemble [/mr] low,high
- disassemble [/mr] low,+length
+ disassemble [/mrs] low,high
+ disassemble [/mrs] low,+length
- dump the assembly code in the range [LOW,HIGH), or [LOW,LOW+length)
- A /m modifier will include source code with the assembly.
- A /r modifier will include raw instructions in hex with the assembly. */
+ A /m modifier will include source code with the assembly in a
+ "source centric" view. This view lists only the file of the first insn,
+ even if other source files are involved (e.g., inlined functions), and
+ the output is in source order, even with optimized code. This view is
+ considered deprecated as it hasn't been useful in practice.
+
+ A /r modifier will include raw instructions in hex with the assembly.
+
+ A /s modifier will include source code with the assembly, like /m, with
+ two important differences:
+ 1) The output is still in pc address order.
+ 2) File names and contents for all relevant source files are displayed. */
static void
disassemble_command (char *arg, int from_tty)
const char *name;
CORE_ADDR pc;
int flags;
+ const char *p;
+ p = arg;
name = NULL;
flags = 0;
- if (arg && *arg == '/')
+ if (p && *p == '/')
{
- ++arg;
+ ++p;
- if (*arg == '\0')
+ if (*p == '\0')
error (_("Missing modifier."));
- while (*arg && ! isspace (*arg))
+ while (*p && ! isspace (*p))
{
- switch (*arg++)
+ switch (*p++)
{
case 'm':
- flags |= DISASSEMBLY_SOURCE;
+ flags |= DISASSEMBLY_SOURCE_DEPRECATED;
break;
case 'r':
flags |= DISASSEMBLY_RAW_INSN;
break;
+ case 's':
+ flags |= DISASSEMBLY_SOURCE;
+ break;
default:
error (_("Invalid disassembly modifier."));
}
}
- while (isspace (*arg))
- ++arg;
+ p = skip_spaces_const (p);
}
- if (! arg || ! *arg)
+ if ((flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
+ == (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
+ error (_("Cannot specify both /m and /s."));
+
+ if (! p || ! *p)
{
flags |= DISASSEMBLY_OMIT_FNAME;
disassemble_current_function (flags);
return;
}
- pc = value_as_address (parse_to_comma_and_eval (&arg));
- if (arg[0] == ',')
- ++arg;
- if (arg[0] == '\0')
+ pc = value_as_address (parse_to_comma_and_eval (&p));
+ if (p[0] == ',')
+ ++p;
+ if (p[0] == '\0')
{
/* One argument. */
if (find_pc_partial_function (pc, &name, &low, &high) == 0)
/* Two arguments. */
int incl_flag = 0;
low = pc;
- while (isspace (*arg))
- arg++;
- if (arg[0] == '+')
+ p = skip_spaces_const (p);
+ if (p[0] == '+')
{
- ++arg;
+ ++p;
incl_flag = 1;
}
- high = parse_and_eval_address (arg);
+ high = parse_and_eval_address (p);
if (incl_flag)
high += low;
}
p = "make";
else
{
- p = xmalloc (sizeof ("make ") + strlen (arg));
+ p = (char *) xmalloc (sizeof ("make ") + strlen (arg));
strcpy (p, "make ");
strcpy (p + sizeof ("make ") - 1, arg);
}
if (args)
{
- char *comname = args;
+ const char *comname = args;
c = lookup_cmd (&comname, cmdlist, "", 0, 1);
- /* c->user_commands would be NULL if it's a python command. */
- if (c->class != class_user || !c->user_commands)
+ if (!cli_user_command_p (c))
error (_("Not a user command."));
show_user_1 (c, "", args, gdb_stdout);
}
{
for (c = cmdlist; c; c = c->next)
{
- if (c->class == class_user || c->prefixlist != NULL)
+ if (cli_user_command_p (c) || c->prefixlist != NULL)
show_user_1 (c, "", c->name, gdb_stdout);
}
}
Return TRUE if COMMAND exists, unambiguously. Otherwise FALSE. */
static int
-valid_command_p (char *command)
+valid_command_p (const char *command)
{
struct cmd_list_element *c;
char *args2, *equals, *alias, *command;
char **alias_argv, **command_argv;
dyn_string_t alias_dyn_string, command_dyn_string;
+ struct cleanup *cleanup;
static const char usage[] = N_("Usage: alias [-a] [--] ALIAS = COMMAND");
if (args == NULL || strchr (args, '=') == NULL)
error (_(usage));
args2 = xstrdup (args);
- make_cleanup (xfree, args2);
+ cleanup = make_cleanup (xfree, args2);
equals = strchr (args2, '=');
*equals = '\0';
alias_argv = gdb_buildargv (args2);
else
{
dyn_string_t alias_prefix_dyn_string, command_prefix_dyn_string;
- char *alias_prefix, *command_prefix;
+ const char *alias_prefix, *command_prefix;
struct cmd_list_element *c_alias, *c_command;
if (alias_argc != command_argc)
command_argv[command_argc - 1],
class_alias, abbrev_flag, c_command->prefixlist);
}
+
+ do_cleanups (cleanup);
}
\f
/* Print a list of files and line numbers which a user may choose from
static int
compare_symtabs (const void *a, const void *b)
{
- const struct symtab_and_line *sala = a;
- const struct symtab_and_line *salb = b;
+ const struct symtab_and_line *sala = (const struct symtab_and_line *) a;
+ const struct symtab_and_line *salb = (const struct symtab_and_line *) b;
+ const char *dira = SYMTAB_DIRNAME (sala->symtab);
+ const char *dirb = SYMTAB_DIRNAME (salb->symtab);
int r;
- if (!sala->symtab->dirname)
+ if (dira == NULL)
{
- if (salb->symtab->dirname)
+ if (dirb != NULL)
return -1;
}
- else if (!salb->symtab->dirname)
+ else if (dirb == NULL)
{
- if (sala->symtab->dirname)
+ if (dira != NULL)
return 1;
}
else
{
- r = filename_cmp (sala->symtab->dirname, salb->symtab->dirname);
+ r = filename_cmp (dira, dirb);
if (r)
return r;
}
{
printf_unfiltered (_("\"set debug\" must be followed by "
"the name of a debug subcommand.\n"));
- help_list (setdebuglist, "set debug ", -1, gdb_stdout);
+ help_list (setdebuglist, "set debug ", all_commands, gdb_stdout);
}
static void
init_cmd_lists (void)
{
max_user_call_depth = 1024;
-
- cmdlist = NULL;
- infolist = NULL;
- enablelist = NULL;
- disablelist = NULL;
- togglelist = NULL;
- stoplist = NULL;
- deletelist = NULL;
- detachlist = NULL;
- setlist = NULL;
- unsetlist = NULL;
- showlist = NULL;
- sethistlist = NULL;
- showhistlist = NULL;
- unsethistlist = NULL;
- maintenancelist = NULL;
- maintenanceinfolist = NULL;
- maintenanceprintlist = NULL;
- setprintlist = NULL;
- showprintlist = NULL;
- setchecklist = NULL;
- showchecklist = NULL;
}
static void
}
static void
-show_baud_rate (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
-{
- fprintf_filtered (file, _("Baud rate for remote serial I/O is %s.\n"),
- value);
-}
-
-static void
show_remote_debug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
show_script_ext_mode,
&setlist, &showlist);
- add_com ("quit", class_support, quit_command, _("Exit gdb."));
+ add_com ("quit", class_support, quit_command, _("\
+Exit gdb.\n\
+Usage: quit [EXPR]\n\
+The optional expression EXPR, if present, is evaluated and the result\n\
+used as GDB's exit code. The default is zero."));
c = add_com ("help", class_support, help_command,
_("Print list of commands."));
set_cmd_completer (c, command_completer);
add_cmd ("version", no_set_class, show_version,
_("Show what version of GDB this is."), &showlist);
- /* If target is open when baud changes, it doesn't take effect until
- the next open (I think, not sure). */
- add_setshow_zinteger_cmd ("remotebaud", no_class, &baud_rate, _("\
-Set baud rate for remote serial I/O."), _("\
-Show baud rate for remote serial I/O."), _("\
-This value is used to set the speed of the serial port when debugging\n\
-using remote targets."),
- NULL,
- show_baud_rate,
- &setlist, &showlist);
+ add_cmd ("configuration", no_set_class, show_configuration,
+ _("Show how GDB was configured at build time."), &showlist);
add_setshow_zinteger_cmd ("remote", no_class, &remote_debug, _("\
Set debugging of remote protocol."), _("\
With two args if one is empty it stands for ten lines away from \
the other arg."));
- if (!xdb_commands)
- add_com_alias ("l", "list", class_files, 1);
- else
- add_com_alias ("v", "list", class_files, 1);
+ add_com_alias ("l", "list", class_files, 1);
if (dbx_commands)
add_com_alias ("file", "list", class_files, 1);
c = add_com ("disassemble", class_vars, disassemble_command, _("\
Disassemble a specified section of memory.\n\
Default is the function surrounding the pc of the selected frame.\n\
+\n\
With a /m modifier, source lines are included (if available).\n\
+This view is \"source centric\": the output is in source line order,\n\
+regardless of any optimization that is present. Only the main source file\n\
+is displayed, not those of, e.g., any inlined functions.\n\
+This modifier hasn't proved useful in practice and is deprecated\n\
+in favor of /s.\n\
+\n\
+With a /s modifier, source lines are included (if available).\n\
+This differs from /m in two important respects:\n\
+- the output is still in pc address order, and\n\
+- file names and contents for all relevant source files are displayed.\n\
+\n\
With a /r modifier, raw instructions in hex are included.\n\
+\n\
With a single argument, the function surrounding that address is dumped.\n\
Two arguments (separated by a comma) are taken as a range of memory to dump,\n\
in the form of \"start,end\", or \"start,+length\".\n\
So, for example, if you want to disassemble function bar in file foo.c\n\
you must type \"disassemble 'foo.c'::bar\" and not \"disassemble foo.c:bar\"."));
set_cmd_completer (c, location_completer);
- if (xdb_commands)
- add_com_alias ("va", "disassemble", class_xdb, 0);
add_com_alias ("!", "shell", class_support, 0);
Run the ``make'' program using the rest of the line as arguments."));
set_cmd_completer (c, filename_completer);
add_cmd ("user", no_class, show_user, _("\
-Show definitions of non-python user defined commands.\n\
+Show definitions of non-python/scheme user defined commands.\n\
Argument is the name of the user defined command.\n\
With no argument, show definitions of all user defined commands."), &showlist);
add_com ("apropos", class_support, apropos_command,
add_setshow_uinteger_cmd ("max-user-call-depth", no_class,
&max_user_call_depth, _("\
-Set the max call depth for non-python user-defined commands."), _("\
-Show the max call depth for non-python user-defined commands."), NULL,
+Set the max call depth for non-python/scheme user-defined commands."), _("\
+Show the max call depth for non-python/scheme user-defined commands."), NULL,
NULL,
show_max_user_call_depth,
&setlist, &showlist);