* alpha-tdep.c (alpha_supply_int_regs, alpha_fill_int_regs,
[deliverable/binutils-gdb.git] / gdb / main.c
index df93e5e51dd683850aebedd733618fe1bd1e6fd6..7cc14adc93852aa226fc799d3b05645d37e8d980 100644 (file)
@@ -1,8 +1,8 @@
 /* Top level stuff for GDB, the GNU debugger.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
-   Foundation, Inc.
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "top.h"
@@ -73,6 +73,15 @@ struct ui_file *gdb_stdtargin;
 struct ui_file *gdb_stdtarg;
 struct ui_file *gdb_stdtargerr;
 
+/* Support for the --batch-silent option.  */
+int batch_silent = 0;
+
+/* Support for --return-child-result option.
+   Set the default to -1 to return error in the case
+   that the program does not run or does not complete.  */
+int return_child_result = 0;
+int return_child_result_value = -1;
+
 /* Whether to enable writing into executable and core files */
 extern int write_files;
 
@@ -129,7 +138,13 @@ captured_main (void *data)
   static int print_version;
 
   /* Pointers to all arguments of --command option.  */
-  char **cmdarg;
+  struct cmdarg {
+    enum {
+      CMDARG_FILE,
+      CMDARG_COMMAND
+    } type;
+    char *string;
+  } *cmdarg;
   /* Allocated size of cmdarg.  */
   int cmdsize;
   /* Number of elements of cmdarg used.  */
@@ -143,7 +158,7 @@ captured_main (void *data)
   int ndir;
 
   struct stat homebuf, cwdbuf;
-  char *homedir, *homeinit;
+  char *homedir;
 
   int i;
 
@@ -169,7 +184,7 @@ captured_main (void *data)
 #endif
 
   cmdsize = 1;
-  cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg));
+  cmdarg = (struct cmdarg *) xmalloc (cmdsize * sizeof (*cmdarg));
   ncmd = 0;
   dirsize = 1;
   dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
@@ -191,9 +206,6 @@ captured_main (void *data)
   gdb_stdtargerr = gdb_stderr; /* for moment */
   gdb_stdtargin = gdb_stdin;   /* for moment */
 
-  /* initialize error() */
-  error_init ();
-
   /* Set the sysroot path.  */
 #ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
   gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
@@ -209,19 +221,60 @@ captured_main (void *data)
       if (res == 0)
        {
          xfree (gdb_sysroot);
-         gdb_sysroot = TARGET_SYSTEM_ROOT;
+         gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
        }
     }
   else
-    gdb_sysroot = TARGET_SYSTEM_ROOT;
+    gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
 #else
-#if defined (TARGET_SYSTEM_ROOT)
-  gdb_sysroot = TARGET_SYSTEM_ROOT;
-#else
-  gdb_sysroot = "";
+  gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
 #endif
+
+  /* Canonicalize the sysroot path.  */
+  if (*gdb_sysroot)
+    {
+      char *canon_sysroot = lrealpath (gdb_sysroot);
+      if (canon_sysroot)
+       {
+         xfree (gdb_sysroot);
+         gdb_sysroot = canon_sysroot;
+       }
+    }
+
+#ifdef DEBUGDIR_RELOCATABLE
+  debug_file_directory = make_relative_prefix (argv[0], BINDIR, DEBUGDIR);
+  if (debug_file_directory)
+    {
+      struct stat s;
+      int res = 0;
+
+      if (stat (debug_file_directory, &s) == 0)
+       if (S_ISDIR (s.st_mode))
+         res = 1;
+
+      if (res == 0)
+       {
+         xfree (debug_file_directory);
+         debug_file_directory = xstrdup (DEBUGDIR);
+       }
+    }
+  else
+    debug_file_directory = xstrdup (DEBUGDIR);
+#else
+  debug_file_directory = xstrdup (DEBUGDIR);
 #endif
 
+  /* Canonicalize the debugfile path.  */
+  if (*debug_file_directory)
+    {
+      char *canon_debug = lrealpath (debug_file_directory);
+      if (canon_debug)
+       {
+         xfree (debug_file_directory);
+         debug_file_directory = canon_debug;
+       }
+    }
+
   /* There will always be an interpreter.  Either the one passed into
      this captured main, or one specified by the user at start up, or
      the console.  Initialize the interpreter to the one requested by 
@@ -257,6 +310,7 @@ captured_main (void *data)
       {"silent", no_argument, &quiet, 1},
       {"nx", no_argument, &inhibit_gdbinit, 1},
       {"n", no_argument, &inhibit_gdbinit, 1},
+      {"batch-silent", no_argument, 0, 'B'},
       {"batch", no_argument, &batch, 1},
       {"epoch", no_argument, &epoch_interface, 1},
 
@@ -278,8 +332,10 @@ captured_main (void *data)
       {"pid", required_argument, 0, 'p'},
       {"p", required_argument, 0, 'p'},
       {"command", required_argument, 0, 'x'},
+      {"eval-command", required_argument, 0, 'X'},
       {"version", no_argument, &print_version, 1},
       {"x", required_argument, 0, 'x'},
+      {"ex", required_argument, 0, 'X'},
 #ifdef GDBTK
       {"tclcommand", required_argument, 0, 'z'},
       {"enable-external-editor", no_argument, 0, 'y'},
@@ -302,6 +358,7 @@ captured_main (void *data)
       {"write", no_argument, &write_files, 1},
       {"args", no_argument, &set_args, 1},
      {"l", required_argument, 0, 'l'},
+      {"return-child-result", no_argument, &return_child_result, 1},
       {0, no_argument, 0, 0}
     };
 
@@ -342,11 +399,16 @@ captured_main (void *data)
          case OPT_TUI:
            /* --tui is equivalent to -i=tui.  */
            xfree (interpreter_p);
-           interpreter_p = xstrdup ("tui");
+           interpreter_p = xstrdup (INTERP_TUI);
            break;
          case OPT_WINDOWS:
            /* FIXME: cagney/2003-03-01: Not sure if this option is
                actually useful, and if it is, what it should do.  */
+#ifdef GDBTK
+           /* --windows is equivalent to -i=insight.  */
+           xfree (interpreter_p);
+           interpreter_p = xstrdup (INTERP_INSIGHT);
+#endif
            use_windows = 1;
            break;
          case OPT_NOWINDOWS:
@@ -374,14 +436,29 @@ captured_main (void *data)
            corearg = optarg;
            break;
          case 'x':
-           cmdarg[ncmd++] = optarg;
+           cmdarg[ncmd].type = CMDARG_FILE;
+           cmdarg[ncmd++].string = optarg;
            if (ncmd >= cmdsize)
              {
                cmdsize *= 2;
-               cmdarg = (char **) xrealloc ((char *) cmdarg,
-                                            cmdsize * sizeof (*cmdarg));
+               cmdarg = xrealloc ((char *) cmdarg,
+                                  cmdsize * sizeof (*cmdarg));
              }
            break;
+         case 'X':
+           cmdarg[ncmd].type = CMDARG_COMMAND;
+           cmdarg[ncmd++].string = optarg;
+           if (ncmd >= cmdsize)
+             {
+               cmdsize *= 2;
+               cmdarg = xrealloc ((char *) cmdarg,
+                                  cmdsize * sizeof (*cmdarg));
+             }
+           break;
+         case 'B':
+           batch = batch_silent = 1;
+           gdb_stdout = ui_file_new();
+           break;
 #ifdef GDBTK
          case 'z':
            {
@@ -553,6 +630,7 @@ extern int gdbtk_test (char *);
       if (symarg)
        printf_filtered ("..");
       wrap_here ("");
+      printf_filtered ("\n");
       gdb_flush (gdb_stdout);  /* Force to screen during slow operations */
     }
 
@@ -564,7 +642,7 @@ extern int gdbtk_test (char *);
     /* Find it.  */
     struct interp *interp = interp_lookup (interpreter_p);
     if (interp == NULL)
-      error ("Interpreter `%s' unrecognized", interpreter_p);
+      error (_("Interpreter `%s' unrecognized"), interpreter_p);
     /* Install it.  */
     if (!interp_set (interp))
       {
@@ -587,13 +665,13 @@ extern int gdbtk_test (char *);
       if (symarg)
        printf_filtered ("..");
       wrap_here ("");
+      printf_filtered ("\n");
       gdb_flush (gdb_stdout);  /* Force to screen during slow operations */
     }
 
-  error_pre_print = "\n\n";
+  /* Set off error and warning messages with a blank line.  */
+  error_pre_print = "\n";
   quit_pre_print = error_pre_print;
-
-  /* We may get more than one warning, don't double space all of them... */
   warning_pre_print = _("\nwarning: ");
 
   /* Read and execute $HOME/.gdbinit file, if it exists.  This is done
@@ -603,15 +681,11 @@ extern int gdbtk_test (char *);
   homedir = getenv ("HOME");
   if (homedir)
     {
-      homeinit = (char *) alloca (strlen (homedir) +
-                                 strlen (gdbinit) + 10);
-      strcpy (homeinit, homedir);
-      strcat (homeinit, "/");
-      strcat (homeinit, gdbinit);
+      char *homeinit = xstrprintf ("%s/%s", homedir, gdbinit);
 
       if (!inhibit_gdbinit)
        {
-         catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+         catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL);
        }
 
       /* Do stats; no need to do them elsewhere since we'll only
@@ -625,6 +699,7 @@ extern int gdbtk_test (char *);
       stat (homeinit, &homebuf);
       stat (gdbinit, &cwdbuf); /* We'll only need this if
                                   homedir was set.  */
+      xfree (homeinit);
     }
 
   /* Now perform all the actions indicated by the arguments.  */
@@ -634,7 +709,7 @@ extern int gdbtk_test (char *);
     }
 
   for (i = 0; i < ndir; i++)
-    catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL);
+    catch_command_errors (directory_switch, dirarg[i], 0, RETURN_MASK_ALL);
   xfree (dirarg);
 
   if (execarg != NULL
@@ -655,15 +730,6 @@ extern int gdbtk_test (char *);
        catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
     }
 
-  /* After the symbol file has been read, print a newline to get us
-     beyond the copyright line...  But errors should still set off
-     the error message with a (single) blank line.  */
-  if (!quiet)
-    printf_filtered ("\n");
-  error_pre_print = "\n";
-  quit_pre_print = error_pre_print;
-  warning_pre_print = _("\nwarning: ");
-
   if (corearg != NULL)
     {
       /* corearg may be either a corefile or a pid.
@@ -697,7 +763,7 @@ extern int gdbtk_test (char *);
       || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
     if (!inhibit_gdbinit)
       {
-       catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL);
+       catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL);
       }
 
   for (i = 0; i < ncmd; i++)
@@ -715,11 +781,16 @@ extern int gdbtk_test (char *);
            read_command_file (stdin);
          else
 #endif
-           source_command (cmdarg[i], !batch);
+           source_script (cmdarg[i], !batch);
          do_cleanups (ALL_CLEANUPS);
        }
 #endif
-      catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL);
+      if (cmdarg[i].type == CMDARG_FILE)
+        catch_command_errors (source_script, cmdarg[i].string,
+                             !batch, RETURN_MASK_ALL);
+      else  /* cmdarg[i].type == CMDARG_COMMAND */
+        catch_command_errors (execute_command, cmdarg[i].string,
+                             !batch, RETURN_MASK_ALL);
     }
   xfree (cmdarg);
 
@@ -728,15 +799,8 @@ extern int gdbtk_test (char *);
 
   if (batch)
     {
-      if (attach_flag)
-       /* Either there was a problem executing the command in the
-          batch file aborted early, or the batch file forgot to do an
-          explicit detach.  Explicitly detach the inferior ensuring
-          that there are no zombies.  */
-       target_detach (NULL, 0);
-      
       /* We have hit the end of the batch file.  */
-      exit (0);
+      quit_force (NULL, 0);
     }
 
   /* Do any host- or target-specific hacks.  This is used for i960 targets
@@ -831,15 +895,19 @@ Options:\n\n\
 "), stream);
   fputs_unfiltered (_("\
   --args             Arguments after executable-file are passed to inferior\n\
-"), stream);
-  fputs_unfiltered (_("\
-  --[no]async        Enable (disable) asynchronous version of CLI\n\
 "), stream);
   fputs_unfiltered (_("\
   -b BAUDRATE        Set serial port baud rate used for remote debugging.\n\
   --batch            Exit after processing options.\n\
+  --batch-silent     As for --batch, but suppress all gdb stdout output.\n\
+  --return-child-result\n\
+                     GDB exit code will be the child's exit code.\n\
   --cd=DIR           Change current directory to DIR.\n\
-  --command=FILE     Execute GDB commands from FILE.\n\
+  --command=FILE, -x Execute GDB commands from FILE.\n\
+  --eval-command=COMMAND, -ex\n\
+                     Execute a single GDB command.\n\
+                     May be used multiple times and in conjunction\n\
+                     with --command.\n\
   --core=COREFILE    Analyze the core dump COREFILE.\n\
   --pid=PID          Attach to running process PID.\n\
 "), stream);
@@ -857,7 +925,6 @@ Options:\n\n\
 "), stream);
   fputs_unfiltered (_("\
   -l TIMEOUT         Set timeout in seconds for remote debugging.\n\
-  --mapped           Use mapped symbol files if supported on this system.\n\
   --nw              Do not use a window interface.\n\
   --nx               Do not read "), stream);
   fputs_unfiltered (gdbinit, stream);
This page took 0.04192 seconds and 4 git commands to generate.