command_loop_marker PARAMS ((int));
static void
-print_gdb_version PARAMS ((void));
+print_gdb_version PARAMS ((FILE *));
static void
quit_command PARAMS ((char *, int));
static void
do_nothing PARAMS ((int));
+static int
+quit_cover PARAMS ((char *));
+
static void
disconnect PARAMS ((int));
disconnect (signo)
int signo;
{
- kill_inferior_fast ();
- signal (signo, SIG_DFL);
+ catch_errors (quit_cover, NULL, "Could not kill inferior process");
+ signal (SIGHUP, SIG_DFL);
kill (getpid (), SIGHUP);
}
+
+/* Just a little helper function for disconnect(). */
+
+static int
+quit_cover (s)
+char *s;
+{
+ caution = 0; /* Throw caution to the wind -- we're exiting.
+ This prevents asking the user dumb questions. */
+ quit_command((char *)0, 0);
+ return 0;
+}
\f
/* Clean up on error during a "source" command (or execution of a
user-defined command). */
{"m", no_argument, &mapped_symbol_files, 1},
{"quiet", no_argument, &quiet, 1},
{"q", no_argument, &quiet, 1},
+ {"silent", no_argument, &quiet, 1},
{"nx", no_argument, &inhibit_gdbinit, 1},
{"n", no_argument, &inhibit_gdbinit, 1},
{"batch", no_argument, &batch, 1},
ADDITIONAL_OPTION_CASES
#endif
case '?':
- fprintf_filtered (stderr,
- "Use `%s +help' for a complete list of options.\n",
+ fprintf (stderr,
+ "Use `%s --help' for a complete list of options.\n",
argv[0]);
exit (1);
}
-
}
+
if (print_help)
{
- fputs ("\
-This is GDB, the GNU debugger. Use the command\n\
- gdb [options] [executable [core-file]]\n\
-to enter the debugger.\n\
-\n\
-Options available are:\n\
+ print_gdb_version(stderr);
+ fputs ("\n\
+This is the GNU debugger. Usage:\n\
+ gdb [options] [executable-file [core-file or process-id]]\n\
+Options:\n\
-help Print this message.\n\
-quiet Do not print version number on startup.\n\
-fullname Output information used by emacs-GDB interface.\n\
corearg = argv[optind];
break;
case 3:
- fprintf_filtered (stderr,
+ fprintf (stderr,
"Excess command line arguments ignored. (%s%s)\n",
argv[optind], (optind == argc - 1) ? "" : " ...");
break;
/* Print all the junk at the top, with trailing "..." if we are about
to read a symbol file (possibly slowly). */
print_gnu_advertisement ();
- print_gdb_version ();
+ print_gdb_version (stdout);
if (symarg)
printf_filtered ("..");
wrap_here("");
/* We may get more than one warning, don't double space all of them... */
warning_pre_print = "\nwarning: ";
+ /* We need a default language for parsing expressions, so simple things like
+ "set width 0" won't fail if no language is explicitly set in a config file
+ or implicitly set by reading an executable during startup. */
+ set_language (language_c);
+ expected_language = current_language; /* don't warn about the change. */
+
/* Read and execute $HOME/.gdbinit file, if it exists. This is done
*before* all the command line arguments are processed; it sets
global parameters, which are independent of what file you are
strcat (homeinit, gdbinit);
if (!inhibit_gdbinit && access (homeinit, R_OK) == 0)
{
- /* The official language of expressions in $HOME/.gdbinit is C. */
- set_language (language_c);
if (!setjmp (to_top_level))
source_command (homeinit, 0);
}
if (execarg != NULL
&& symarg != NULL
- && strcmp (execarg, symarg) == 0)
+ && STREQ (execarg, symarg))
{
/* The exec file and the symbol-file are the same. If we can't open
it, better only print one error message. */
error_pre_print = "\n";
warning_pre_print = "\nwarning: ";
- /* Set the initial language. */
- {
- struct partial_symtab *pst = find_main_psymtab ();
- enum language lang = language_unknown;
- if (pst == NULL) ;
-#if 0
- /* A better solution would set the language when reading the psymtab.
- This would win for symbol file formats that encode the langauge,
- such as DWARF. But, we don't do that yet. FIXME */
- else if (pst->language != language_unknown)
- lang = pst->language;
-#endif
- else if (pst->filename != NULL)
- lang = deduce_language_from_filename (pst->filename);
- if (lang == language_unknown) /* Make C the default language */
- lang = language_c;
- set_language (lang);
- }
-
if (corearg != NULL)
if (!setjmp (to_top_level))
core_file_command (corearg, !batch);
if (!homedir
|| memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0)
- if (!setjmp (to_top_level))
- source_command (gdbinit, 0);
- do_cleanups (ALL_CLEANUPS);
-
- for (i = 0; i < ncmd; i++)
- if (!setjmp (to_top_level))
{
- if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
- read_command_file (stdin);
- else
- source_command (cmdarg[i], !batch);
- do_cleanups (ALL_CLEANUPS);
+ if (!setjmp (to_top_level))
+ source_command (gdbinit, 0);
}
+ do_cleanups (ALL_CLEANUPS);
+
+ for (i = 0; i < ncmd; i++)
+ {
+ if (!setjmp (to_top_level))
+ {
+ if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
+ read_command_file (stdin);
+ else
+ source_command (cmdarg[i], !batch);
+ do_cleanups (ALL_CLEANUPS);
+ }
+ }
free ((PTR)cmdarg);
/* Read in the old history after all the command files have been read. */
/* No exit -- exit is through quit_command. */
}
+void
+execute_user_command (c, args)
+ struct cmd_list_element *c;
+ char *args;
+{
+ register struct command_line *cmdlines;
+ struct cleanup *old_chain;
+
+ if (args)
+ error ("User-defined commands cannot take arguments.");
+
+ cmdlines = c->user_commands;
+ if (cmdlines == 0)
+ /* Null command */
+ return;
+
+ /* Set the instream to 0, indicating execution of a
+ user-defined function. */
+ old_chain = make_cleanup (source_cleanup, instream);
+ instream = (FILE *) 0;
+ while (cmdlines)
+ {
+ execute_command (cmdlines->line, 0);
+ cmdlines = cmdlines->next;
+ }
+ do_cleanups (old_chain);
+}
+
/* Execute the line P as a command.
Pass FROM_TTY as second argument to the defining function. */
int from_tty;
{
register struct cmd_list_element *c;
- register struct command_line *cmdlines;
register enum language flang;
- static const struct language_defn *saved_language = 0;
static int warned = 0;
free_all_values ();
c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* Pass null arg rather than an empty one. */
arg = *p ? p : 0;
+
+ /* If this command has been hooked, run the hook first. */
+ if (c->hook)
+ execute_user_command (c->hook, (char *)0);
+
if (c->class == class_user)
- {
- struct cleanup *old_chain;
-
- if (*p)
- error ("User-defined commands cannot take arguments.");
- cmdlines = c->user_commands;
- if (cmdlines == 0)
- /* Null command */
- return;
-
- /* Set the instream to 0, indicating execution of a
- user-defined function. */
- old_chain = make_cleanup (source_cleanup, instream);
- instream = (FILE *) 0;
- while (cmdlines)
- {
- execute_command (cmdlines->line, 0);
- cmdlines = cmdlines->next;
- }
- do_cleanups (old_chain);
- }
+ execute_user_command (c, arg);
else if (c->type == set_cmd || c->type == show_cmd)
do_setshow_command (arg, from_tty & caution, c);
else if (c->function.cfunc == NO_FUNCTION)
}
/* Tell the user if the language has changed (except first time). */
- if (current_language != saved_language)
+ if (current_language != expected_language)
{
if (language_mode == language_mode_auto) {
- if (saved_language)
- language_info (1); /* Print what changed. */
+ language_info (1); /* Print what changed. */
}
- saved_language = current_language;
warned = 0;
}
#else
signal (STOP_SIGNAL, stop_sig);
#endif
- printf_filtered ("%s", prompt);
+ printf ("%s", prompt);
fflush (stdout);
/* Forget about any previous command -- null line now will do nothing. */
if (expanded)
{
/* Print the changes. */
- printf_filtered ("%s\n", history_value);
+ printf ("%s\n", history_value);
/* If there was an error, call this function again. */
if (expanded < 0)
char *arg;
int from_tty;
{
- printf_filtered ("\"info\" must be followed by the name of an info command.\n");
+ printf ("\"info\" must be followed by the name of an info command.\n");
help_list (infolist, "info ", -1, stdout);
}
int from_tty;
{
register struct command_line *cmds;
- register struct cmd_list_element *c, *newc;
+ register struct cmd_list_element *c, *newc, *hookc = 0;
char *tem = comname;
+#define HOOK_STRING "hook-"
+#define HOOK_LEN 5
validate_comname (comname);
/* Look it up, and verify that we got an exact match. */
c = lookup_cmd (&tem, cmdlist, "", -1, 1);
- if (c && 0 != strcmp (comname, c->name))
+ if (c && !STREQ (comname, c->name))
c = 0;
if (c)
error ("Command \"%s\" not redefined.", c->name);
}
+ /* If this new command is a hook, then mark the command which it
+ is hooking. Note that we allow hooking `help' commands, so that
+ we can hook the `stop' pseudo-command. */
+
+ if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
+ {
+ /* Look up cmd it hooks, and verify that we got an exact match. */
+ tem = comname+HOOK_LEN;
+ hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
+ if (hookc && !STREQ (comname+HOOK_LEN, hookc->name))
+ hookc = 0;
+ if (!hookc)
+ {
+ warning ("Your new `%s' command does not hook any existing command.",
+ comname);
+ if (!query ("Proceed? ", (char *)0))
+ error ("Not confirmed.");
+ }
+ }
+
comname = savestring (comname, strlen (comname));
- /* If the rest of the commands will be case insensetive, this one
+ /* If the rest of the commands will be case insensitive, this one
should behave in the same manner. */
for (tem = comname; *tem; tem++)
if (isupper(*tem)) *tem = tolower(*tem);
if (from_tty)
{
- printf_filtered ("Type commands for definition of \"%s\".\n\
+ printf ("Type commands for definition of \"%s\".\n\
End with a line saying just \"end\".\n", comname);
fflush (stdout);
}
(c && c->class == class_user)
? c->doc : savestring ("User-defined.", 13), &cmdlist);
newc->user_commands = cmds;
+
+ /* If this new command is a hook, then mark both commands as being
+ tied. */
+ if (hookc)
+ {
+ hookc->hook = newc; /* Target gets hooked. */
+ newc->hookee = hookc; /* We are marked as hooking target cmd. */
+ }
}
static void
error ("Command \"%s\" is built-in.", comname);
if (from_tty)
- printf_filtered ("Type documentation for \"%s\".\n\
+ printf ("Type documentation for \"%s\".\n\
End with a line saying just \"end\".\n", comname);
doclines = read_command_lines ();
static void
print_gnu_advertisement()
{
- printf_filtered ("\
+ printf ("\
GDB is free software and you are welcome to distribute copies of it\n\
under certain conditions; type \"show copying\" to see the conditions.\n\
There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
}
static void
-print_gdb_version ()
+print_gdb_version (stream)
+ FILE *stream;
{
- printf_filtered ("\
+ fprintf_filtered (stream, "\
GDB %s, Copyright 1992 Free Software Foundation, Inc.",
version);
}
{
immediate_quit++;
print_gnu_advertisement ();
- print_gdb_version ();
+ print_gdb_version (stdout);
printf_filtered ("\n");
immediate_quit--;
}
void
print_prompt ()
{
- printf_filtered ("%s", prompt);
+ printf ("%s", prompt);
fflush (stdout);
}
\f
{
if (query ("The program is running. Quit anyway? "))
{
- target_kill ();
+ if (attach_flag)
+ target_detach (args, from_tty);
+ else
+ target_kill ();
}
else
error ("Not confirmed.");
if (args) error ("The \"pwd\" command does not take an argument: %s", args);
getcwd (dirbuf, sizeof (dirbuf));
- if (strcmp (dirbuf, current_directory))
- printf_filtered ("Working directory %s\n (canonically %s).\n",
+ if (!STREQ (dirbuf, current_directory))
+ printf ("Working directory %s\n (canonically %s).\n",
current_directory, dirbuf);
else
- printf_filtered ("Working directory %s.\n", current_directory);
+ printf ("Working directory %s.\n", current_directory);
}
static void
register int c;
if (text)
- while (c = *p++)
+ while ((c = *p++) != '\0')
{
if (c == '\\')
{
char *args;
int from_tty;
{
- printf_filtered ("\"set history\" must be followed by the name of a history subcommand.\n");
+ printf ("\"set history\" must be followed by the name of a history subcommand.\n");
help_list (sethistlist, "set history ", -1, stdout);
}
{
/* This message is based on ANSI C, section 4.7. Note that integer
divide by zero causes this, so "float" is a misnomer. */
+ signal (SIGFPE, float_handler);
error ("Erroneous arithmetic operation.");
}