/* Top level `main' program for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbtypes.h"
#include "expression.h"
#include "language.h"
-#include "serial.h" /* For job_control. */
+#include "terminal.h" /* For job_control. */
#include "getopt.h"
command_loop_marker PARAMS ((int));
static void
-print_gdb_version PARAMS ((FILE *));
+print_gdb_version PARAMS ((GDB_FILE *));
static void
quit_command PARAMS ((char *, int));
/* Canonical host name as a string. */
-extern char *host_canonical;
+extern char *host_name;
/* Canonical target name as a string. */
-extern char *target_canonical;
-
-/* Message to be printed before the error message, when an error occurs. */
-
-extern char *error_pre_print;
-
-/* Message to be printed before the warning message, when a warning occurs. */
-
-extern char *warning_pre_print;
+extern char *target_name;
extern char lang_frame_mismatch_warn[]; /* language.c */
struct cmd_list_element *showchecklist;
-/* stdio stream that command input is being read from. */
+/* stdio stream that command input is being read from. Set to stdin normally.
+ Set by source_command to the file we are sourcing. Set to NULL if we are
+ executing a user-defined command. */
FILE *instream;
int linesize = 100;
/* Baud rate specified for talking to serial target systems. Default
- is left as a zero pointer, so targets can choose their own defaults. */
+ is left as -1, so targets can choose their own defaults. */
+/* FIXME: This means that "show remotebaud" and gr_files_info can print -1
+ or (unsigned int)-1. This is a Bad User Interface. */
+
+int baud_rate = -1;
-char *baud_rate;
+/* Non-zero tells remote* modules to output debugging info. */
+
+int remote_debug = 0;
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
/* Some System V have job control but not sigsetmask(). */
#if !defined (HAVE_SIGSETMASK)
-#define HAVE_SIGSETMASK !defined (USG)
+#if !defined (USG)
+#define HAVE_SIGSETMASK 1
+#else
+#define HAVE_SIGSETMASK 0
+#endif
#endif
#if 0 == (HAVE_SIGSETMASK)
print ERRSTRING, print the specific error message, then return
zero.
+ Must not be called with immediate_quit in effect (bad things might
+ happen, say we got a signal in the middle of a memcpy to quit_return).
+ This is an OK restriction; with very few exceptions immediate_quit can
+ be replaced by judicious use of QUIT.
+
MASK specifies what to catch; it is normally set to
RETURN_MASK_ALL, if for no other reason than that the code which
calls catch_errors might not be set up to deal with a quit which
return 0;
}
\f
+/* Line number we are currently in in a file which is being sourced. */
+static int source_line_number;
+
+/* Name of the file we are sourcing. */
+static char *source_file_name;
+
+/* Buffer containing the error_pre_print used by the source stuff.
+ Malloc'd. */
+static char *source_error;
+static int source_error_allocated;
+
+/* Something to glom on to the start of error_pre_print if source_file_name
+ is set. */
+static char *source_pre_error;
+
/* Clean up on error during a "source" command (or execution of a
user-defined command). */
quiet = 1;
break;
case 'b':
- baud_rate = optarg;
+ {
+ int i;
+ char *p;
+
+ i = strtol (optarg, &p, 0);
+ if (i == 0 && p == optarg)
+ warning ("Could not set baud rate to `%s'.\n", optarg);
+ else
+ baud_rate = i;
+ }
break;
+
#ifdef ADDITIONAL_OPTION_CASES
ADDITIONAL_OPTION_CASES
#endif
case '?':
- fprintf (stderr,
+ fprintf_unfiltered (gdb_stderr,
"Use `%s --help' for a complete list of options.\n",
argv[0]);
exit (1);
corearg = argv[optind];
break;
case 3:
- fprintf (stderr,
+ fprintf_unfiltered (gdb_stderr,
"Excess command line arguments ignored. (%s%s)\n",
argv[optind], (optind == argc - 1) ? "" : " ...");
break;
after initialize_all_files. */
if (print_version)
{
- print_gdb_version (stdout);
+ print_gdb_version (gdb_stdout);
wrap_here ("");
printf_filtered ("\n");
exit (0);
are printing the version here, and the help is long enough
already. */
- print_gdb_version (stdout);
+ print_gdb_version (gdb_stdout);
/* Make sure the output gets printed. */
wrap_here ("");
printf_filtered ("\n");
/* But don't use *_filtered here. We don't want to prompt for continue
no matter how small the screen or how much we're going to print. */
- fputs ("\
+ fputs_unfiltered ("\
This is the GNU debugger. Usage:\n\
gdb [options] [executable-file [core-file or process-id]]\n\
Options:\n\
-b BAUDRATE Set serial port baud rate used for remote debugging.\n\
--mapped Use mapped symbol files if supported on this system.\n\
--readnow Fully read symbol files on first access.\n\
-", stdout);
+", gdb_stdout);
#ifdef ADDITIONAL_OPTION_HELP
- fputs (ADDITIONAL_OPTION_HELP, stdout);
+ fputs_unfiltered (ADDITIONAL_OPTION_HELP, gdb_stdout);
#endif
- fputs ("\n\
+ fputs_unfiltered ("\n\
For more information, type \"help\" from within GDB, or consult the\n\
-GDB manual (available as on-line info or a printed manual).\n", stdout);
+GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
exit (0);
}
/* 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 (stdout);
+ print_gdb_version (gdb_stdout);
if (symarg)
printf_filtered ("..");
wrap_here("");
- fflush (stdout); /* Force to screen during slow operations */
+ gdb_flush (gdb_stdout); /* Force to screen during slow operations */
}
error_pre_print = "\n\n";
/* Don't use a _filtered function here. It causes the assumed
character position to be off, since the newline we read from
the user is not accounted for. */
- fputs (prrompt, stdout);
- fflush (stdout);
+ fputs_unfiltered (prrompt, gdb_stdout);
+ gdb_flush (gdb_stdout);
}
result = (char *) xmalloc (result_size);
if (c == EOF)
{
+ if (input_index > 0)
+ /* The last line does not end with a newline. Return it, and
+ if we are called again fgetc will still return EOF and
+ we'll return NULL then. */
+ break;
free (result);
return NULL;
}
#else
signal (STOP_SIGNAL, stop_sig);
#endif
- printf ("%s", prompt);
- fflush (stdout);
+ printf_unfiltered ("%s", prompt);
+ gdb_flush (gdb_stdout);
/* Forget about any previous command -- null line now will do nothing. */
dont_repeat ();
while (1)
{
- /* Reports are that some Sys V's don't flush stdout/err on reads
+ /* Reports are that some Sys V's don't flush gdb_stdout/err on reads
from stdin, when stdin/out are sockets rather than ttys. So we
have to do it ourselves, to make emacs-gdb and xxgdb work.
On other machines, doing this once per input should be a cheap nop. */
- fflush (stdout);
- fflush (stderr);
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ if (source_file_name != NULL)
+ {
+ ++source_line_number;
+ sprintf (source_error,
+ "%s%s:%d: Error in sourced command file:\n",
+ source_pre_error,
+ source_file_name,
+ source_line_number);
+ error_pre_print = source_error;
+ }
/* Don't use fancy stuff if not talking to stdin. */
if (command_editing_p && instream == stdin
if (expanded)
{
/* Print the changes. */
- printf ("%s\n", history_value);
+ printf_unfiltered ("%s\n", history_value);
/* If there was an error, call this function again. */
if (expanded < 0)
char *arg;
int from_tty;
{
- printf ("\"info\" must be followed by the name of an info command.\n");
- help_list (infolist, "info ", -1, stdout);
+ 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. */
char *command;
int from_tty; /* Ignored */
{
- help_cmd (command, stdout);
+ help_cmd (command, gdb_stdout);
}
\f
static void
if (from_tty)
{
- printf ("Type commands for definition of \"%s\".\n\
+ printf_unfiltered ("Type commands for definition of \"%s\".\n\
End with a line saying just \"end\".\n", comname);
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
cmds = read_command_lines ();
error ("Command \"%s\" is built-in.", comname);
if (from_tty)
- printf ("Type documentation for \"%s\".\n\
+ printf_unfiltered ("Type documentation for \"%s\".\n\
End with a line saying just \"end\".\n", comname);
doclines = read_command_lines ();
static void
print_gnu_advertisement()
{
- printf ("\
+ printf_unfiltered ("\
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 (stream)
- FILE *stream;
+ GDB_FILE *stream;
{
fprintf_filtered (stream, "\
-GDB %s (%s", version, host_canonical);
+GDB %s (%s", version, host_name);
- if (strcmp(host_canonical, target_canonical))
- fprintf_filtered (stream, " --target %s", target_canonical);
+ if (!STREQ (host_name, target_name))
+ fprintf_filtered (stream, " --target %s", target_name);
fprintf_filtered (stream, "), ");
wrap_here("");
- fprintf_filtered (stream, "Copyright 1993 Free Software Foundation, Inc.");
+ fprintf_filtered (stream, "Copyright 1994 Free Software Foundation, Inc.");
}
/* ARGSUSED */
{
immediate_quit++;
print_gnu_advertisement ();
- print_gdb_version (stdout);
+ print_gdb_version (gdb_stdout);
printf_filtered ("\n");
immediate_quit--;
}
void
print_prompt ()
{
- printf ("%s", prompt);
- fflush (stdout);
+ printf_unfiltered ("%s", prompt);
+ gdb_flush (gdb_stdout);
}
\f
static void
getcwd (dirbuf, sizeof (dirbuf));
if (!STREQ (dirbuf, current_directory))
- printf ("Working directory %s\n (canonically %s).\n",
+ printf_unfiltered ("Working directory %s\n (canonically %s).\n",
current_directory, dirbuf);
else
- printf ("Working directory %s.\n", current_directory);
+ printf_unfiltered ("Working directory %s.\n", current_directory);
}
static void
pwd_command ((char *) 0, 1);
}
\f
+struct source_cleanup_lines_args {
+ int old_line;
+ char *old_file;
+ char *old_pre_error;
+ char *old_error_pre_print;
+};
+
+static void
+source_cleanup_lines (args)
+ PTR args;
+{
+ struct source_cleanup_lines_args *p =
+ (struct source_cleanup_lines_args *)args;
+ source_line_number = p->old_line;
+ source_file_name = p->old_file;
+ source_pre_error = p->old_pre_error;
+ error_pre_print = p->old_error_pre_print;
+}
+
/* ARGSUSED */
static void
source_command (args, from_tty)
int from_tty;
{
FILE *stream;
- struct cleanup *cleanups;
+ struct cleanup *old_cleanups;
char *file = args;
+ struct source_cleanup_lines_args old_lines;
+ int needed_length;
if (file == NULL)
{
}
file = tilde_expand (file);
- make_cleanup (free, file);
+ old_cleanups = make_cleanup (free, file);
stream = fopen (file, FOPEN_RT);
if (stream == 0)
perror_with_name (file);
- cleanups = make_cleanup (fclose, stream);
+ make_cleanup (fclose, stream);
+
+ old_lines.old_line = source_line_number;
+ old_lines.old_file = source_file_name;
+ old_lines.old_pre_error = source_pre_error;
+ old_lines.old_error_pre_print = error_pre_print;
+ make_cleanup (source_cleanup_lines, &old_lines);
+ source_line_number = 0;
+ source_file_name = file;
+ source_pre_error = error_pre_print == NULL ? "" : error_pre_print;
+ source_pre_error = savestring (source_pre_error, strlen (source_pre_error));
+ make_cleanup (free, source_pre_error);
+ /* This will get set every time we read a line. So it won't stay "" for
+ long. */
+ error_pre_print = "";
+
+ needed_length = strlen (source_file_name) + strlen (source_pre_error) + 80;
+ if (source_error_allocated < needed_length)
+ {
+ source_error_allocated *= 2;
+ if (source_error_allocated < needed_length)
+ source_error_allocated = needed_length;
+ if (source_error == NULL)
+ source_error = xmalloc (source_error_allocated);
+ else
+ source_error = xrealloc (source_error, source_error_allocated);
+ }
read_command_file (stream);
- do_cleanups (cleanups);
+ do_cleanups (old_cleanups);
}
/* ARGSUSED */
/* Force this output to appear now. */
wrap_here ("");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
\f
than the number of the last command). Relative to history_base. */
int hist_len;
- extern struct _hist_entry *history_get PARAMS ((int));
+ extern HIST_ENTRY *history_get PARAMS ((int));
extern int history_base;
/* Print out some of the commands from the command history. */
char *args;
int from_tty;
{
- printf ("\"set history\" must be followed by the name of a history subcommand.\n");
- help_list (sethistlist, "set history ", -1, stdout);
+ printf_unfiltered ("\"set history\" must be followed by the name of a history subcommand.\n");
+ help_list (sethistlist, "set history ", -1, gdb_stdout);
}
/* ARGSUSED */
add_cmd ("version", no_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_show_from_set (add_set_cmd ("remotebaud", no_class,
+ var_zinteger, (char *)&baud_rate,
+ "Set baud rate for remote serial I/O.\n\
+This value is used to set the speed of the serial port when debugging\n\
+using remote targets.", &setlist),
+ &showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotedebug", no_class, var_zinteger, (char *)&remote_debug,
+ "Set debugging of remote protocol.\n\
+When enabled, each packet sent or received with the remote target\n\
+is displayed.", &setlist),
+ &showlist);
}