xref: /csrg-svn/contrib/gdb-4.7.LBL/gdb/main.c (revision 69201)
169200Smckusick /* Top level `main' program for GDB, the GNU debugger.
269200Smckusick    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
369200Smckusick    Free Software Foundation, Inc.
469200Smckusick 
569200Smckusick This file is part of GDB.
669200Smckusick 
769200Smckusick This program is free software; you can redistribute it and/or modify
869200Smckusick it under the terms of the GNU General Public License as published by
969200Smckusick the Free Software Foundation; either version 2 of the License, or
1069200Smckusick (at your option) any later version.
1169200Smckusick 
1269200Smckusick This program is distributed in the hope that it will be useful,
1369200Smckusick but WITHOUT ANY WARRANTY; without even the implied warranty of
1469200Smckusick MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1569200Smckusick GNU General Public License for more details.
1669200Smckusick 
1769200Smckusick You should have received a copy of the GNU General Public License
1869200Smckusick along with this program; if not, write to the Free Software
1969200Smckusick Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
2069200Smckusick 
2169200Smckusick #include <stdio.h>
2269200Smckusick #include <sys/param.h>
2369200Smckusick int fclose ();
2469200Smckusick #include "defs.h"
2569200Smckusick #include "gdbcmd.h"
2669200Smckusick #include "call-cmds.h"
2769200Smckusick #include "gdbcore.h"
2869200Smckusick #include "symtab.h"
2969200Smckusick #include "inferior.h"
3069200Smckusick #include "signals.h"
3169200Smckusick #include "target.h"
3269200Smckusick #include "breakpoint.h"
3369200Smckusick #include "gdbtypes.h"
3469200Smckusick #include "expression.h"
3569200Smckusick #include "language.h"
3669200Smckusick 
3769200Smckusick #include "getopt.h"
3869200Smckusick 
3969200Smckusick /* readline include files */
4069200Smckusick #include "readline.h"
4169200Smckusick #include "history.h"
4269200Smckusick 
4369200Smckusick /* readline defines these.  */
4469200Smckusick #undef savestring
4569200Smckusick #undef CTRL
4669200Smckusick 
4769200Smckusick #ifdef USG
4869200Smckusick #include <sys/types.h>
4969200Smckusick #include <unistd.h>
5069200Smckusick #endif
5169200Smckusick 
5269200Smckusick #include <string.h>
5369200Smckusick #ifndef	NO_SYS_FILE
5469200Smckusick #include <sys/file.h>
5569200Smckusick #endif
5669200Smckusick #include <setjmp.h>
5769200Smckusick #include <sys/stat.h>
5869200Smckusick #include <ctype.h>
5969200Smckusick 
6069200Smckusick #ifdef SET_STACK_LIMIT_HUGE
6169200Smckusick #include <sys/time.h>
6269200Smckusick #include <sys/resource.h>
6369200Smckusick 
6469200Smckusick int original_stack_limit;
6569200Smckusick #endif
6669200Smckusick 
6769200Smckusick /* Prototypes for local functions */
6869200Smckusick 
6969200Smckusick static char *
7069200Smckusick symbol_completion_function PARAMS ((char *, int));
7169200Smckusick 
7269200Smckusick static void
7369200Smckusick command_loop PARAMS ((void));
7469200Smckusick 
7569200Smckusick static void
7669200Smckusick command_loop_marker PARAMS ((int));
7769200Smckusick 
7869200Smckusick static void
7969200Smckusick print_gdb_version PARAMS ((void));
8069200Smckusick 
8169200Smckusick static void
8269200Smckusick quit_command PARAMS ((char *, int));
8369200Smckusick 
8469200Smckusick static void
8569200Smckusick initialize_main PARAMS ((void));
8669200Smckusick 
8769200Smckusick static void
8869200Smckusick initialize_history PARAMS ((void));
8969200Smckusick 
9069200Smckusick static void
9169200Smckusick initialize_cmd_lists PARAMS ((void));
9269200Smckusick 
9369200Smckusick static void
9469200Smckusick float_handler PARAMS ((int));
9569200Smckusick 
9669200Smckusick static void
9769200Smckusick source_command PARAMS ((char *, int));
9869200Smckusick 
9969200Smckusick static void
10069200Smckusick cd_command PARAMS ((char *, int));
10169200Smckusick 
10269200Smckusick static void
10369200Smckusick print_gnu_advertisement PARAMS ((void));
10469200Smckusick 
10569200Smckusick static void
10669200Smckusick init_signals PARAMS ((void));
10769200Smckusick 
10869200Smckusick static void
10969200Smckusick read_command_file PARAMS ((FILE *));
11069200Smckusick 
11169200Smckusick static void
11269200Smckusick set_verbose PARAMS ((char *, int, struct cmd_list_element *));
11369200Smckusick 
11469200Smckusick static void
11569200Smckusick show_history PARAMS ((char *, int));
11669200Smckusick 
11769200Smckusick static void
11869200Smckusick set_history PARAMS ((char *, int));
11969200Smckusick 
12069200Smckusick static void
12169200Smckusick set_history_size_command PARAMS ((char *, int, struct cmd_list_element *));
12269200Smckusick 
12369200Smckusick static void
12469200Smckusick show_commands PARAMS ((char *, int));
12569200Smckusick 
12669200Smckusick static void
12769200Smckusick echo_command PARAMS ((char *, int));
12869200Smckusick 
12969200Smckusick static void
13069200Smckusick pwd_command PARAMS ((char *, int));
13169200Smckusick 
13269200Smckusick static void
13369200Smckusick show_version PARAMS ((char *, int));
13469200Smckusick 
13569200Smckusick static void
13669200Smckusick document_command PARAMS ((char *, int));
13769200Smckusick 
13869200Smckusick static void
13969200Smckusick define_command PARAMS ((char *, int));
14069200Smckusick 
14169200Smckusick static void
14269200Smckusick validate_comname PARAMS ((char *));
14369200Smckusick 
14469200Smckusick static void
14569200Smckusick help_command PARAMS ((char *, int));
14669200Smckusick 
14769200Smckusick static void
14869200Smckusick show_command PARAMS ((char *, int));
14969200Smckusick 
15069200Smckusick static void
15169200Smckusick info_command PARAMS ((char *, int));
15269200Smckusick 
15369200Smckusick static void
15469200Smckusick do_nothing PARAMS ((int));
15569200Smckusick 
15669200Smckusick static int
15769200Smckusick quit_cover PARAMS ((char *));
15869200Smckusick 
15969200Smckusick static void
16069200Smckusick disconnect PARAMS ((int));
16169200Smckusick 
16269200Smckusick void
16369200Smckusick source_cleanup PARAMS ((FILE *));
16469200Smckusick 
16569200Smckusick /* If this definition isn't overridden by the header files, assume
16669200Smckusick    that isatty and fileno exist on this system.  */
16769200Smckusick #ifndef ISATTY
16869200Smckusick #define ISATTY(FP)	(isatty (fileno (FP)))
16969200Smckusick #endif
17069200Smckusick 
17169200Smckusick /* Initialization file name for gdb.  This is overridden in some configs.  */
17269200Smckusick 
17369200Smckusick #ifndef	GDBINIT_FILENAME
17469200Smckusick #define	GDBINIT_FILENAME	".gdbinit"
17569200Smckusick #endif
17669200Smckusick char gdbinit[] = GDBINIT_FILENAME;
17769200Smckusick 
17869200Smckusick #define	ALL_CLEANUPS	((struct cleanup *)0)
17969200Smckusick 
18069200Smckusick /* Version number of GDB, as a string.  */
18169200Smckusick 
18269200Smckusick extern char *version;
18369200Smckusick 
18469200Smckusick /* Message to be printed before the error message, when an error occurs.  */
18569200Smckusick 
18669200Smckusick extern char *error_pre_print;
18769200Smckusick 
18869200Smckusick /* Message to be printed before the warning message, when a warning occurs.  */
18969200Smckusick 
19069200Smckusick extern char *warning_pre_print;
19169200Smckusick 
19269200Smckusick extern char lang_frame_mismatch_warn[];		/* language.c */
19369200Smckusick 
19469200Smckusick /* Whether GDB's stdin is on a terminal.  */
19569200Smckusick 
19669200Smckusick extern int gdb_has_a_terminal;			/* inflow.c */
19769200Smckusick 
19869200Smckusick /* Flag for whether we want all the "from_tty" gubbish printed.  */
19969200Smckusick 
20069200Smckusick int caution = 1;			/* Default is yes, sigh. */
20169200Smckusick 
20269200Smckusick /*
20369200Smckusick  * Define all cmd_list_element's
20469200Smckusick  */
20569200Smckusick 
20669200Smckusick /* Chain containing all defined commands.  */
20769200Smckusick 
20869200Smckusick struct cmd_list_element *cmdlist;
20969200Smckusick 
21069200Smckusick /* Chain containing all defined info subcommands.  */
21169200Smckusick 
21269200Smckusick struct cmd_list_element *infolist;
21369200Smckusick 
21469200Smckusick /* Chain containing all defined enable subcommands. */
21569200Smckusick 
21669200Smckusick struct cmd_list_element *enablelist;
21769200Smckusick 
21869200Smckusick /* Chain containing all defined disable subcommands. */
21969200Smckusick 
22069200Smckusick struct cmd_list_element *disablelist;
22169200Smckusick 
22269200Smckusick /* Chain containing all defined delete subcommands. */
22369200Smckusick 
22469200Smckusick struct cmd_list_element *deletelist;
22569200Smckusick 
22669200Smckusick /* Chain containing all defined "enable breakpoint" subcommands. */
22769200Smckusick 
22869200Smckusick struct cmd_list_element *enablebreaklist;
22969200Smckusick 
23069200Smckusick /* Chain containing all defined set subcommands */
23169200Smckusick 
23269200Smckusick struct cmd_list_element *setlist;
23369200Smckusick 
23469200Smckusick /* Chain containing all defined unset subcommands */
23569200Smckusick 
23669200Smckusick struct cmd_list_element *unsetlist;
23769200Smckusick 
23869200Smckusick /* Chain containing all defined show subcommands.  */
23969200Smckusick 
24069200Smckusick struct cmd_list_element *showlist;
24169200Smckusick 
24269200Smckusick /* Chain containing all defined \"set history\".  */
24369200Smckusick 
24469200Smckusick struct cmd_list_element *sethistlist;
24569200Smckusick 
24669200Smckusick /* Chain containing all defined \"show history\".  */
24769200Smckusick 
24869200Smckusick struct cmd_list_element *showhistlist;
24969200Smckusick 
25069200Smckusick /* Chain containing all defined \"unset history\".  */
25169200Smckusick 
25269200Smckusick struct cmd_list_element *unsethistlist;
25369200Smckusick 
25469200Smckusick /* Chain containing all defined maintenance subcommands. */
25569200Smckusick 
25669200Smckusick #if MAINTENANCE_CMDS
25769200Smckusick struct cmd_list_element *maintenancelist;
25869200Smckusick #endif
25969200Smckusick 
26069200Smckusick /* Chain containing all defined "maintenance info" subcommands. */
26169200Smckusick 
26269200Smckusick #if MAINTENANCE_CMDS
26369200Smckusick struct cmd_list_element *maintenanceinfolist;
26469200Smckusick #endif
26569200Smckusick 
26669200Smckusick /* Chain containing all defined "maintenance print" subcommands. */
26769200Smckusick 
26869200Smckusick #if MAINTENANCE_CMDS
26969200Smckusick struct cmd_list_element *maintenanceprintlist;
27069200Smckusick #endif
27169200Smckusick 
27269200Smckusick struct cmd_list_element *setprintlist;
27369200Smckusick 
27469200Smckusick struct cmd_list_element *showprintlist;
27569200Smckusick 
27669200Smckusick struct cmd_list_element *setchecklist;
27769200Smckusick 
27869200Smckusick struct cmd_list_element *showchecklist;
27969200Smckusick 
28069200Smckusick /* stdio stream that command input is being read from.  */
28169200Smckusick 
28269200Smckusick FILE *instream;
28369200Smckusick 
28469200Smckusick /* Current working directory.  */
28569200Smckusick 
28669200Smckusick char *current_directory;
28769200Smckusick 
28869200Smckusick /* The directory name is actually stored here (usually).  */
28969200Smckusick static char dirbuf[MAXPATHLEN];
29069200Smckusick 
29169200Smckusick #ifdef KERNELDEBUG
29269200Smckusick /* Nonzero if we're debugging /dev/kmem or a kernel crash dump */
29369200Smckusick int kernel_debugging;
29469200Smckusick #endif
29569200Smckusick 
29669200Smckusick /* Function to call before reading a command, if nonzero.
29769200Smckusick    The function receives two args: an input stream,
29869200Smckusick    and a prompt string.  */
29969200Smckusick 
30069200Smckusick void (*window_hook) PARAMS ((FILE *, char *));
30169200Smckusick 
30269200Smckusick extern int frame_file_full_name;
30369200Smckusick extern int mapped_symbol_files;
30469200Smckusick extern int readnow_symbol_files;
30569200Smckusick 
30669200Smckusick /* Nonzero to inhibit confirmation of quitting or restarting
30769200Smckusick    a stopped inferior. */
30869200Smckusick 
30969200Smckusick int inhibit_confirm;
31069200Smckusick 
31169200Smckusick /* The number of lines on a page */
31269200Smckusick int pagesize;
31369200Smckusick 
31469200Smckusick /* Nonzero if we should refrain from using an X window.  */
31569200Smckusick 
31669200Smckusick int inhibit_windows = 0;
31769200Smckusick 
31869200Smckusick extern int frame_file_full_name;
31969200Smckusick int epoch_interface;
32069200Smckusick int xgdb_verbose;
32169200Smckusick 
32269200Smckusick /* Buffer used for reading command lines, and the size
32369200Smckusick    allocated for it so far.  */
32469200Smckusick 
32569200Smckusick char *line;
32669200Smckusick int linesize = 100;
32769200Smckusick 
32869200Smckusick char *getenv ();
32969200Smckusick 
33069200Smckusick /* gdb prints this when reading a command interactively */
33169200Smckusick static char *masterprompt;
33269200Smckusick 
33369200Smckusick /* Baud rate specified for talking to serial target systems.  Default
33469200Smckusick    is left as a zero pointer, so targets can choose their own defaults.  */
33569200Smckusick 
33669200Smckusick char *baud_rate;
33769200Smckusick 
33869200Smckusick /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT.  */
33969200Smckusick 
34069200Smckusick #ifndef STOP_SIGNAL
34169200Smckusick #ifdef SIGTSTP
34269200Smckusick #define STOP_SIGNAL SIGTSTP
34369200Smckusick static void stop_sig PARAMS ((int));
34469200Smckusick #endif
34569200Smckusick #endif
34669200Smckusick 
34769200Smckusick /* Some System V have job control but not sigsetmask(). */
34869200Smckusick #if !defined (HAVE_SIGSETMASK)
34969200Smckusick #define HAVE_SIGSETMASK !defined (USG)
35069200Smckusick #endif
35169200Smckusick 
35269200Smckusick #if 0 == (HAVE_SIGSETMASK)
35369200Smckusick #define sigsetmask(n)
35469200Smckusick #endif
35569200Smckusick 
35669200Smckusick /* This is how `error' returns to command level.  */
35769200Smckusick 
35869200Smckusick jmp_buf to_top_level;
35969200Smckusick 
36069200Smckusick NORETURN void
return_to_top_level()36169200Smckusick return_to_top_level ()
36269200Smckusick {
36369200Smckusick   quit_flag = 0;
36469200Smckusick   immediate_quit = 0;
36569200Smckusick   bpstat_clear_actions(stop_bpstat);	/* Clear queued breakpoint commands */
36669200Smckusick   disable_current_display ();
36769200Smckusick   do_cleanups (ALL_CLEANUPS);
36869200Smckusick   (NORETURN void) longjmp (to_top_level, 1);
36969200Smckusick }
37069200Smckusick 
37169200Smckusick /* Call FUNC with arg ARGS, catching any errors.
37269200Smckusick    If there is no error, return the value returned by FUNC.
37369200Smckusick    If there is an error, print ERRSTRING, print the specific error message,
37469200Smckusick 		         then return zero.  */
37569200Smckusick 
37669200Smckusick int
37769200Smckusick catch_errors (func, args, errstring)
37869200Smckusick      int (*func) PARAMS ((char *));
37969200Smckusick      char *args;
38069200Smckusick      char *errstring;
38169200Smckusick {
38269200Smckusick   jmp_buf saved;
38369200Smckusick   int val;
38469200Smckusick   struct cleanup *saved_cleanup_chain;
38569200Smckusick   char *saved_error_pre_print;
38669200Smckusick 
38769200Smckusick   saved_cleanup_chain = save_cleanups ();
38869200Smckusick   saved_error_pre_print = error_pre_print;
38969200Smckusick 
39069200Smckusick   memcpy ((char *)saved, (char *)to_top_level, sizeof (jmp_buf));
39169200Smckusick   error_pre_print = errstring;
39269200Smckusick 
39369200Smckusick   if (setjmp (to_top_level) == 0)
39469200Smckusick     val = (*func) (args);
39569200Smckusick   else
39669200Smckusick     val = 0;
39769200Smckusick 
39869200Smckusick   restore_cleanups (saved_cleanup_chain);
39969200Smckusick 
40069200Smckusick   error_pre_print = saved_error_pre_print;
40169200Smckusick   memcpy ((char *)to_top_level, (char *)saved, sizeof (jmp_buf));
40269200Smckusick   return val;
40369200Smckusick }
40469200Smckusick 
40569200Smckusick /* Handler for SIGHUP.  */
40669200Smckusick 
40769200Smckusick static void
disconnect(signo)40869200Smckusick disconnect (signo)
40969200Smckusick int signo;
41069200Smckusick {
41169200Smckusick   catch_errors (quit_cover, NULL, "Could not kill inferior process");
41269200Smckusick   signal (SIGHUP, SIG_DFL);
41369200Smckusick   kill (getpid (), SIGHUP);
41469200Smckusick }
41569200Smckusick 
41669200Smckusick /* Just a little helper function for disconnect().  */
41769200Smckusick 
41869200Smckusick static int
quit_cover(s)41969200Smckusick quit_cover (s)
42069200Smckusick char *s;
42169200Smckusick {
42269200Smckusick   caution = 0;		/* Throw caution to the wind -- we're exiting.
42369200Smckusick 			   This prevents asking the user dumb questions.  */
42469200Smckusick   quit_command((char *)0, 0);
42569200Smckusick   return 0;
42669200Smckusick }
42769200Smckusick 
42869200Smckusick /*
42969200Smckusick  * Source an init file if it exists.
43069200Smckusick  */
43169200Smckusick void
sourcefile(file)43269200Smckusick sourcefile(file)
43369200Smckusick 	char *file;
43469200Smckusick {
43569200Smckusick 	if (access (file, R_OK) == 0)
43669200Smckusick 		if (!setjmp (to_top_level))
43769200Smckusick 			source_command (file, 0);
43869200Smckusick 	do_cleanups(ALL_CLEANUPS);
43969200Smckusick }
44069200Smckusick 
44169200Smckusick /*
44269200Smckusick  * Source $HOME/.gdbinit and $cwd/.gdbinit.
44369200Smckusick  * If X is enabled, also $HOME/.xgdbinit and $cwd/.xgdbinit.source
44469200Smckusick  */
44569200Smckusick void
source_init_files()44669200Smckusick source_init_files()
44769200Smckusick {
44869200Smckusick 	char *homedir, initfile[256];
44969200Smckusick 	int samedir = 0;
45069200Smckusick 
45169200Smckusick 	/* Read init file, if it exists in home directory  */
45269200Smckusick 	homedir = getenv ("HOME");
45369200Smckusick 	if (homedir) {
45469200Smckusick 		struct stat homebuf, cwdbuf;
45569200Smckusick 
45669200Smckusick 		sprintf(initfile, "%s/%s", homedir, gdbinit);
45769200Smckusick 		sourcefile(initfile);
45869200Smckusick 		if (!inhibit_windows) {
45969200Smckusick 			sprintf(initfile, "%s/.xgdbinit", homedir);
46069200Smckusick 			sourcefile(initfile);
46169200Smckusick 		}
46269200Smckusick #ifdef KERNELDEBUG
46369200Smckusick 		if (kernel_debugging) {
46469200Smckusick 			sprintf(initfile, "%s/.kgdbinit", homedir);
46569200Smckusick 			sourcefile(initfile);
46669200Smckusick 		}
46769200Smckusick #endif
46869200Smckusick 		/* Determine if current directory is the same as the home
46969200Smckusick 		   directory, so we don't source the same file twice. */
47069200Smckusick 
47169200Smckusick 		bzero (&homebuf, sizeof (struct stat));
47269200Smckusick 		bzero (&cwdbuf, sizeof (struct stat));
47369200Smckusick 
47469200Smckusick 		stat(homedir, &homebuf);
47569200Smckusick 		stat(".", &cwdbuf);
47669200Smckusick 
47769200Smckusick 		samedir = bcmp(&homebuf, &cwdbuf, sizeof(struct stat)) == 0;
47869200Smckusick 	}
47969200Smckusick 	/* Read the input file in the current directory, *if* it isn't
48069200Smckusick 	   the same file (it should exist, also).  */
48169200Smckusick 	if (!samedir) {
48269200Smckusick 		sourcefile(gdbinit);
48369200Smckusick 		sourcefile(".xgdbinit");
48469200Smckusick #ifdef KERNELDEBUG
48569200Smckusick 		if (kernel_debugging)
48669200Smckusick 			sourcefile(".kgdbinit");
48769200Smckusick #endif
48869200Smckusick 	}
48969200Smckusick }
49069200Smckusick 
49169200Smckusick /* Clean up on error during a "source" command (or execution of a
49269200Smckusick    user-defined command).  */
49369200Smckusick 
49469200Smckusick void
source_cleanup(stream)49569200Smckusick source_cleanup (stream)
49669200Smckusick      FILE *stream;
49769200Smckusick {
49869200Smckusick   /* Restore the previous input stream.  */
49969200Smckusick   instream = stream;
50069200Smckusick }
50169200Smckusick 
50269200Smckusick /* Read commands from STREAM.  */
50369200Smckusick static void
read_command_file(stream)50469200Smckusick read_command_file (stream)
50569200Smckusick      FILE *stream;
50669200Smckusick {
50769200Smckusick   struct cleanup *cleanups;
50869200Smckusick 
50969200Smckusick   cleanups = make_cleanup (source_cleanup, instream);
51069200Smckusick   instream = stream;
51169200Smckusick   command_loop ();
51269200Smckusick   do_cleanups (cleanups);
51369200Smckusick }
51469200Smckusick 
51569200Smckusick /*
51669200Smckusick  * Process the core file argument.
51769200Smckusick  * We infer (lexically) from the name and (semantically) from the
51869200Smckusick  * corresponding file type what the target is.  It's one of a live
51969200Smckusick  * user process (pid), a user process core dump (core), a kernel
52069200Smckusick  * crash dump (vmcore), a live kernel (/dev/mem), a remote kernel (/dev/ttya)
52169200Smckusick  * or a remote internet host (@127.0.0.1).
52269200Smckusick  */
52369200Smckusick void
do_core_arg(corefile,batch)52469200Smckusick do_core_arg(corefile, batch)
52569200Smckusick 	char *corefile;
52669200Smckusick 	int batch;
52769200Smckusick {
52869200Smckusick 	struct stat stb;
52969200Smckusick 
53069200Smckusick 	if (setjmp(to_top_level))
53169200Smckusick 		return;
53269200Smckusick 
53369200Smckusick 	if (corefile[0] == '@')
53469200Smckusick 		/* Internet host -- we're remote debugging. */
53569200Smckusick 		remote_open(corefile, 0);
53669200Smckusick 	else if (stat(corefile, &stb) == 0) {
53769200Smckusick #ifdef KERNELDEBUG
53869200Smckusick 		if (S_ISCHR(stb.st_mode)) {
53969200Smckusick 			/*
54069200Smckusick 			 * character device -- either we're debugging a live
54169200Smckusick 			 * kernel (/dev/mem, /dev/kmem) or a remote kernel
54269200Smckusick 			 * over a serial link.  Use the heuristic that
54369200Smckusick 			 * /dev/mem has a "small" major device number.
54469200Smckusick 			 */
54569200Smckusick 			if (major(stb.st_rdev) <= 4)
54669200Smckusick 				/* kernel memory */
54769200Smckusick 				kernel_core_open(corefile, !batch);
54869200Smckusick 			else
54969200Smckusick 				remote_open(corefile, !batch);
55069200Smckusick 		} else if (kernel_debugging)
55169200Smckusick 			/* a kernel crash dump */
55269200Smckusick 			kernel_core_open(corefile, !batch);
55369200Smckusick 		else
55469200Smckusick #endif
55569200Smckusick 			core_file_command(corefile, !batch);
55669200Smckusick 	} else if (isdigit(corefile[0]))
55769200Smckusick 		attach_command(corefile, !batch);
55869200Smckusick 	else
55969200Smckusick 		/*
56069200Smckusick 		 * stat() failed and arg isn't a pid
56169200Smckusick 		 */
56269200Smckusick 		perror(corefile);
56369200Smckusick }
56469200Smckusick 
56569200Smckusick int
main(argc,argv)56669200Smckusick main (argc, argv)
56769200Smckusick      int argc;
56869200Smckusick      char **argv;
56969200Smckusick {
57069200Smckusick   int count;
57169200Smckusick   static int inhibit_gdbinit = 0;
572*69201Smckusick   static int quiet = 0;
57369200Smckusick   static int batch = 0;
57469200Smckusick 
57569200Smckusick   /* Pointers to various arguments from command line.  */
57669200Smckusick   char *symarg = NULL;
57769200Smckusick   char *execarg = NULL;
57869200Smckusick   char *corearg = NULL;
57969200Smckusick   char *cdarg = NULL;
58069200Smckusick   char *ttyarg = NULL;
58169200Smckusick   char *cp;
58269200Smckusick 
58369200Smckusick   /* Pointers to all arguments of +command option.  */
58469200Smckusick   char **cmdarg;
58569200Smckusick   /* Allocated size of cmdarg.  */
58669200Smckusick   int cmdsize;
58769200Smckusick   /* Number of elements of cmdarg used.  */
58869200Smckusick   int ncmd;
58969200Smckusick 
59069200Smckusick   /* Indices of all arguments of +directory option.  */
59169200Smckusick   char **dirarg;
59269200Smckusick   /* Allocated size.  */
59369200Smckusick   int dirsize;
59469200Smckusick   /* Number of elements used.  */
59569200Smckusick   int ndir;
59669200Smckusick 
59769200Smckusick   register int i;
59869200Smckusick 
59969200Smckusick   /* XXX Windows only for xgdb. */
60069200Smckusick   char *strrchr();
60169200Smckusick   if (cp = strrchr(argv[0], '/'))
60269200Smckusick 	  ++cp;
60369200Smckusick   else
60469200Smckusick 	  cp = argv[0];
60569200Smckusick   if (*cp != 'x')
60669200Smckusick 	  inhibit_windows = 1;
60769200Smckusick 
60869200Smckusick   /* This needs to happen before the first use of malloc.  */
60969200Smckusick   init_malloc ((PTR) NULL);
61069200Smckusick 
61169200Smckusick #if defined (ALIGN_STACK_ON_STARTUP)
61269200Smckusick   i = (int) &count & 0x3;
61369200Smckusick   if (i != 0)
61469200Smckusick     alloca (4 - i);
61569200Smckusick #endif
61669200Smckusick 
61769200Smckusick   /* If error() is called from initialization code, just exit */
61869200Smckusick   if (setjmp (to_top_level)) {
61969200Smckusick     exit(1);
62069200Smckusick   }
62169200Smckusick 
62269200Smckusick   cmdsize = 1;
62369200Smckusick   cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg));
62469200Smckusick   ncmd = 0;
62569200Smckusick   dirsize = 1;
62669200Smckusick   dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
62769200Smckusick   ndir = 0;
62869200Smckusick 
62969200Smckusick   quit_flag = 0;
63069200Smckusick   instream = stdin;
63169200Smckusick 
63269200Smckusick   getcwd (dirbuf, sizeof (dirbuf));
63369200Smckusick   current_directory = dirbuf;
63469200Smckusick 
63569200Smckusick #ifdef SET_STACK_LIMIT_HUGE
63669200Smckusick   {
63769200Smckusick     struct rlimit rlim;
63869200Smckusick 
63969200Smckusick     /* Set the stack limit huge so that alloca (particularly stringtab
64069200Smckusick      * in dbxread.c) does not fail. */
64169200Smckusick     getrlimit (RLIMIT_STACK, &rlim);
64269200Smckusick     original_stack_limit = rlim.rlim_cur;
64369200Smckusick     rlim.rlim_cur = rlim.rlim_max;
64469200Smckusick     setrlimit (RLIMIT_STACK, &rlim);
64569200Smckusick   }
64669200Smckusick #endif /* SET_STACK_LIMIT_HUGE */
64769200Smckusick 
64869200Smckusick   /* Parse arguments and options.  */
64969200Smckusick   {
65069200Smckusick     int c;
65169200Smckusick     static int print_help;
65269200Smckusick     /* When var field is 0, use flag field to record the equivalent
65369200Smckusick        short option (or arbitrary numbers starting at 10 for those
65469200Smckusick        with no equivalent).  */
65569200Smckusick     static struct option long_options[] =
65669200Smckusick       {
65769200Smckusick 	{"readnow", no_argument, &readnow_symbol_files, 1},
65869200Smckusick 	{"r", no_argument, &readnow_symbol_files, 1},
65969200Smckusick 	{"mapped", no_argument, &mapped_symbol_files, 1},
66069200Smckusick 	{"m", no_argument, &mapped_symbol_files, 1},
66169200Smckusick 	{"quiet", no_argument, &quiet, 1},
66269200Smckusick 	{"q", no_argument, &quiet, 1},
66369200Smckusick 	{"version", no_argument, &quiet, 0},
66469200Smckusick 	{"nc", no_argument, &inhibit_confirm, 1},
66569200Smckusick 	{"nx", no_argument, &inhibit_gdbinit, 1},
66669200Smckusick 	{"nw", no_argument, &inhibit_windows, 1},
66769200Smckusick 	{"n", no_argument, &inhibit_gdbinit, 1},
66869200Smckusick 	{"batch", no_argument, &batch, 1},
66969200Smckusick 	{"epoch", no_argument, &epoch_interface, 1},
67069200Smckusick 	{"fullname", no_argument, &frame_file_full_name, 1},
67169200Smckusick 	{"f", no_argument, &frame_file_full_name, 1},
67269200Smckusick 	{"help", no_argument, &print_help, 1},
67369200Smckusick 	{"se", required_argument, 0, 10},
67469200Smckusick 	{"symbols", required_argument, 0, 's'},
67569200Smckusick 	{"s", required_argument, 0, 's'},
67669200Smckusick 	{"exec", required_argument, 0, 'e'},
67769200Smckusick 	{"e", required_argument, 0, 'e'},
67869200Smckusick 	{"core", required_argument, 0, 'c'},
67969200Smckusick 	{"c", required_argument, 0, 'c'},
68069200Smckusick 	{"command", required_argument, 0, 'x'},
68169200Smckusick 	{"x", required_argument, 0, 'x'},
68269200Smckusick 	{"directory", required_argument, 0, 'd'},
68369200Smckusick 	{"cd", required_argument, 0, 11},
68469200Smckusick 	{"tty", required_argument, 0, 't'},
68569200Smckusick 	{"baud", required_argument, 0, 'b'},
68669200Smckusick 	{"b", required_argument, 0, 'b'},
68769200Smckusick 	{"w", no_argument, &write_files, 1},
68869200Smckusick #ifdef KERNELDEBUG
68969200Smckusick 	{"k", no_argument, &kernel_debugging, 1},
69069200Smckusick #endif
69169200Smckusick /* Allow machine descriptions to add more options... */
69269200Smckusick #ifdef ADDITIONAL_OPTIONS
69369200Smckusick 	ADDITIONAL_OPTIONS
69469200Smckusick #endif
69569200Smckusick 	{0, no_argument, 0, 0},
69669200Smckusick       };
69769200Smckusick 
69869200Smckusick     while (1)
69969200Smckusick       {
70069200Smckusick 	int option_index;
70169200Smckusick 
70269200Smckusick 	c = getopt_long_only (argc, argv, "",
70369200Smckusick 			      long_options, &option_index);
70469200Smckusick 	if (c == EOF)
70569200Smckusick 	  break;
70669200Smckusick 
70769200Smckusick 	/* Long option that takes an argument.  */
70869200Smckusick 	if (c == 0 && long_options[option_index].flag == 0)
70969200Smckusick 	  c = long_options[option_index].val;
71069200Smckusick 
71169200Smckusick 	switch (c)
71269200Smckusick 	  {
71369200Smckusick 	  case 0:
71469200Smckusick 	    /* Long option that just sets a flag.  */
71569200Smckusick 	    break;
71669200Smckusick 	  case 10:
71769200Smckusick 	    symarg = optarg;
71869200Smckusick 	    execarg = optarg;
71969200Smckusick 	    break;
72069200Smckusick 	  case 11:
72169200Smckusick 	    cdarg = optarg;
72269200Smckusick 	    break;
72369200Smckusick 	  case 's':
72469200Smckusick 	    symarg = optarg;
72569200Smckusick 	    break;
72669200Smckusick 	  case 'e':
72769200Smckusick 	    execarg = optarg;
72869200Smckusick 	    break;
72969200Smckusick 	  case 'c':
73069200Smckusick 	    corearg = optarg;
73169200Smckusick 	    break;
73269200Smckusick 	  case 'x':
73369200Smckusick 	    cmdarg[ncmd++] = optarg;
73469200Smckusick 	    if (ncmd >= cmdsize)
73569200Smckusick 	      {
73669200Smckusick 		cmdsize *= 2;
73769200Smckusick 		cmdarg = (char **) xrealloc ((char *)cmdarg,
73869200Smckusick 					     cmdsize * sizeof (*cmdarg));
73969200Smckusick 	      }
74069200Smckusick 	    break;
74169200Smckusick 	  case 'd':
74269200Smckusick 	    dirarg[ndir++] = optarg;
74369200Smckusick 	    if (ndir >= dirsize)
74469200Smckusick 	      {
74569200Smckusick 		dirsize *= 2;
74669200Smckusick 		dirarg = (char **) xrealloc ((char *)dirarg,
74769200Smckusick 					     dirsize * sizeof (*dirarg));
74869200Smckusick 	      }
74969200Smckusick 	    break;
75069200Smckusick 	  case 't':
75169200Smckusick 	    ttyarg = optarg;
75269200Smckusick 	    break;
75369200Smckusick 	  case 'q':
75469200Smckusick 	    quiet = 1;
75569200Smckusick 	    break;
75669200Smckusick 	  case 'b':
75769200Smckusick 	    baud_rate = optarg;
75869200Smckusick 	    break;
75969200Smckusick #ifdef ADDITIONAL_OPTION_CASES
76069200Smckusick 	  ADDITIONAL_OPTION_CASES
76169200Smckusick #endif
76269200Smckusick 	  case '?':
76369200Smckusick 	    fprintf (stderr,
76469200Smckusick 		     "Use `%s +help' for a complete list of options.\n",
76569200Smckusick 		     argv[0]);
76669200Smckusick 	    exit (1);
76769200Smckusick 	  }
76869200Smckusick 
76969200Smckusick       }
77069200Smckusick     if (print_help)
77169200Smckusick       {
77269200Smckusick 	fputs ("\
77369200Smckusick This is GDB, the GNU debugger.  Use the command\n\
77469200Smckusick     gdb [options] [executable [core-file]]\n\
77569200Smckusick to enter the debugger.\n\
77669200Smckusick \n\
77769200Smckusick Options available are:\n\
77869200Smckusick   -help             Print this message.\n\
77969200Smckusick   -quiet            Do not print version number on startup.\n\
78069200Smckusick   -fullname         Output information used by emacs-GDB interface.\n\
78169200Smckusick   -epoch            Output information used by epoch emacs-GDB interface.\n\
78269200Smckusick   -batch            Exit after processing options.\n\
78369200Smckusick   -nx               Do not read .gdbinit file.\n\
78469200Smckusick   -tty=TTY          Use TTY for input/output by the program being debugged.\n\
78569200Smckusick   -cd=DIR           Change current directory to DIR.\n\
78669200Smckusick   -directory=DIR    Search for source files in DIR.\n\
78769200Smckusick   -command=FILE     Execute GDB commands from FILE.\n\
78869200Smckusick   -symbols=SYMFILE  Read symbols from SYMFILE.\n\
78969200Smckusick   -exec=EXECFILE    Use EXECFILE as the executable.\n\
79069200Smckusick   -se=FILE          Use FILE as symbol file and executable file.\n\
79169200Smckusick   -core=COREFILE    Analyze the core dump COREFILE.\n\
79269200Smckusick   -b BAUDRATE       Set serial port baud rate used for remote debugging.\n\
79369200Smckusick   -mapped           Use mapped symbol files if supported on this system.\n\
79469200Smckusick   -readnow          Fully read symbol files on first access.\n\
79569200Smckusick   -k                Kernel debugging.\n\
79669200Smckusick   -w                Writeable text.\n\
79769200Smckusick   -version          Print GNU message and version number on startup.\n\
79869200Smckusick   -nc               Don't confirm quit or run commands.\n\
79969200Smckusick ", stderr);
80069200Smckusick #ifdef ADDITIONAL_OPTION_HELP
80169200Smckusick 	fputs (ADDITIONAL_OPTION_HELP, stderr);
80269200Smckusick #endif
80369200Smckusick 	fputs ("\n\
80469200Smckusick For more information, type \"help\" from within GDB, or consult the\n\
80569200Smckusick GDB manual (available as on-line info or a printed manual).\n", stderr);
80669200Smckusick 	/* Exiting after printing this message seems like
80769200Smckusick 	   the most useful thing to do.  */
80869200Smckusick 	exit (0);
80969200Smckusick       }
81069200Smckusick 
81169200Smckusick     /* OK, that's all the options.  The other arguments are filenames.  */
81269200Smckusick     count = 0;
81369200Smckusick     for (; optind < argc; optind++)
81469200Smckusick       switch (++count)
81569200Smckusick 	{
81669200Smckusick 	case 1:
81769200Smckusick 	  symarg = argv[optind];
81869200Smckusick 	  execarg = argv[optind];
81969200Smckusick 	  break;
82069200Smckusick 	case 2:
82169200Smckusick 	  corearg = argv[optind];
82269200Smckusick 	  break;
82369200Smckusick 	case 3:
82469200Smckusick 	  fprintf (stderr,
82569200Smckusick 		   "Excess command line arguments ignored. (%s%s)\n",
82669200Smckusick 		   argv[optind], (optind == argc - 1) ? "" : " ...");
82769200Smckusick 	  break;
82869200Smckusick 	}
82969200Smckusick     if (batch)
83069200Smckusick       quiet = 1;
83169200Smckusick   }
83269200Smckusick 
83369200Smckusick   /* Run the init function of each source file */
83469200Smckusick 
83569200Smckusick   initialize_cmd_lists ();	/* This needs to be done first */
83669200Smckusick   initialize_all_files ();
83769200Smckusick   initialize_main ();		/* But that omits this file!  Do it now */
83869200Smckusick   init_signals ();
83969200Smckusick 
84069200Smckusick   if (!quiet)
84169200Smckusick     {
84269200Smckusick       /* Print all the junk at the top, with trailing "..." if we are about
84369200Smckusick 	 to read a symbol file (possibly slowly).  */
84469200Smckusick       print_gnu_advertisement ();
84569200Smckusick       print_gdb_version ();
84669200Smckusick       if (symarg)
84769200Smckusick 	printf_filtered ("..");
84869200Smckusick       wrap_here("");
84969200Smckusick       fflush (stdout);		/* Force to screen during slow operations */
85069200Smckusick     }
85169200Smckusick 
85269200Smckusick   error_pre_print = "\n\n";
85369200Smckusick   /* We may get more than one warning, don't double space all of them... */
85469200Smckusick   warning_pre_print = "\nwarning: ";
85569200Smckusick 
85669200Smckusick   /* We need a default language for parsing expressions, so simple things like
85769200Smckusick      "set width 0" won't fail if no language is explicitly set in a config file
85869200Smckusick      or implicitly set by reading an executable during startup. */
85969200Smckusick   set_language (language_c);
86069200Smckusick   expected_language = current_language;	/* don't warn about the change.  */
86169200Smckusick 
86269200Smckusick   /* Now perform all the actions indicated by the arguments.  */
86369200Smckusick   if (cdarg != NULL)
86469200Smckusick     {
86569200Smckusick       if (!setjmp (to_top_level))
86669200Smckusick 	{
86769200Smckusick 	  cd_command (cdarg, 0);
86869200Smckusick 	  init_source_path ();
86969200Smckusick 	}
87069200Smckusick     }
87169200Smckusick   do_cleanups (ALL_CLEANUPS);
87269200Smckusick 
87369200Smckusick   for (i = 0; i < ndir; i++)
87469200Smckusick     if (!setjmp (to_top_level))
87569200Smckusick       directory_command (dirarg[i], 0);
87669200Smckusick   free ((PTR)dirarg);
87769200Smckusick   do_cleanups (ALL_CLEANUPS);
87869200Smckusick 
87969200Smckusick   if (execarg != NULL
88069200Smckusick       && symarg != NULL
88169200Smckusick       && strcmp (execarg, symarg) == 0)
88269200Smckusick     {
88369200Smckusick       /* The exec file and the symbol-file are the same.  If we can't open
88469200Smckusick 	 it, better only print one error message.  */
88569200Smckusick       if (!setjmp (to_top_level))
88669200Smckusick 	{
88769200Smckusick 	  exec_file_command (execarg, !batch);
88869200Smckusick 	  symbol_file_command (symarg, 0);
88969200Smckusick 	}
89069200Smckusick     }
89169200Smckusick   else
89269200Smckusick     {
89369200Smckusick       if (execarg != NULL)
89469200Smckusick 	if (!setjmp (to_top_level))
89569200Smckusick 	  exec_file_command (execarg, !batch);
89669200Smckusick       if (symarg != NULL)
89769200Smckusick 	if (!setjmp (to_top_level))
89869200Smckusick 	  symbol_file_command (symarg, 0);
89969200Smckusick     }
90069200Smckusick   do_cleanups (ALL_CLEANUPS);
90169200Smckusick 
90269200Smckusick   /* After the symbol file has been read, print a newline to get us
90369200Smckusick      beyond the copyright line...  But errors should still set off
90469200Smckusick      the error message with a (single) blank line.  */
90569200Smckusick   if (!quiet)
90669200Smckusick     printf_filtered ("\n");
90769200Smckusick   error_pre_print = "\n";
90869200Smckusick   warning_pre_print = "\nwarning: ";
90969200Smckusick 
91069200Smckusick   if (corearg != NULL)
91169200Smckusick     do_core_arg(corearg, batch);
91269200Smckusick   do_cleanups (ALL_CLEANUPS);
91369200Smckusick 
91469200Smckusick   if (ttyarg != NULL)
91569200Smckusick     if (!setjmp (to_top_level))
91669200Smckusick       tty_command (ttyarg, !batch);
91769200Smckusick   do_cleanups (ALL_CLEANUPS);
91869200Smckusick 
91969200Smckusick #ifdef ADDITIONAL_OPTION_HANDLER
92069200Smckusick   ADDITIONAL_OPTION_HANDLER;
92169200Smckusick #endif
92269200Smckusick 
92369200Smckusick   /* Error messages should no longer be distinguished with extra output. */
92469200Smckusick   error_pre_print = 0;
92569200Smckusick   warning_pre_print = "warning: ";
92669200Smckusick 
92769200Smckusick   if (!inhibit_gdbinit)
92869200Smckusick     source_init_files();
92969200Smckusick 
93069200Smckusick   for (i = 0; i < ncmd; i++)
93169200Smckusick     {
93269200Smckusick       if (!setjmp (to_top_level))
93369200Smckusick 	{
93469200Smckusick 	  if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
93569200Smckusick 	    read_command_file (stdin);
93669200Smckusick 	  else
93769200Smckusick 	    source_command (cmdarg[i], !batch);
93869200Smckusick 	  do_cleanups (ALL_CLEANUPS);
93969200Smckusick 	}
94069200Smckusick     }
94169200Smckusick   free ((PTR)cmdarg);
94269200Smckusick 
94369200Smckusick   /* Read in the old history after all the command files have been read. */
94469200Smckusick   initialize_history();
94569200Smckusick 
94669200Smckusick   if (batch)
94769200Smckusick     {
94869200Smckusick       /* We have hit the end of the batch file.  */
94969200Smckusick       exit (0);
95069200Smckusick     }
95169200Smckusick 
95269200Smckusick   /* Do any host- or target-specific hacks.  This is used for i960 targets
95369200Smckusick      to force the user to set a nindy target and spec its parameters.  */
95469200Smckusick 
95569200Smckusick #ifdef BEFORE_MAIN_LOOP_HOOK
95669200Smckusick   BEFORE_MAIN_LOOP_HOOK;
95769200Smckusick #endif
95869200Smckusick 
95969200Smckusick   /* The command loop.  */
96069200Smckusick 
96169200Smckusick   while (1)
96269200Smckusick     {
96369200Smckusick       if (!setjmp (to_top_level))
96469200Smckusick 	{
96569200Smckusick 	  do_cleanups (ALL_CLEANUPS);		/* Do complete cleanup */
96669200Smckusick 	  command_loop ();
96769200Smckusick           quit_command ((char *)0, instream == stdin);
96869200Smckusick 	}
96969200Smckusick     }
97069200Smckusick   /* No exit -- exit is through quit_command.  */
97169200Smckusick }
97269200Smckusick 
97369200Smckusick void
execute_user_command(c,args)97469200Smckusick execute_user_command (c, args)
97569200Smckusick      struct cmd_list_element *c;
97669200Smckusick      char *args;
97769200Smckusick {
97869200Smckusick   register struct command_line *cmdlines;
97969200Smckusick   struct cleanup *old_chain;
98069200Smckusick 
98169200Smckusick   if (args)
98269200Smckusick     error ("User-defined commands cannot take arguments.");
98369200Smckusick 
98469200Smckusick   cmdlines = c->user_commands;
98569200Smckusick   if (cmdlines == 0)
98669200Smckusick     /* Null command */
98769200Smckusick     return;
98869200Smckusick 
98969200Smckusick   /* Set the instream to 0, indicating execution of a
99069200Smckusick      user-defined function.  */
99169200Smckusick   old_chain = make_cleanup (source_cleanup, instream);
99269200Smckusick   instream = (FILE *) 0;
99369200Smckusick   while (cmdlines)
99469200Smckusick     {
99569200Smckusick       execute_command (cmdlines->line, 0);
99669200Smckusick       cmdlines = cmdlines->next;
99769200Smckusick     }
99869200Smckusick   do_cleanups (old_chain);
99969200Smckusick }
100069200Smckusick 
100169200Smckusick /* ARGSUSED */
100269200Smckusick static void
command_loop_marker(foo)100369200Smckusick command_loop_marker (foo)
100469200Smckusick      int foo;
100569200Smckusick {
100669200Smckusick }
100769200Smckusick 
100869200Smckusick /* Read commands from `instream' and execute them
100969200Smckusick    until end of file or error reading instream.  */
101069200Smckusick static void
command_loop()101169200Smckusick command_loop ()
101269200Smckusick {
101369200Smckusick   struct cleanup *old_chain;
101469200Smckusick   register int toplevel = (instream == stdin);
101569200Smckusick   register int interactive = (toplevel && ISATTY(stdin));
101669200Smckusick 
101769200Smckusick   while (!feof(instream))
101869200Smckusick     {
101969200Smckusick       register char *cmd_line;
102069200Smckusick 
102169200Smckusick       quit_flag = 0;
102269200Smckusick       if (interactive)
102369200Smckusick 	reinitialize_more_filter ();
102469200Smckusick       old_chain = make_cleanup (command_loop_marker, 0);
102569200Smckusick       cmd_line = command_line_input (toplevel ? masterprompt : 0, toplevel);
102669200Smckusick       if (cmd_line == 0)
102769200Smckusick         {
102869200Smckusick 	  do_cleanups (old_chain);
102969200Smckusick 	  return;
103069200Smckusick         }
103169200Smckusick       execute_command (cmd_line, toplevel);
103269200Smckusick       /* Do any commands attached to breakpoint we stopped at.  */
103369200Smckusick       bpstat_do_actions (&stop_bpstat);
103469200Smckusick       do_cleanups (old_chain);
103569200Smckusick     }
103669200Smckusick }
103769200Smckusick 
103869200Smckusick /* Read a line from the stream "instream" without command line editing.
103969200Smckusick 
104069200Smckusick    It prints PROMPT once at the start.
104169200Smckusick    Action is compatible with "readline", e.g. space for the result is
104269200Smckusick    malloc'd and should be freed by the caller.
104369200Smckusick 
104469200Smckusick    A NULL return means end of file.  */
104569200Smckusick char *
gdb_readline(prompt)104669200Smckusick gdb_readline (prompt)
104769200Smckusick      char *prompt;
104869200Smckusick {
104969200Smckusick   int c;
105069200Smckusick   char *result;
105169200Smckusick   int input_index = 0;
105269200Smckusick   int result_size = 80;
105369200Smckusick 
105469200Smckusick   if (prompt)
105569200Smckusick     {
105669200Smckusick       /* Don't use a _filtered function here.  It causes the assumed
105769200Smckusick 	 character position to be off, since the newline we read from
105869200Smckusick 	 the user is not accounted for.  */
105969200Smckusick       fputs (prompt, stdout);
106069200Smckusick       fflush (stdout);
106169200Smckusick     }
106269200Smckusick 
106369200Smckusick   result = (char *) xmalloc (result_size);
106469200Smckusick 
106569200Smckusick   while (1)
106669200Smckusick     {
106769200Smckusick       /* Read from stdin if we are executing a user defined command.
106869200Smckusick 	 This is the right thing for prompt_for_continue, at least.  */
106969200Smckusick       c = fgetc (instream ? instream : stdin);
107069200Smckusick 
107169200Smckusick       if (c == EOF)
107269200Smckusick 	{
107369200Smckusick 	  free (result);
107469200Smckusick 	  return NULL;
107569200Smckusick 	}
107669200Smckusick 
107769200Smckusick       if (c == '\n')
107869200Smckusick 	break;
107969200Smckusick 
108069200Smckusick       result[input_index++] = c;
108169200Smckusick       while (input_index >= result_size)
108269200Smckusick 	{
108369200Smckusick 	  result_size *= 2;
108469200Smckusick 	  result = (char *) xrealloc (result, result_size);
108569200Smckusick 	}
108669200Smckusick     }
108769200Smckusick 
108869200Smckusick   result[input_index++] = '\0';
108969200Smckusick   return result;
109069200Smckusick }
109169200Smckusick 
109269200Smckusick /* Variables which control command line editing and history
109369200Smckusick    substitution.  These variables are given default values at the end
109469200Smckusick    of this file.  */
109569200Smckusick static int write_history_p;
109669200Smckusick static unsigned int history_size;
109769200Smckusick static char *history_filename;
109869200Smckusick 
109969200Smckusick /* Variables which are necessary for fancy command line editing.  */
110069200Smckusick char *gdb_completer_word_break_characters =
110169200Smckusick   " \t\n!@#$%^&*()+=|~`}{[]\"';?/>.<,-";
110269200Smckusick 
110369200Smckusick /* When completing on command names, we remove '-' from the list of
110469200Smckusick    word break characters, since we use it in command names.  If the
110569200Smckusick    readline library sees one in any of the current completion strings,
110669200Smckusick    it thinks that the string needs to be quoted and automatically supplies
110769200Smckusick    a leading quote. */
110869200Smckusick char *gdb_completer_command_word_break_characters =
110969200Smckusick   " \t\n!@#$%^&*()+=|~`}{[]\"';?/>.<,";
111069200Smckusick 
111169200Smckusick /* Characters that can be used to quote completion strings.  Note that we
111269200Smckusick    can't include '"' because the gdb C parser treats such quoted sequences
111369200Smckusick    as strings. */
111469200Smckusick char *gdb_completer_quote_characters =
111569200Smckusick   "'";
111669200Smckusick 
111769200Smckusick /* Functions that are used as part of the fancy command line editing.  */
111869200Smckusick 
111969200Smckusick /* This can be used for functions which don't want to complete on symbols
112069200Smckusick    but don't want to complete on anything else either.  */
112169200Smckusick /* ARGSUSED */
112269200Smckusick char **
noop_completer(text)112369200Smckusick noop_completer (text)
112469200Smckusick      char *text;
112569200Smckusick {
112669200Smckusick   return NULL;
112769200Smckusick }
112869200Smckusick 
112969200Smckusick /* Generate symbol names one by one for the completer.  Each time we are
113069200Smckusick    called return another potential completion to the caller.
113169200Smckusick 
113269200Smckusick    TEXT is what we expect the symbol to start with.
113369200Smckusick 
113469200Smckusick    MATCHES is the number of matches that have currently been collected from
113569200Smckusick    calling this completion function.  When zero, then we need to initialize,
113669200Smckusick    otherwise the initialization has already taken place and we can just
113769200Smckusick    return the next potential completion string.
113869200Smckusick 
113969200Smckusick    Returns NULL if there are no more completions, else a pointer to a string
114069200Smckusick    which is a possible completion.
114169200Smckusick 
114269200Smckusick    RL_LINE_BUFFER is available to be looked at; it contains the entire text
114369200Smckusick    of the line.  RL_POINT is the offset in that line of the cursor.  You
114469200Smckusick    should pretend that the line ends at RL_POINT. */
114569200Smckusick 
114669200Smckusick static char *
symbol_completion_function(text,matches)114769200Smckusick symbol_completion_function (text, matches)
114869200Smckusick      char *text;
114969200Smckusick      int matches;
115069200Smckusick {
115169200Smckusick   static char **list = (char **)NULL;		/* Cache of completions */
115269200Smckusick   static int index;				/* Next cached completion */
115369200Smckusick   char *output = NULL;
115469200Smckusick   char *tmp_command, *p;
115569200Smckusick   struct cmd_list_element *c, *result_list;
115669200Smckusick   extern char *rl_line_buffer;
115769200Smckusick   extern int rl_point;
115869200Smckusick 
115969200Smckusick   if (matches == 0)
116069200Smckusick     {
116169200Smckusick       /* The caller is beginning to accumulate a new set of completions, so
116269200Smckusick 	 we need to find all of them now, and cache them for returning one at
116369200Smckusick 	 a time on future calls. */
116469200Smckusick 
116569200Smckusick       if (list)
116669200Smckusick 	{
116769200Smckusick 	  /* Free the storage used by LIST, but not by the strings inside.
116869200Smckusick 	     This is because rl_complete_internal () frees the strings. */
116969200Smckusick 	  free ((PTR)list);
117069200Smckusick 	}
117169200Smckusick       list = 0;
117269200Smckusick       index = 0;
117369200Smckusick 
117469200Smckusick       /* Choose the default set of word break characters to break completions.
117569200Smckusick 	 If we later find out that we are doing completions on command strings
117669200Smckusick 	 (as opposed to strings supplied by the individual command completer
117769200Smckusick 	 functions, which can be any string) then we will switch to the
117869200Smckusick 	 special word break set for command strings, which leaves out the
117969200Smckusick 	 '-' character used in some commands. */
118069200Smckusick 
118169200Smckusick       rl_completer_word_break_characters =
118269200Smckusick 	  gdb_completer_word_break_characters;
118369200Smckusick 
118469200Smckusick       /* Decide whether to complete on a list of gdb commands or on symbols. */
118569200Smckusick       tmp_command = (char *) alloca (rl_point + 1);
118669200Smckusick       p = tmp_command;
118769200Smckusick 
118869200Smckusick       strncpy (tmp_command, rl_line_buffer, rl_point);
118969200Smckusick       tmp_command[rl_point] = '\0';
119069200Smckusick 
119169200Smckusick       if (rl_point == 0)
119269200Smckusick 	{
119369200Smckusick 	  /* An empty line we want to consider ambiguous; that is, it
119469200Smckusick 	     could be any command.  */
119569200Smckusick 	  c = (struct cmd_list_element *) -1;
119669200Smckusick 	  result_list = 0;
119769200Smckusick 	}
119869200Smckusick       else
119969200Smckusick 	{
120069200Smckusick 	  c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
120169200Smckusick 	}
120269200Smckusick 
120369200Smckusick       /* Move p up to the next interesting thing.  */
120469200Smckusick       while (*p == ' ' || *p == '\t')
120569200Smckusick 	{
120669200Smckusick 	  p++;
120769200Smckusick 	}
120869200Smckusick 
120969200Smckusick       if (!c)
121069200Smckusick 	{
121169200Smckusick 	  /* He's typed something unrecognizable.  Sigh.  */
121269200Smckusick 	  list = NULL;
121369200Smckusick 	}
121469200Smckusick       else if (c == (struct cmd_list_element *) -1)
121569200Smckusick 	{
121669200Smckusick 	  /* If we didn't recognize everything up to the thing that
121769200Smckusick 	     needs completing, and we don't know what command it is
121869200Smckusick 	     yet, we are in trouble. */
121969200Smckusick 
122069200Smckusick 	  if (p + strlen(text) != tmp_command + rl_point)
122169200Smckusick 	    {
122269200Smckusick 	      /* This really should not produce an error.  Better would
122369200Smckusick 		 be to pretend to hit RETURN here; this would produce a
122469200Smckusick 		 response like "Ambiguous command: foo, foobar, etc",
122569200Smckusick 		 and leave the line available for re-entry with ^P.
122669200Smckusick 		 Instead, this error blows away the user's typed input
122769200Smckusick 		 without any way to get it back.  */
122869200Smckusick 	      error ("  Unrecognized command.");
122969200Smckusick 	    }
123069200Smckusick 
123169200Smckusick 	  /* He's typed something ambiguous.  This is easier.  */
123269200Smckusick 	  if (result_list)
123369200Smckusick 	    {
123469200Smckusick 	      list = complete_on_cmdlist (*result_list->prefixlist, text);
123569200Smckusick 	    }
123669200Smckusick 	  else
123769200Smckusick 	    {
123869200Smckusick 	      list = complete_on_cmdlist (cmdlist, text);
123969200Smckusick 	    }
124069200Smckusick 	  rl_completer_word_break_characters =
124169200Smckusick 	      gdb_completer_command_word_break_characters;
124269200Smckusick 	}
124369200Smckusick       else
124469200Smckusick 	{
124569200Smckusick 	  /* If we've gotten this far, gdb has recognized a full
124669200Smckusick 	     command.  There are several possibilities:
124769200Smckusick 
124869200Smckusick 	     1) We need to complete on the command.
124969200Smckusick 	     2) We need to complete on the possibilities coming after
125069200Smckusick 	     the command.
125169200Smckusick 	     2) We need to complete the text of what comes after the
125269200Smckusick 	     command.   */
125369200Smckusick 
125469200Smckusick 	  if (!*p && *text)
125569200Smckusick 	    {
125669200Smckusick 	      /* Always (might be longer versions of thie command).  */
125769200Smckusick 	      list = complete_on_cmdlist (result_list, text);
125869200Smckusick 	      rl_completer_word_break_characters =
125969200Smckusick 		  gdb_completer_command_word_break_characters;
126069200Smckusick 	    }
126169200Smckusick 	  else if (!*p && !*text)
126269200Smckusick 	    {
126369200Smckusick 	      if (c->prefixlist)
126469200Smckusick 		{
126569200Smckusick 		  list = complete_on_cmdlist (*c->prefixlist, "");
126669200Smckusick 		  rl_completer_word_break_characters =
126769200Smckusick 		      gdb_completer_command_word_break_characters;
126869200Smckusick 		}
126969200Smckusick 	      else
127069200Smckusick 		{
127169200Smckusick 		  list = (*c->completer) ("");
127269200Smckusick 		}
127369200Smckusick 	    }
127469200Smckusick 	  else
127569200Smckusick 	    {
127669200Smckusick 	      if (c->prefixlist && !c->allow_unknown)
127769200Smckusick 		{
127869200Smckusick 		  /* Something like "info adsfkdj".  But error() is not the
127969200Smckusick 		     proper response; just return no completions instead. */
128069200Smckusick 		  list = NULL;
128169200Smckusick 		}
128269200Smckusick 	      else
128369200Smckusick 		{
128469200Smckusick 		  list = (*c->completer) (text);
128569200Smckusick 		}
128669200Smckusick 	    }
128769200Smckusick 	}
128869200Smckusick     }
128969200Smckusick 
129069200Smckusick   /* If we found a list of potential completions during initialization then
129169200Smckusick      dole them out one at a time.  The vector of completions is NULL
129269200Smckusick      terminated, so after returning the last one, return NULL (and continue
129369200Smckusick      to do so) each time we are called after that, until a new list is
129469200Smckusick      available. */
129569200Smckusick 
129669200Smckusick   if (list)
129769200Smckusick     {
129869200Smckusick       output = list[index];
129969200Smckusick       if (output)
130069200Smckusick 	{
130169200Smckusick 	  index++;
130269200Smckusick 	}
130369200Smckusick     }
130469200Smckusick 
130569200Smckusick   return (output);
130669200Smckusick }
130769200Smckusick 
130869200Smckusick /* Skip over a possibly quoted word (as defined by the quote characters
130969200Smckusick    and word break characters the completer uses).  Returns pointer to the
131069200Smckusick    location after the "word". */
131169200Smckusick 
131269200Smckusick char *
skip_quoted(str)131369200Smckusick skip_quoted (str)
131469200Smckusick      char *str;
131569200Smckusick {
131669200Smckusick   char quote_char = '\0';
131769200Smckusick   char *scan;
131869200Smckusick 
131969200Smckusick   for (scan = str; *scan != '\0'; scan++)
132069200Smckusick     {
132169200Smckusick       if (quote_char != '\0')
132269200Smckusick 	{
132369200Smckusick 	  /* Ignore everything until the matching close quote char */
132469200Smckusick 	  if (*scan == quote_char)
132569200Smckusick 	    {
132669200Smckusick 	      /* Found matching close quote. */
132769200Smckusick 	      scan++;
132869200Smckusick 	      break;
132969200Smckusick 	    }
133069200Smckusick 	}
133169200Smckusick       else if (strchr (gdb_completer_quote_characters, *scan))
133269200Smckusick 	{
133369200Smckusick 	  /* Found start of a quoted string. */
133469200Smckusick 	  quote_char = *scan;
133569200Smckusick 	}
133669200Smckusick       else if (strchr (gdb_completer_word_break_characters, *scan))
133769200Smckusick 	{
133869200Smckusick 	  break;
133969200Smckusick 	}
134069200Smckusick     }
134169200Smckusick   return (scan);
134269200Smckusick }
134369200Smckusick 
134469200Smckusick 
134569200Smckusick #ifdef STOP_SIGNAL
134669200Smckusick static void
stop_sig(signo)134769200Smckusick stop_sig (signo)
134869200Smckusick int signo;
134969200Smckusick {
135069200Smckusick #if STOP_SIGNAL == SIGTSTP
135169200Smckusick   signal (SIGTSTP, SIG_DFL);
135269200Smckusick   sigsetmask (0);
135369200Smckusick   kill (getpid (), SIGTSTP);
135469200Smckusick   signal (SIGTSTP, stop_sig);
135569200Smckusick #else
135669200Smckusick   signal (STOP_SIGNAL, stop_sig);
135769200Smckusick #endif
135869200Smckusick   printf ("%s", masterprompt);
135969200Smckusick   fflush (stdout);
136069200Smckusick 
136169200Smckusick   /* Forget about any previous command -- null line now will do nothing.  */
136269200Smckusick   dont_repeat ();
136369200Smckusick }
136469200Smckusick #endif /* STOP_SIGNAL */
136569200Smckusick 
136669200Smckusick /* Initialize signal handlers. */
136769200Smckusick static void
do_nothing(signo)136869200Smckusick do_nothing (signo)
136969200Smckusick int signo;
137069200Smckusick {
137169200Smckusick }
137269200Smckusick 
137369200Smckusick static void suspend_sig ();
137469200Smckusick 
137569200Smckusick static void
init_signals()137669200Smckusick init_signals ()
137769200Smckusick {
137869200Smckusick   signal (SIGINT, request_quit);
137969200Smckusick 
138069200Smckusick   /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
138169200Smckusick      passed to the inferior, which we don't want.  It would be
138269200Smckusick      possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but
138369200Smckusick      on BSD4.3 systems using vfork, that will (apparently) affect the
138469200Smckusick      GDB process as well as the inferior (the signal handling tables
138569200Smckusick      being shared between the two, apparently).  Since we establish
138669200Smckusick      a handler for SIGQUIT, when we call exec it will set the signal
138769200Smckusick      to SIG_DFL for us.  */
138869200Smckusick   signal (SIGQUIT, do_nothing);
138969200Smckusick   if (signal (SIGHUP, do_nothing) != SIG_IGN)
139069200Smckusick     signal (SIGHUP, disconnect);
139169200Smckusick   signal (SIGFPE, float_handler);
139269200Smckusick 
139369200Smckusick #if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
139469200Smckusick   signal (SIGWINCH, SIGWINCH_HANDLER);
139569200Smckusick #endif
139669200Smckusick 
139769200Smckusick   init_term(fileno(stdin));
139869200Smckusick   signal(SIGTSTP, suspend_sig);
139969200Smckusick }
140069200Smckusick 
140169200Smckusick /* Execute the line P as a command.
140269200Smckusick    Pass FROM_TTY as second argument to the defining function.  */
140369200Smckusick 
140469200Smckusick void
execute_command(p,from_tty)140569200Smckusick execute_command (p, from_tty)
140669200Smckusick      char *p;
140769200Smckusick      int from_tty;
140869200Smckusick {
140969200Smckusick   register struct cmd_list_element *c;
141069200Smckusick   register struct command_line *cmdlines;
141169200Smckusick   register enum language flang;
141269200Smckusick   static const struct language_defn *saved_language = 0;
141369200Smckusick   static int warned = 0;
141469200Smckusick 
141569200Smckusick   free_all_values ();
141669200Smckusick 
141769200Smckusick   /* This can happen when command_line_input hits end of file.  */
141869200Smckusick   if (p == NULL)
141969200Smckusick       return;
142069200Smckusick 
142169200Smckusick   while (*p == ' ' || *p == '\t') p++;
142269200Smckusick   if (*p) {
142369200Smckusick 	  char *arg;
142469200Smckusick 
142569200Smckusick 	  c = lookup_cmd(&p, cmdlist, "", 0, 1);
142669200Smckusick 	  /* Pass null arg rather than an empty one.  */
142769200Smckusick 	  arg = *p ? p : 0;
142869200Smckusick 	  if (c->function.cfunc == 0)
142969200Smckusick 		  error("That is not a command, just a help topic.");
143069200Smckusick 	  else if (c->class == (int) class_user) {
143169200Smckusick 		  extern struct cleanup *setup_user_args();
143269200Smckusick 
143369200Smckusick 		  struct cleanup *old_chain = setup_user_args(p);
143469200Smckusick 
143569200Smckusick 		  if (c->user_commands != 0)
143669200Smckusick 			  (void)execute_command_lines(c->user_commands);
143769200Smckusick 
143869200Smckusick 		  do_cleanups(old_chain);
143969200Smckusick 	  } else if (c->type == set_cmd || c->type == show_cmd)
144069200Smckusick 		  do_setshow_command (arg, from_tty & caution, c);
144169200Smckusick 	  else if (c->function.cfunc == NO_FUNCTION)
144269200Smckusick 		  error ("That is not a command, just a help topic.");
144369200Smckusick 	  else
144469200Smckusick 		  (*c->function.cfunc) (arg, from_tty & caution);
144569200Smckusick   }
144669200Smckusick   /* Tell the user if the language has changed (except first time).  */
144769200Smckusick   if (current_language != saved_language)
144869200Smckusick   {
144969200Smckusick     if (language_mode == language_mode_auto) {
145069200Smckusick       if (saved_language)
145169200Smckusick 	language_info (1);
145269200Smckusick     }
145369200Smckusick     saved_language = current_language;
145469200Smckusick     warned = 0;
145569200Smckusick   }
145669200Smckusick 
145769200Smckusick   /* Warn the user if the working language does not match the
145869200Smckusick      language of the current frame.  Only warn the user if we are
145969200Smckusick      actually running the program, i.e. there is a stack. */
146069200Smckusick   /* FIXME:  This should be cacheing the frame and only running when
146169200Smckusick      the frame changes.  */
146269200Smckusick   if (target_has_stack)
146369200Smckusick   {
146469200Smckusick     flang = get_frame_language ();
146569200Smckusick     if (!warned
146669200Smckusick         && flang != language_unknown
146769200Smckusick 	&& flang != current_language->la_language)
146869200Smckusick     {
146969200Smckusick       printf_filtered ("%s\n", lang_frame_mismatch_warn);
147069200Smckusick       warned = 1;
147169200Smckusick     }
147269200Smckusick   }
147369200Smckusick }
147469200Smckusick 
147569200Smckusick /* Add an element to the list of info subcommands.  */
147669200Smckusick 
147769200Smckusick void
add_info(name,fun,doc)147869200Smckusick add_info (name, fun, doc)
147969200Smckusick      char *name;
148069200Smckusick      void (*fun) PARAMS ((char *, int));
148169200Smckusick      char *doc;
148269200Smckusick {
148369200Smckusick   add_cmd (name, no_class, fun, doc, &infolist);
148469200Smckusick }
148569200Smckusick 
148669200Smckusick /* Add an alias to the list of info subcommands.  */
148769200Smckusick 
148869200Smckusick void
add_info_alias(name,oldname,abbrev_flag)148969200Smckusick add_info_alias (name, oldname, abbrev_flag)
149069200Smckusick      char *name;
149169200Smckusick      char *oldname;
149269200Smckusick      int abbrev_flag;
149369200Smckusick {
149469200Smckusick   add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
149569200Smckusick }
149669200Smckusick 
149769200Smckusick /* The "info" command is defined as a prefix, with allow_unknown = 0.
149869200Smckusick    Therefore, its own definition is called only for "info" with no args.  */
149969200Smckusick 
150069200Smckusick /* ARGSUSED */
150169200Smckusick static void
info_command(arg,from_tty)150269200Smckusick info_command (arg, from_tty)
150369200Smckusick      char *arg;
150469200Smckusick      int from_tty;
150569200Smckusick {
150669200Smckusick   printf ("\"info\" must be followed by the name of an info command.\n");
150769200Smckusick   help_list (infolist, "info ", -1, stdout);
150869200Smckusick }
150969200Smckusick 
151069200Smckusick /* The "show" command with no arguments shows all the settings.  */
151169200Smckusick 
151269200Smckusick /* ARGSUSED */
151369200Smckusick static void
show_command(arg,from_tty)151469200Smckusick show_command (arg, from_tty)
151569200Smckusick      char *arg;
151669200Smckusick      int from_tty;
151769200Smckusick {
151869200Smckusick   cmd_show_list (showlist, from_tty, "");
151969200Smckusick }
152069200Smckusick 
152169200Smckusick /* Add an element to the list of commands.  */
152269200Smckusick 
152369200Smckusick void
add_com(name,class,fun,doc)152469200Smckusick add_com (name, class, fun, doc)
152569200Smckusick      char *name;
152669200Smckusick      enum command_class class;
152769200Smckusick      void (*fun) PARAMS ((char *, int));
152869200Smckusick      char *doc;
152969200Smckusick {
153069200Smckusick   add_cmd (name, class, fun, doc, &cmdlist);
153169200Smckusick }
153269200Smckusick 
153369200Smckusick /* Add an alias or abbreviation command to the list of commands.  */
153469200Smckusick 
153569200Smckusick void
add_com_alias(name,oldname,class,abbrev_flag)153669200Smckusick add_com_alias (name, oldname, class, abbrev_flag)
153769200Smckusick      char *name;
153869200Smckusick      char *oldname;
153969200Smckusick      enum command_class class;
154069200Smckusick      int abbrev_flag;
154169200Smckusick {
154269200Smckusick   add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
154369200Smckusick }
154469200Smckusick 
154569200Smckusick void
error_no_arg(why)154669200Smckusick error_no_arg (why)
154769200Smckusick      char *why;
154869200Smckusick {
154969200Smckusick   error ("Argument required (%s).", why);
155069200Smckusick }
155169200Smckusick 
155269200Smckusick /* ARGSUSED */
155369200Smckusick static void
help_command(command,from_tty)155469200Smckusick help_command (command, from_tty)
155569200Smckusick      char *command;
155669200Smckusick      int from_tty; /* Ignored */
155769200Smckusick {
155869200Smckusick   help_cmd (command, stdout);
155969200Smckusick }
156069200Smckusick 
156169200Smckusick static void
validate_comname(comname)156269200Smckusick validate_comname (comname)
156369200Smckusick      char *comname;
156469200Smckusick {
156569200Smckusick   register char *p;
156669200Smckusick 
156769200Smckusick   if (comname == 0)
156869200Smckusick     error_no_arg ("name of command to define");
156969200Smckusick 
157069200Smckusick   p = comname;
157169200Smckusick   while (*p)
157269200Smckusick     {
157369200Smckusick       if (!isalnum(*p) && *p != '-')
157469200Smckusick 	error ("Junk in argument list: \"%s\"", p);
157569200Smckusick       p++;
157669200Smckusick     }
157769200Smckusick }
157869200Smckusick 
157969200Smckusick /* This is just a placeholder in the command data structures.  */
158069200Smckusick static void
user_defined_command(ignore,from_tty)158169200Smckusick user_defined_command (ignore, from_tty)
158269200Smckusick      char *ignore;
158369200Smckusick      int from_tty;
158469200Smckusick {
158569200Smckusick }
158669200Smckusick 
158769200Smckusick static void
define_command(comname,from_tty)158869200Smckusick define_command (comname, from_tty)
158969200Smckusick      char *comname;
159069200Smckusick      int from_tty;
159169200Smckusick {
159269200Smckusick   register struct command_line *cmds;
159369200Smckusick   register struct cmd_list_element *c, *newc, *hookc = 0;
159469200Smckusick   char *tem = comname;
159569200Smckusick #define	HOOK_STRING	"hook-"
159669200Smckusick #define	HOOK_LEN 5
159769200Smckusick 
159869200Smckusick   validate_comname (comname);
159969200Smckusick 
160069200Smckusick   /* Look it up, and verify that we got an exact match.  */
160169200Smckusick   c = lookup_cmd (&tem, cmdlist, "", -1, 1);
160269200Smckusick   if (c && 0 != strcmp (comname, c->name))
160369200Smckusick     c = 0;
160469200Smckusick 
160569200Smckusick   if (c)
160669200Smckusick     {
160769200Smckusick       if (c->class == class_user || c->class == class_alias)
160869200Smckusick 	tem = "Redefine command \"%s\"? ";
160969200Smckusick       else
161069200Smckusick 	tem = "Really redefine built-in command \"%s\"? ";
161169200Smckusick       if (!query (tem, c->name))
161269200Smckusick 	error ("Command \"%s\" not redefined.", c->name);
161369200Smckusick     }
161469200Smckusick 
161569200Smckusick   /* If this new command is a hook, then mark the command which it
161669200Smckusick      is hooking.  Note that we allow hooking `help' commands, so that
161769200Smckusick      we can hook the `stop' pseudo-command.  */
161869200Smckusick 
161969200Smckusick   if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
162069200Smckusick     {
162169200Smckusick       /* Look up cmd it hooks, and verify that we got an exact match.  */
162269200Smckusick       tem = comname+HOOK_LEN;
162369200Smckusick       hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
162469200Smckusick       if (hookc && 0 != strcmp (comname+HOOK_LEN, hookc->name))
162569200Smckusick 	hookc = 0;
162669200Smckusick       if (!hookc)
162769200Smckusick 	{
162869200Smckusick 	  warning ("Your new `%s' command does not hook any existing command.",
162969200Smckusick 		   comname);
163069200Smckusick 	  if (!query ("Proceed? ", (char *)0))
163169200Smckusick 	    error ("Not confirmed.");
163269200Smckusick 	}
163369200Smckusick     }
163469200Smckusick 
163569200Smckusick   comname = savestring (comname, strlen (comname));
163669200Smckusick 
163769200Smckusick   /* If the rest of the commands will be case insensitive, this one
163869200Smckusick      should behave in the same manner. */
163969200Smckusick   for (tem = comname; *tem; tem++)
164069200Smckusick     if (isupper(*tem)) *tem = tolower(*tem);
164169200Smckusick 
164269200Smckusick   if (from_tty)
164369200Smckusick     {
164469200Smckusick       printf ("Type commands for definition of \"%s\".\n\
164569200Smckusick End with a line saying just \"end\".\n", comname);
164669200Smckusick       fflush (stdout);
164769200Smckusick     }
164869200Smckusick 
164969200Smckusick   cmds = read_command_lines (from_tty);
165069200Smckusick 
165169200Smckusick   if (c && c->class == class_user)
165269200Smckusick     free_command_lines (c->user_commands);
165369200Smckusick 
165469200Smckusick   newc = add_cmd (comname, class_user, user_defined_command,
165569200Smckusick 	   (c && c->class == class_user)
165669200Smckusick 	   ? c->doc : savestring ("User-defined.", 13), &cmdlist);
165769200Smckusick   newc->user_commands = cmds;
165869200Smckusick 
165969200Smckusick   /* If this new command is a hook, then mark both commands as being
166069200Smckusick      tied.  */
166169200Smckusick   if (hookc)
166269200Smckusick     {
166369200Smckusick       hookc->hook = newc;	/* Target gets hooked.  */
166469200Smckusick       newc->hookee = hookc;	/* We are marked as hooking target cmd.  */
166569200Smckusick     }
166669200Smckusick }
166769200Smckusick 
166869200Smckusick static void
document_command(comname,from_tty)166969200Smckusick document_command (comname, from_tty)
167069200Smckusick      char *comname;
167169200Smckusick      int from_tty;
167269200Smckusick {
167369200Smckusick   struct command_line *doclines;
167469200Smckusick   register struct cmd_list_element *c;
167569200Smckusick   char *tem = comname;
167669200Smckusick 
167769200Smckusick   validate_comname (comname);
167869200Smckusick 
167969200Smckusick   c = lookup_cmd (&tem, cmdlist, "", 0, 1);
168069200Smckusick 
168169200Smckusick   if (c->class != class_user)
168269200Smckusick     error ("Command \"%s\" is built-in.", comname);
168369200Smckusick 
168469200Smckusick   if (from_tty)
168569200Smckusick     printf ("Type documentation for \"%s\".\n\
168669200Smckusick End with a line saying just \"end\".\n", comname);
168769200Smckusick 
168869200Smckusick   doclines = read_command_lines (from_tty);
168969200Smckusick 
169069200Smckusick   if (c->doc) free (c->doc);
169169200Smckusick 
169269200Smckusick   {
169369200Smckusick     register struct command_line *cl1;
169469200Smckusick     register int len = 0;
169569200Smckusick 
169669200Smckusick     for (cl1 = doclines; cl1; cl1 = cl1->next)
169769200Smckusick       len += strlen (cl1->line) + 1;
169869200Smckusick 
169969200Smckusick     c->doc = (char *) xmalloc (len + 1);
170069200Smckusick     *c->doc = 0;
170169200Smckusick 
170269200Smckusick     for (cl1 = doclines; cl1; cl1 = cl1->next)
170369200Smckusick       {
170469200Smckusick 	strcat (c->doc, cl1->line);
170569200Smckusick 	if (cl1->next)
170669200Smckusick 	  strcat (c->doc, "\n");
170769200Smckusick       }
170869200Smckusick   }
170969200Smckusick 
171069200Smckusick   free_command_lines (doclines);
171169200Smckusick }
171269200Smckusick 
171369200Smckusick static void
print_gnu_advertisement()171469200Smckusick print_gnu_advertisement()
171569200Smckusick {
171669200Smckusick     printf ("\
171769200Smckusick GDB is free software and you are welcome to distribute copies of it\n\
171869200Smckusick  under certain conditions; type \"show copying\" to see the conditions.\n\
171969200Smckusick There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
172069200Smckusick ");
172169200Smckusick }
172269200Smckusick 
172369200Smckusick static void
print_gdb_version()172469200Smckusick print_gdb_version ()
172569200Smckusick {
172669200Smckusick   printf_filtered ("\
172769200Smckusick GDB %s, Copyright 1992 Free Software Foundation, Inc.",
172869200Smckusick 	  version);
172969200Smckusick }
173069200Smckusick 
173169200Smckusick /* ARGSUSED */
173269200Smckusick static void
show_version(args,from_tty)173369200Smckusick show_version (args, from_tty)
173469200Smckusick      char *args;
173569200Smckusick      int from_tty;
173669200Smckusick {
173769200Smckusick   immediate_quit++;
173869200Smckusick   print_gnu_advertisement ();
173969200Smckusick   print_gdb_version ();
174069200Smckusick   printf_filtered ("\n");
174169200Smckusick   immediate_quit--;
174269200Smckusick }
174369200Smckusick 
174469200Smckusick /* xgdb calls this to reprint the usual GDB prompt.  */
174569200Smckusick 
174669200Smckusick void
print_prompt()174769200Smckusick print_prompt ()
174869200Smckusick {
174969200Smckusick   printf ("%s", masterprompt);
175069200Smckusick   fflush (stdout);
175169200Smckusick }
175269200Smckusick 
175369200Smckusick #ifdef HAVE_TERMIO
175469200Smckusick #include <termio.h>
175569200Smckusick static struct termio norm_tty;
175669200Smckusick 
init_term(tty)175769200Smckusick init_term(tty)
175869200Smckusick {
175969200Smckusick 	ioctl(tty, TCGETA, &norm_tty);
176069200Smckusick }
176169200Smckusick 
176269200Smckusick static void
suspend_sig()176369200Smckusick suspend_sig()
176469200Smckusick {
176569200Smckusick 	int tty = fileno(stdin);
176669200Smckusick 	struct termio cur_tty;
176769200Smckusick 
176869200Smckusick 	ioctl(tty, TCGETA, &cur_tty);
176969200Smckusick 	ioctl(tty, TCSETAW, &norm_tty);
177069200Smckusick 
177169200Smckusick 	(void) sigsetmask(0);
177269200Smckusick 	signal(SIGTSTP, SIG_DFL);
177369200Smckusick 	kill(0, SIGTSTP);
177469200Smckusick 
177569200Smckusick 	/*
177669200Smckusick 	 * we've just been resumed -- current tty params become new
177769200Smckusick 	 * 'normal' params (in case tset/stty was done while we were
177869200Smckusick 	 * suspended).  Merge values that readline might have changed
177969200Smckusick 	 * into new params, then restore term mode.
178069200Smckusick 	 */
178169200Smckusick 	ioctl(tty, TCGETA, &norm_tty);
178269200Smckusick 	cur_tty.c_lflag = (cur_tty.c_lflag & (ICANON|ECHO|ISIG)) |
178369200Smckusick 			  (norm_tty.c_lflag &~ (ICANON|ECHO|ISIG));
178469200Smckusick 	cur_tty.c_iflag = (cur_tty.c_iflag & (IXON|ISTRIP|INPCK)) |
178569200Smckusick 			  (norm_tty.c_iflag &~ (IXON|ISTRIP|INPCK));
178669200Smckusick 	ioctl(tty, TCSETAW, &cur_tty);
178769200Smckusick 
178869200Smckusick 	signal(SIGTSTP, suspend_sig);
178969200Smckusick 	print_prompt();
179069200Smckusick 
179169200Smckusick 	/*
179269200Smckusick 	 * Forget about any previous command -- null line now will do
179369200Smckusick 	 * nothing.
179469200Smckusick 	 */
179569200Smckusick 	dont_repeat();
179669200Smckusick }
179769200Smckusick 
179869200Smckusick #else
179969200Smckusick 
180069200Smckusick #include <fcntl.h>
180169200Smckusick #include <sgtty.h>
180269200Smckusick #include <sys/ioctl.h> /* XXX BSD: must follow sgtty.h for compat to kick in */
180369200Smckusick 
180469200Smckusick static struct sgttyb norm_tty;
180569200Smckusick static struct tchars norm_tchars;
180669200Smckusick static struct ltchars norm_ltchars;
180769200Smckusick static int norm_lflags;
180869200Smckusick 
180969200Smckusick #ifdef PASS8
181069200Smckusick #define RL_TFLAGS (RAW|CRMOD|ECHO|CBREAK|PASS8)
181169200Smckusick #else
181269200Smckusick #define RL_TFLAGS (RAW|CRMOD|ECHO|CBREAK)
181369200Smckusick #endif
181469200Smckusick 
init_term(tty)181569200Smckusick init_term(tty)
181669200Smckusick 	int tty;
181769200Smckusick {
181869200Smckusick   ioctl(tty, TIOCGETP, &norm_tty);
181969200Smckusick   ioctl(tty, TIOCLGET, &norm_lflags);
182069200Smckusick   ioctl(tty, TIOCGETC, &norm_tchars);
182169200Smckusick   ioctl(tty, TIOCGLTC, &norm_ltchars);
182269200Smckusick }
182369200Smckusick 
182469200Smckusick static void
suspend_sig()182569200Smckusick suspend_sig()
182669200Smckusick {
182769200Smckusick 	int tty = fileno(stdin);
182869200Smckusick 	struct sgttyb cur_tty;
182969200Smckusick 	struct tchars cur_tchars;
183069200Smckusick 	struct ltchars cur_ltchars;
183169200Smckusick 	int cur_lflags;
183269200Smckusick 	int cur_flags;
183369200Smckusick 
183469200Smckusick 	ioctl(tty, TIOCGETP, &cur_tty);
183569200Smckusick 	ioctl(tty, TIOCGETC, &cur_tchars);
183669200Smckusick 	ioctl(tty, TIOCLGET, &cur_lflags);
183769200Smckusick 	ioctl(tty, TIOCGLTC, &cur_ltchars);
183869200Smckusick 
183969200Smckusick 	ioctl(tty, TIOCSETP, &norm_tty);
184069200Smckusick 	ioctl(tty, TIOCSETC, &norm_tchars);
184169200Smckusick 	ioctl(tty, TIOCLSET, &norm_lflags);
184269200Smckusick 	ioctl(tty, TIOCSLTC, &norm_ltchars);
184369200Smckusick 
184469200Smckusick 	(void) sigsetmask(0);
184569200Smckusick 	signal(SIGTSTP, SIG_DFL);
184669200Smckusick 	kill(0, SIGTSTP);
184769200Smckusick 
184869200Smckusick 	/*
184969200Smckusick 	 * we've just been resumed -- current tty params become new
185069200Smckusick 	 * 'normal' params (in case tset/stty was done while we were
185169200Smckusick 	 * suspended).  Merge values that readline might have changed
185269200Smckusick 	 * into new params, then restore term mode.
185369200Smckusick 	 */
185469200Smckusick 	ioctl(tty, TIOCGETP, &norm_tty);
185569200Smckusick 	cur_flags = cur_tty.sg_flags;
185669200Smckusick 	cur_tty = norm_tty;
185769200Smckusick 	cur_tty.sg_flags = (cur_tty.sg_flags &~ RL_TFLAGS)
185869200Smckusick 			   | (cur_flags & RL_TFLAGS);
185969200Smckusick 
186069200Smckusick 	ioctl(tty, TIOCLGET, &norm_lflags);
186169200Smckusick #ifdef LPASS8
186269200Smckusick 	cur_lflags = (cur_lflags &~ LPASS8) | (cur_flags & LPASS8);
186369200Smckusick #endif
186469200Smckusick 	ioctl(tty, TIOCGETC, &norm_tchars);
186569200Smckusick 	ioctl(tty, TIOCGLTC, &norm_ltchars);
186669200Smckusick 
186769200Smckusick 	ioctl(tty, TIOCSETP, &cur_tty);
186869200Smckusick 	ioctl(tty, TIOCSETC, &cur_tchars);
186969200Smckusick 	ioctl(tty, TIOCLSET, &cur_lflags);
187069200Smckusick 	ioctl(tty, TIOCSLTC, &cur_ltchars);
187169200Smckusick 
187269200Smckusick 	signal(SIGTSTP, suspend_sig);
187369200Smckusick 	print_prompt();
187469200Smckusick 
187569200Smckusick 	/*
187669200Smckusick 	 * Forget about any previous command -- null line now will do
187769200Smckusick 	 * nothing.
187869200Smckusick 	 */
187969200Smckusick 	dont_repeat();
188069200Smckusick }
188169200Smckusick #endif /* HAVE_TERMIO */
188269200Smckusick 
188369200Smckusick static void
quit_command(args,from_tty)188469200Smckusick quit_command (args, from_tty)
188569200Smckusick      char *args;
188669200Smckusick      int from_tty;
188769200Smckusick {
188869200Smckusick   /*
188969200Smckusick    * Don't bother checking if the inferior_pid is 0 because the remote
189069200Smckusick    * module doesn't muck with it (for pid 0, target_kill should be a nop
189169200Smckusick    * in the ptrace case anyway -- moreover, inferior_pid should be private
189269200Smckusick    * to infptrace.c)
189369200Smckusick    */
189469200Smckusick   if (target_has_execution)
189569200Smckusick     {
189669200Smckusick       if (inhibit_confirm || query ("The program is running.  Quit anyway? "))
189769200Smckusick 	{
189869200Smckusick 	  if (attach_flag)
189969200Smckusick 	    target_detach (args, from_tty);
190069200Smckusick 	  else
190169200Smckusick 	    target_kill ();
190269200Smckusick 	}
190369200Smckusick       else
190469200Smckusick 	error ("Not confirmed.");
190569200Smckusick     }
190669200Smckusick   /* Save the history information if it is appropriate to do so.  */
190769200Smckusick   if (write_history_p && history_filename)
190869200Smckusick     write_history (history_filename);
190969200Smckusick   exit (0);
191069200Smckusick }
191169200Smckusick 
191269200Smckusick /* Returns whether GDB is running on a terminal and whether the user
191369200Smckusick    desires that questions be asked of them on that terminal.  */
191469200Smckusick 
191569200Smckusick int
input_from_terminal_p()191669200Smckusick input_from_terminal_p ()
191769200Smckusick {
191869200Smckusick   return gdb_has_a_terminal && (instream == stdin) & caution;
191969200Smckusick }
192069200Smckusick 
192169200Smckusick /* ARGSUSED */
192269200Smckusick static void
pwd_command(args,from_tty)192369200Smckusick pwd_command (args, from_tty)
192469200Smckusick      char *args;
192569200Smckusick      int from_tty;
192669200Smckusick {
192769200Smckusick   if (args) error ("The \"pwd\" command does not take an argument: %s", args);
192869200Smckusick   getcwd (dirbuf, sizeof (dirbuf));
192969200Smckusick 
193069200Smckusick   if (strcmp (dirbuf, current_directory))
193169200Smckusick     printf ("Working directory %s\n (canonically %s).\n",
193269200Smckusick 	    current_directory, dirbuf);
193369200Smckusick   else
193469200Smckusick     printf ("Working directory %s.\n", current_directory);
193569200Smckusick }
193669200Smckusick 
193769200Smckusick static void
cd_command(dir,from_tty)193869200Smckusick cd_command (dir, from_tty)
193969200Smckusick      char *dir;
194069200Smckusick      int from_tty;
194169200Smckusick {
194269200Smckusick   int len;
194369200Smckusick   int change;
194469200Smckusick 
194569200Smckusick   /* If the new directory is absolute, repeat is a no-op; if relative,
194669200Smckusick      repeat might be useful but is more likely to be a mistake.  */
194769200Smckusick   dont_repeat ();
194869200Smckusick 
194969200Smckusick   if (dir == 0)
195069200Smckusick     error_no_arg ("new working directory");
195169200Smckusick 
195269200Smckusick   dir = tilde_expand (dir);
195369200Smckusick   make_cleanup (free, dir);
195469200Smckusick 
195569200Smckusick   if (chdir (dir) < 0)
195669200Smckusick     perror_with_name (dir);
195769200Smckusick 
195869200Smckusick   len = strlen (dir);
195969200Smckusick   dir = savestring (dir, len - (len > 1 && dir[len-1] == '/'));
196069200Smckusick   if (dir[0] == '/')
196169200Smckusick     current_directory = dir;
196269200Smckusick   else
196369200Smckusick     {
196469200Smckusick       current_directory = concat (current_directory, "/", dir, NULL);
196569200Smckusick       free (dir);
196669200Smckusick     }
196769200Smckusick 
196869200Smckusick   /* Now simplify any occurrences of `.' and `..' in the pathname.  */
196969200Smckusick 
197069200Smckusick   change = 1;
197169200Smckusick   while (change)
197269200Smckusick     {
197369200Smckusick       char *p;
197469200Smckusick       change = 0;
197569200Smckusick 
197669200Smckusick       for (p = current_directory; *p;)
197769200Smckusick 	{
197869200Smckusick 	  if (!strncmp (p, "/./", 2)
197969200Smckusick 	      && (p[2] == 0 || p[2] == '/'))
198069200Smckusick 	    strcpy (p, p + 2);
198169200Smckusick 	  else if (!strncmp (p, "/..", 3)
198269200Smckusick 		   && (p[3] == 0 || p[3] == '/')
198369200Smckusick 		   && p != current_directory)
198469200Smckusick 	    {
198569200Smckusick 	      char *q = p;
198669200Smckusick 	      while (q != current_directory && q[-1] != '/') q--;
198769200Smckusick 	      if (q != current_directory)
198869200Smckusick 		{
198969200Smckusick 		  strcpy (q-1, p+3);
199069200Smckusick 		  p = q-1;
199169200Smckusick 		}
199269200Smckusick 	    }
199369200Smckusick 	  else p++;
199469200Smckusick 	}
199569200Smckusick     }
199669200Smckusick 
199769200Smckusick   forget_cached_source_info ();
199869200Smckusick 
199969200Smckusick   if (from_tty)
200069200Smckusick     pwd_command ((char *) 0, 1);
200169200Smckusick }
200269200Smckusick 
200369200Smckusick /* ARGSUSED */
200469200Smckusick static void
source_command(args,from_tty)200569200Smckusick source_command (args, from_tty)
200669200Smckusick      char *args;
200769200Smckusick      int from_tty;
200869200Smckusick {
200969200Smckusick   FILE *stream;
201069200Smckusick   struct cleanup *cleanups;
201169200Smckusick   char *file = args;
201269200Smckusick 
201369200Smckusick   if (file == 0)
201469200Smckusick     /* Let source without arguments read .gdbinit.  */
201569200Smckusick     file = gdbinit;
201669200Smckusick 
201769200Smckusick   file = tilde_expand (file);
201869200Smckusick   make_cleanup (free, file);
201969200Smckusick   stream = fopen (file, "r");
202069200Smckusick   if (stream == 0) {
202169200Smckusick     char *cp = xmalloc(strlen(file) + 5);
202269200Smckusick 
202369200Smckusick     sprintf(cp, "%s.gdb", file);
202469200Smckusick     make_cleanup (free, cp);
202569200Smckusick     stream = fopen(cp, "r");
202669200Smckusick     if (stream == 0)
202769200Smckusick       perror_with_name (file);
202869200Smckusick   }
202969200Smckusick 
203069200Smckusick   cleanups = make_cleanup (fclose, stream);
203169200Smckusick 
203269200Smckusick   read_command_file (stream);
203369200Smckusick 
203469200Smckusick   do_cleanups (cleanups);
203569200Smckusick }
203669200Smckusick 
203769200Smckusick /* ARGSUSED */
203869200Smckusick static void
echo_command(text,from_tty)203969200Smckusick echo_command (text, from_tty)
204069200Smckusick      char *text;
204169200Smckusick      int from_tty;
204269200Smckusick {
204369200Smckusick   char *p = text;
204469200Smckusick   register int c;
204569200Smckusick 
204669200Smckusick   if (text)
204769200Smckusick     while (c = *p++)
204869200Smckusick       {
204969200Smckusick 	if (c == '\\')
205069200Smckusick 	  {
205169200Smckusick 	    /* \ at end of argument is used after spaces
205269200Smckusick 	       so they won't be lost.  */
205369200Smckusick 	    if (*p == 0)
205469200Smckusick 	      return;
205569200Smckusick 
205669200Smckusick 	    c = parse_escape (&p);
205769200Smckusick 	    if (c >= 0)
205869200Smckusick 	      printf_filtered ("%c", c);
205969200Smckusick 	  }
206069200Smckusick 	else
206169200Smckusick 	  printf_filtered ("%c", c);
206269200Smckusick       }
206369200Smckusick 
206469200Smckusick   /* Force this output to appear now.  */
206569200Smckusick   wrap_here ("");
206669200Smckusick   fflush (stdout);
206769200Smckusick }
206869200Smckusick 
206969200Smckusick 
207069200Smckusick /* Functions to manipulate command line editing control variables.  */
207169200Smckusick 
207269200Smckusick /* Number of commands to print in each call to show_commands.  */
207369200Smckusick #define Hist_print 10
207469200Smckusick static void
show_commands(args,from_tty)207569200Smckusick show_commands (args, from_tty)
207669200Smckusick      char *args;
207769200Smckusick      int from_tty;
207869200Smckusick {
207969200Smckusick   /* Index for history commands.  Relative to history_base.  */
208069200Smckusick   int offset;
208169200Smckusick 
208269200Smckusick   /* Number of the history entry which we are planning to display next.
208369200Smckusick      Relative to history_base.  */
208469200Smckusick   static int num = 0;
208569200Smckusick 
208669200Smckusick   /* The first command in the history which doesn't exist (i.e. one more
208769200Smckusick      than the number of the last command).  Relative to history_base.  */
208869200Smckusick   int hist_len;
208969200Smckusick 
209069200Smckusick   extern struct _hist_entry *history_get PARAMS ((int));
209169200Smckusick   extern int history_base;
209269200Smckusick 
209369200Smckusick   /* Print out some of the commands from the command history.  */
209469200Smckusick   /* First determine the length of the history list.  */
209569200Smckusick   hist_len = history_size;
209669200Smckusick   for (offset = 0; offset < history_size; offset++)
209769200Smckusick     {
209869200Smckusick       if (!history_get (history_base + offset))
209969200Smckusick 	{
210069200Smckusick 	  hist_len = offset;
210169200Smckusick 	  break;
210269200Smckusick 	}
210369200Smckusick     }
210469200Smckusick 
210569200Smckusick   if (args)
210669200Smckusick     {
210769200Smckusick       if (args[0] == '+' && args[1] == '\0')
210869200Smckusick 	/* "info editing +" should print from the stored position.  */
210969200Smckusick 	;
211069200Smckusick       else
211169200Smckusick 	/* "info editing <exp>" should print around command number <exp>.  */
211269200Smckusick 	num = (parse_and_eval_address (args) - history_base) - Hist_print / 2;
211369200Smckusick     }
211469200Smckusick   /* "show commands" means print the last Hist_print commands.  */
211569200Smckusick   else
211669200Smckusick     {
211769200Smckusick       num = hist_len - Hist_print;
211869200Smckusick     }
211969200Smckusick 
212069200Smckusick   if (num < 0)
212169200Smckusick     num = 0;
212269200Smckusick 
212369200Smckusick   /* If there are at least Hist_print commands, we want to display the last
212469200Smckusick      Hist_print rather than, say, the last 6.  */
212569200Smckusick   if (hist_len - num < Hist_print)
212669200Smckusick     {
212769200Smckusick       num = hist_len - Hist_print;
212869200Smckusick       if (num < 0)
212969200Smckusick 	num = 0;
213069200Smckusick     }
213169200Smckusick 
213269200Smckusick   for (offset = num; offset < num + Hist_print && offset < hist_len; offset++)
213369200Smckusick     {
213469200Smckusick       printf_filtered ("%5d  %s\n", history_base + offset,
213569200Smckusick 	      (history_get (history_base + offset))->line);
213669200Smckusick     }
213769200Smckusick 
213869200Smckusick   /* The next command we want to display is the next one that we haven't
213969200Smckusick      displayed yet.  */
214069200Smckusick   num += Hist_print;
214169200Smckusick 
214269200Smckusick   /* If the user repeats this command with return, it should do what
214369200Smckusick      "show commands +" does.  This is unnecessary if arg is null,
214469200Smckusick      because "show commands +" is not useful after "show commands".  */
214569200Smckusick   if (from_tty && args)
214669200Smckusick     {
214769200Smckusick       args[0] = '+';
214869200Smckusick       args[1] = '\0';
214969200Smckusick     }
215069200Smckusick }
215169200Smckusick 
215269200Smckusick /* Called by do_setshow_command.  */
215369200Smckusick /* ARGSUSED */
215469200Smckusick static void
set_history_size_command(args,from_tty,c)215569200Smckusick set_history_size_command (args, from_tty, c)
215669200Smckusick      char *args;
215769200Smckusick      int from_tty;
215869200Smckusick      struct cmd_list_element *c;
215969200Smckusick {
216069200Smckusick   if (history_size == UINT_MAX)
216169200Smckusick     unstifle_history ();
216269200Smckusick   else if (history_size >= 0)
216369200Smckusick     stifle_history (history_size);
216469200Smckusick   else
216569200Smckusick     {
216669200Smckusick       history_size = UINT_MAX;
216769200Smckusick       error ("History size must be non-negative");
216869200Smckusick     }
216969200Smckusick }
217069200Smckusick 
217169200Smckusick /* ARGSUSED */
217269200Smckusick static void
set_history(args,from_tty)217369200Smckusick set_history (args, from_tty)
217469200Smckusick      char *args;
217569200Smckusick      int from_tty;
217669200Smckusick {
217769200Smckusick   printf ("\"set history\" must be followed by the name of a history subcommand.\n");
217869200Smckusick   help_list (sethistlist, "set history ", -1, stdout);
217969200Smckusick }
218069200Smckusick 
218169200Smckusick /* ARGSUSED */
218269200Smckusick static void
show_history(args,from_tty)218369200Smckusick show_history (args, from_tty)
218469200Smckusick      char *args;
218569200Smckusick      int from_tty;
218669200Smckusick {
218769200Smckusick   cmd_show_list (showhistlist, from_tty, "");
218869200Smckusick }
218969200Smckusick 
219069200Smckusick int info_verbose = 0;		/* Default verbose msgs off */
219169200Smckusick 
219269200Smckusick /* Called by do_setshow_command.  An elaborate joke.  */
219369200Smckusick /* ARGSUSED */
219469200Smckusick static void
set_verbose(args,from_tty,c)219569200Smckusick set_verbose (args, from_tty, c)
219669200Smckusick      char *args;
219769200Smckusick      int from_tty;
219869200Smckusick      struct cmd_list_element *c;
219969200Smckusick {
220069200Smckusick   char *cmdname = "verbose";
220169200Smckusick   struct cmd_list_element *showcmd;
220269200Smckusick 
220369200Smckusick   showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, 1);
220469200Smckusick 
220569200Smckusick   if (info_verbose)
220669200Smckusick     {
220769200Smckusick       c->doc = "Set verbose printing of informational messages.";
220869200Smckusick       showcmd->doc = "Show verbose printing of informational messages.";
220969200Smckusick     }
221069200Smckusick   else
221169200Smckusick     {
221269200Smckusick       c->doc = "Set verbosity.";
221369200Smckusick       showcmd->doc = "Show verbosity.";
221469200Smckusick     }
221569200Smckusick }
221669200Smckusick 
221769200Smckusick static void
float_handler(signo)221869200Smckusick float_handler (signo)
221969200Smckusick int signo;
222069200Smckusick {
222169200Smckusick   /* This message is based on ANSI C, section 4.7.  Note that integer
222269200Smckusick      divide by zero causes this, so "float" is a misnomer.  */
222369200Smckusick   error ("Erroneous arithmetic operation.");
222469200Smckusick }
222569200Smckusick 
222669200Smckusick /* Return whether we are running a batch file or from terminal.  */
222769200Smckusick int
batch_mode()222869200Smckusick batch_mode ()
222969200Smckusick {
223069200Smckusick   return !(instream == stdin && ISATTY (stdin));
223169200Smckusick }
223269200Smckusick 
223369200Smckusick 
223469200Smckusick static void
initialize_cmd_lists()223569200Smckusick initialize_cmd_lists ()
223669200Smckusick {
223769200Smckusick   cmdlist = NULL;
223869200Smckusick   infolist = NULL;
223969200Smckusick   enablelist = NULL;
224069200Smckusick   disablelist = NULL;
224169200Smckusick   deletelist = NULL;
224269200Smckusick   enablebreaklist = NULL;
224369200Smckusick   setlist = NULL;
224469200Smckusick   unsetlist = NULL;
224569200Smckusick   showlist = NULL;
224669200Smckusick   sethistlist = NULL;
224769200Smckusick   showhistlist = NULL;
224869200Smckusick   unsethistlist = NULL;
224969200Smckusick #if MAINTENANCE_CMDS
225069200Smckusick   maintenancelist = NULL;
225169200Smckusick   maintenanceinfolist = NULL;
225269200Smckusick   maintenanceprintlist = NULL;
225369200Smckusick #endif
225469200Smckusick   setprintlist = NULL;
225569200Smckusick   showprintlist = NULL;
225669200Smckusick   setchecklist = NULL;
225769200Smckusick   showchecklist = NULL;
225869200Smckusick }
225969200Smckusick 
226069200Smckusick /* Init the history buffer.  Note that we are called after the init file(s)
226169200Smckusick  * have been read so that the user can change the history file via his
226269200Smckusick  * .gdbinit file (for instance).  The GDBHISTFILE environment variable
226369200Smckusick  * overrides all of this.
226469200Smckusick  */
226569200Smckusick 
226669200Smckusick static void
initialize_history()226769200Smckusick initialize_history()
226869200Smckusick {
226969200Smckusick   char *tmpenv;
227069200Smckusick 
227169200Smckusick   tmpenv = getenv ("HISTSIZE");
227269200Smckusick   if (tmpenv)
227369200Smckusick     history_size = atoi (tmpenv);
227469200Smckusick   else if (!history_size)
227569200Smckusick     history_size = 256;
227669200Smckusick 
227769200Smckusick   stifle_history (history_size);
227869200Smckusick 
227969200Smckusick   tmpenv = getenv ("GDBHISTFILE");
228069200Smckusick   if (tmpenv)
228169200Smckusick     history_filename = savestring (tmpenv, strlen(tmpenv));
228269200Smckusick   else if (!history_filename) {
228369200Smckusick     /* We include the current directory so that if the user changes
228469200Smckusick        directories the file written will be the same as the one
228569200Smckusick        that was read.  */
228669200Smckusick     history_filename = concat (current_directory, "/.gdb_history", NULL);
228769200Smckusick   }
228869200Smckusick   read_history (history_filename);
228969200Smckusick }
229069200Smckusick 
229169200Smckusick void
set_prompt(s)229269200Smckusick set_prompt(s)
229369200Smckusick      char *s;
229469200Smckusick {
229569200Smckusick   if (masterprompt != 0)
229669200Smckusick     free (masterprompt);
229769200Smckusick   masterprompt = strsave (s);
229869200Smckusick }
229969200Smckusick 
230069200Smckusick static void
initialize_main()230169200Smckusick initialize_main ()
230269200Smckusick {
230369200Smckusick   struct cmd_list_element *c;
230469200Smckusick 
230569200Smckusick #ifdef DEFAULT_PROMPT
230669200Smckusick   set_prompt(DEFAULT_PROMPT);
230769200Smckusick #else
230869200Smckusick #ifdef KERNELDEBUG
230969200Smckusick   if (kernel_debugging) set_prompt ("(kgdb) "); else
231069200Smckusick #endif
231169200Smckusick   set_prompt("(gdb) ");
231269200Smckusick #endif
231369200Smckusick 
231469200Smckusick   /* Set the important stuff up for command editing.  */
231569200Smckusick   write_history_p = 0;
231669200Smckusick 
231769200Smckusick   /* Setup important stuff for command line editing.  */
231869200Smckusick   rl_completion_entry_function = (int (*)()) symbol_completion_function;
231969200Smckusick   rl_completer_word_break_characters = gdb_completer_word_break_characters;
232069200Smckusick   rl_completer_quote_characters = gdb_completer_quote_characters;
232169200Smckusick   rl_readline_name = "gdb";
232269200Smckusick 
232369200Smckusick   /* Define the classes of commands.
232469200Smckusick      They will appear in the help list in the reverse of this order.  */
232569200Smckusick 
232669200Smckusick   add_cmd ("internals", class_maintenance, NO_FUNCTION,
232769200Smckusick 	   "Maintenance commands.\n\
232869200Smckusick Some gdb commands are provided just for use by gdb maintainers.\n\
232969200Smckusick These commands are subject to frequent change, and may not be as\n\
233069200Smckusick well documented as user commands.",
233169200Smckusick 	   &cmdlist);
233269200Smckusick   add_cmd ("obscure", class_obscure, NO_FUNCTION, "Obscure features.", &cmdlist);
233369200Smckusick   add_cmd ("aliases", class_alias, NO_FUNCTION, "Aliases of other commands.", &cmdlist);
233469200Smckusick   add_cmd ("user-defined", class_user, NO_FUNCTION, "User-defined commands.\n\
233569200Smckusick The commands in this class are those defined by the user.\n\
233669200Smckusick Use the \"define\" command to define a command.", &cmdlist);
233769200Smckusick   add_cmd ("support", class_support, NO_FUNCTION, "Support facilities.", &cmdlist);
233869200Smckusick   add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
233969200Smckusick   add_cmd ("files", class_files, NO_FUNCTION, "Specifying and examining files.", &cmdlist);
234069200Smckusick   add_cmd ("breakpoints", class_breakpoint, NO_FUNCTION, "Making program stop at certain points.", &cmdlist);
234169200Smckusick   add_cmd ("data", class_vars, NO_FUNCTION, "Examining data.", &cmdlist);
234269200Smckusick   add_cmd ("stack", class_stack, NO_FUNCTION, "Examining the stack.\n\
234369200Smckusick The stack is made up of stack frames.  Gdb assigns numbers to stack frames\n\
234469200Smckusick counting from zero for the innermost (currently executing) frame.\n\n\
234569200Smckusick At any time gdb identifies one frame as the \"selected\" frame.\n\
234669200Smckusick Variable lookups are done with respect to the selected frame.\n\
234769200Smckusick When the program being debugged stops, gdb selects the innermost frame.\n\
234869200Smckusick The commands below can be used to select other frames by number or address.",
234969200Smckusick 	   &cmdlist);
235069200Smckusick   add_cmd ("running", class_run, NO_FUNCTION, "Running the program.", &cmdlist);
235169200Smckusick 
235269200Smckusick   add_com ("pwd", class_files, pwd_command,
235369200Smckusick 	   "Print working directory.  This is used for your program as well.");
235469200Smckusick   add_com ("cd", class_files, cd_command,
235569200Smckusick 	   "Set working directory to DIR for debugger and program being debugged.\n\
235669200Smckusick The change does not take effect for the program being debugged\n\
235769200Smckusick until the next time it is started.");
235869200Smckusick 
235969200Smckusick   add_show_from_set
236069200Smckusick     (add_set_cmd ("prompt", class_support, var_string, (char *)&masterprompt,
236169200Smckusick 	   "Set gdb's prompt",
236269200Smckusick 	   &setlist),
236369200Smckusick      &showlist);
236469200Smckusick 
236569200Smckusick   add_com ("echo", class_support, echo_command,
236669200Smckusick 	   "Print a constant string.  Give string as argument.\n\
236769200Smckusick C escape sequences may be used in the argument.\n\
236869200Smckusick No newline is added at the end of the argument;\n\
236969200Smckusick use \"\\n\" if you want a newline to be printed.\n\
237069200Smckusick Since leading and trailing whitespace are ignored in command arguments,\n\
237169200Smckusick if you want to print some you must use \"\\\" before leading whitespace\n\
237269200Smckusick to be printed or after trailing whitespace.");
237369200Smckusick   add_com ("document", class_support, document_command,
237469200Smckusick 	   "Document a user-defined command.\n\
237569200Smckusick Give command name as argument.  Give documentation on following lines.\n\
237669200Smckusick End with a line of just \"end\".");
237769200Smckusick   add_com ("define", class_support, define_command,
237869200Smckusick 	   "Define a new command name.  Command name is argument.\n\
237969200Smckusick Definition appears on following lines, one command per line.\n\
238069200Smckusick End with a line of just \"end\".\n\
238169200Smckusick Use the \"document\" command to give documentation for the new command.\n\
238269200Smckusick Commands defined in this way do not take arguments.");
238369200Smckusick 
238469200Smckusick #ifdef __STDC__
238569200Smckusick   add_com ("source", class_support, source_command,
238669200Smckusick 	   "Read commands from a file named FILE.\n\
238769200Smckusick Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\
238869200Smckusick when gdb is started.");
238969200Smckusick #else
239069200Smckusick   /* Punt file name, we can't help it easily.  */
239169200Smckusick   add_com ("source", class_support, source_command,
239269200Smckusick 	   "Read commands from a file named FILE.\n\
239369200Smckusick Note that the file \".gdbinit\" is read automatically in this way\n\
239469200Smckusick when gdb is started.");
239569200Smckusick #endif
239669200Smckusick 
239769200Smckusick   add_com ("quit", class_support, quit_command, "Exit gdb.");
239869200Smckusick   add_com ("help", class_support, help_command, "Print list of commands.");
239969200Smckusick   add_com_alias ("q", "quit", class_support, 1);
240069200Smckusick   add_com_alias ("h", "help", class_support, 1);
240169200Smckusick 
240269200Smckusick 
240369200Smckusick   c = add_set_cmd ("verbose", class_support, var_boolean, (char *)&info_verbose,
240469200Smckusick 		   "Set ",
240569200Smckusick 		   &setlist),
240669200Smckusick   add_show_from_set (c, &showlist);
240769200Smckusick   c->function.sfunc = set_verbose;
240869200Smckusick   set_verbose (NULL, 0, c);
240969200Smckusick 
241069200Smckusick   add_prefix_cmd ("history", class_support, set_history,
241169200Smckusick 		  "Generic command for setting command history parameters.",
241269200Smckusick 		  &sethistlist, "set history ", 0, &setlist);
241369200Smckusick   add_prefix_cmd ("history", class_support, show_history,
241469200Smckusick 		  "Generic command for showing command history parameters.",
241569200Smckusick 		  &showhistlist, "show history ", 0, &showlist);
241669200Smckusick 
241769200Smckusick   add_show_from_set
241869200Smckusick     (add_set_cmd ("save", no_class, var_boolean, (char *)&write_history_p,
241969200Smckusick 	   "Set saving of the history record on exit.\n\
242069200Smckusick Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\
242169200Smckusick Without an argument, saving is enabled.", &sethistlist),
242269200Smckusick      &showhistlist);
242369200Smckusick 
242469200Smckusick   c = add_set_cmd ("size", no_class, var_uinteger, (char *)&history_size,
242569200Smckusick 		   "Set the size of the command history, \n\
242669200Smckusick ie. the number of previous commands to keep a record of.", &sethistlist);
242769200Smckusick   add_show_from_set (c, &showhistlist);
242869200Smckusick   c->function.sfunc = set_history_size_command;
242969200Smckusick 
243069200Smckusick   add_show_from_set
243169200Smckusick     (add_set_cmd ("filename", no_class, var_filename, (char *)&history_filename,
243269200Smckusick 	   "Set the filename in which to record the command history\n\
243369200Smckusick  (the list of previous commands of which a record is kept).", &sethistlist),
243469200Smckusick      &showhistlist);
243569200Smckusick 
243669200Smckusick   add_show_from_set
243769200Smckusick     (add_set_cmd ("confirm", class_support, var_boolean,
243869200Smckusick 		  (char *)&caution,
243969200Smckusick 		  "Set whether to confirm potentially dangerous operations.",
244069200Smckusick 		  &setlist),
244169200Smckusick      &showlist);
244269200Smckusick 
244369200Smckusick   add_prefix_cmd ("info", class_info, info_command,
244469200Smckusick         "Generic command for showing things about the program being debugged.",
244569200Smckusick 		  &infolist, "info ", 0, &cmdlist);
244669200Smckusick   add_com_alias ("i", "info", class_info, 1);
244769200Smckusick 
244869200Smckusick   add_prefix_cmd ("show", class_info, show_command,
244969200Smckusick 		  "Generic command for showing things about the debugger.",
245069200Smckusick 		  &showlist, "show ", 0, &cmdlist);
245169200Smckusick   /* Another way to get at the same thing.  */
245269200Smckusick   add_info ("set", show_command, "Show all GDB settings.");
245369200Smckusick 
245469200Smckusick   add_cmd ("commands", no_class, show_commands,
245569200Smckusick 	   "Show the the history of commands you typed.\n\
245669200Smckusick You can supply a command number to start with, or a `+' to start after\n\
245769200Smckusick the previous command number shown.",
245869200Smckusick 	   &showlist);
245969200Smckusick 
246069200Smckusick   add_cmd ("version", no_class, show_version,
246169200Smckusick 	   "Show what version of GDB this is.", &showlist);
246269200Smckusick }
2463