📄 cli-cmds.c
字号:
/* GDB CLI commands. Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "defs.h"#include "readline/readline.h"#include "readline/tilde.h"#include "completer.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 "frame.h"#include "value.h"#include "language.h"#include "filenames.h" /* for DOSish file names */#include "objfiles.h"#include "source.h"#include "disasm.h"#include "ui-out.h"#include "top.h"#include "cli/cli-decode.h"#include "cli/cli-script.h"#include "cli/cli-setshow.h"#include "cli/cli-cmds.h"#ifdef TUI#include "tui/tui.h" /* For tui_active et.al. */#endif#ifndef GDBINIT_FILENAME#define GDBINIT_FILENAME ".gdbinit"#endif/* Prototypes for local command functions */static void complete_command (char *, int);static void echo_command (char *, int);static void pwd_command (char *, int);static void show_version (char *, int);static void help_command (char *, int);static void show_command (char *, int);static void info_command (char *, int);static void show_debug (char *, int);static void set_debug (char *, int);static void show_user (char *, int);static void make_command (char *, int);static void shell_escape (char *, int);static void edit_command (char *, int);static void list_command (char *, int);void apropos_command (char *, int);/* Prototypes for local utility functions */static void ambiguous_line_spec (struct symtabs_and_lines *);/* Limit the call depth of user-defined commands */int max_user_call_depth;/* Define all cmd_list_elements. *//* Chain containing all defined commands. */struct cmd_list_element *cmdlist;/* Chain containing all defined info subcommands. */struct cmd_list_element *infolist;/* Chain containing all defined enable subcommands. */struct cmd_list_element *enablelist;/* Chain containing all defined disable subcommands. */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;/* Chain containing all defined delete subcommands. */struct cmd_list_element *deletelist;/* Chain containing all defined "enable breakpoint" subcommands. */struct cmd_list_element *enablebreaklist;/* Chain containing all defined set subcommands */struct cmd_list_element *setlist;/* Chain containing all defined unset subcommands */struct cmd_list_element *unsetlist;/* Chain containing all defined show subcommands. */struct cmd_list_element *showlist;/* Chain containing all defined \"set history\". */struct cmd_list_element *sethistlist;/* Chain containing all defined \"show history\". */struct cmd_list_element *showhistlist;/* Chain containing all defined \"unset history\". */struct cmd_list_element *unsethistlist;/* Chain containing all defined maintenance subcommands. */struct cmd_list_element *maintenancelist;/* Chain containing all defined "maintenance info" subcommands. */struct cmd_list_element *maintenanceinfolist;/* Chain containing all defined "maintenance print" subcommands. */struct cmd_list_element *maintenanceprintlist;struct cmd_list_element *setprintlist;struct cmd_list_element *showprintlist;struct cmd_list_element *setdebuglist;struct cmd_list_element *showdebuglist;struct cmd_list_element *setchecklist;struct cmd_list_element *showchecklist;/* Utility used everywhere when at least one argument is needed and none is supplied. */voiderror_no_arg (char *why){ error ("Argument required (%s).", why);}/* The "info" command is defined as a prefix, with allow_unknown = 0. Therefore, its own definition is called only for "info" with no args. */static voidinfo_command (char *arg, int from_tty){ printf_unfiltered ("\"info\" must be followed by the name of an info command.\n"); help_list (infolist, "info ", -1, gdb_stdout);}/* The "show" command with no arguments shows all the settings. */static voidshow_command (char *arg, int from_tty){ cmd_show_list (showlist, from_tty, "");}/* Provide documentation on command or list given by COMMAND. FROM_TTY is ignored. */static voidhelp_command (char *command, int from_tty){ help_cmd (command, gdb_stdout);}/* String compare function for qsort. */static intcompare_strings (const void *arg1, const void *arg2){ const char **s1 = (const char **) arg1; const char **s2 = (const char **) arg2; return strcmp (*s1, *s2);}/* The "complete" command is used by Emacs to implement completion. */static voidcomplete_command (char *arg, int from_tty){ int i; int argpoint; char **completions, *point, *arg_prefix; dont_repeat (); if (arg == NULL) arg = ""; argpoint = strlen (arg); /* complete_line assumes that its first argument is somewhere within, and except for filenames at the beginning of, the word to be completed. The following crude imitation of readline's word-breaking tries to accomodate this. */ point = arg + argpoint; while (point > arg) { if (strchr (rl_completer_word_break_characters, point[-1]) != 0) break; point--; } arg_prefix = alloca (point - arg + 1); memcpy (arg_prefix, arg, point - arg); arg_prefix[point - arg] = 0; completions = complete_line (point, arg, argpoint); if (completions) { int item, size; for (size = 0; completions[size]; ++size) ; qsort (completions, size, sizeof (char *), compare_strings); /* We do extra processing here since we only want to print each unique item once. */ item = 0; while (item < size) { int next_item; printf_unfiltered ("%s%s\n", arg_prefix, completions[item]); next_item = item + 1; while (next_item < size && ! strcmp (completions[item], completions[next_item])) { xfree (completions[next_item]); ++next_item; } xfree (completions[item]); item = next_item; } xfree (completions); }}intis_complete_command (struct cmd_list_element *c){ return cmd_cfunc_eq (c, complete_command);}static voidshow_version (char *args, int from_tty){ immediate_quit++; print_gdb_version (gdb_stdout); printf_filtered ("\n"); immediate_quit--;}/* Handle the quit command. */voidquit_command (char *args, int from_tty){ if (!quit_confirm ()) error ("Not confirmed."); quit_force (args, from_tty);}static voidpwd_command (char *args, int from_tty){ if (args) error ("The \"pwd\" command does not take an argument: %s", args); getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); if (strcmp (gdb_dirbuf, current_directory) != 0) printf_unfiltered ("Working directory %s\n (canonically %s).\n", current_directory, gdb_dirbuf); else printf_unfiltered ("Working directory %s.\n", current_directory);}voidcd_command (char *dir, int from_tty){ int len; /* Found something other than leading repetitions of "/..". */ int found_real_path; char *p; /* 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. */ dont_repeat (); if (dir == 0) error_no_arg ("new working directory"); dir = tilde_expand (dir); make_cleanup (xfree, dir); if (chdir (dir) < 0) perror_with_name (dir);#ifdef HAVE_DOS_BASED_FILE_SYSTEM /* There's too much mess with DOSish names like "d:", "d:.", "d:./foo" etc. Instead of having lots of special #ifdef'ed code, simply get the canonicalized name of the current directory. */ dir = getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));#endif len = strlen (dir); if (IS_DIR_SEPARATOR (dir[len - 1])) { /* Remove the trailing slash unless this is a root directory (including a drive letter on non-Unix systems). */ if (!(len == 1) /* "/" */#ifdef HAVE_DOS_BASED_FILE_SYSTEM && !(len == 3 && dir[1] == ':') /* "d:/" */#endif ) len--; } dir = savestring (dir, len); if (IS_ABSOLUTE_PATH (dir)) current_directory = dir; else { if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])) current_directory = concat (current_directory, dir, NULL); else current_directory = concat (current_directory, SLASH_STRING, dir, NULL); xfree (dir); } /* Now simplify any occurrences of `.' and `..' in the pathname. */ found_real_path = 0; for (p = current_directory; *p;) { if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.' && (p[2] == 0 || IS_DIR_SEPARATOR (p[2]))) strcpy (p, p + 2); else if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.' && p[2] == '.' && (p[3] == 0 || IS_DIR_SEPARATOR (p[3]))) { if (found_real_path) { /* Search backwards for the directory just before the "/.." and obliterate it and the "/..". */ char *q = p; while (q != current_directory && !IS_DIR_SEPARATOR (q[-1])) --q; if (q == current_directory) /* current_directory is a relative pathname ("can't happen"--leave it alone). */ ++p; else { strcpy (q - 1, p + 3); p = q - 1; } } else /* We are dealing with leading repetitions of "/..", for example "/../..", which is the Mach super-root. */ p += 3; } else { found_real_path = 1; ++p; } } forget_cached_source_info (); if (from_tty) pwd_command ((char *) 0, 1);}voidsource_command (char *args, int from_tty){ FILE *stream; struct cleanup *old_cleanups; char *file = args;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -