* values.c, value.h (modify_field), callers: Make fieldval a LONGEST.
[deliverable/binutils-gdb.git] / gdb / main.c
index 1976a5d43beef38be022f320af1208af21c9d950..5e00b8639ad8437ab5e111aa146c4737559f4e86 100644 (file)
@@ -78,13 +78,13 @@ static void
 quit_command PARAMS ((char *, int));
 
 static void
-initialize_main PARAMS ((void));
+init_main PARAMS ((void));
 
 static void
-initialize_history PARAMS ((void));
+init_history PARAMS ((void));
 
 static void
-initialize_cmd_lists PARAMS ((void));
+init_cmd_lists PARAMS ((void));
 
 static void
 float_handler PARAMS ((int));
@@ -169,7 +169,8 @@ source_cleanup PARAMS ((FILE *));
 #ifndef        GDBINIT_FILENAME
 #define        GDBINIT_FILENAME        ".gdbinit"
 #endif
-char gdbinit[] = GDBINIT_FILENAME;
+static char gdbinit[] = GDBINIT_FILENAME;
+static int inhibit_gdbinit = 0;
 
 #define        ALL_CLEANUPS    ((struct cleanup *)0)
 
@@ -177,6 +178,14 @@ char gdbinit[] = GDBINIT_FILENAME;
 
 extern char *version;
 
+/* Canonical host name as a string. */
+
+extern char *host_canonical;
+
+/* Canonical target name as a string. */
+
+extern char *target_canonical;
+
 /* Message to be printed before the error message, when an error occurs.  */
 
 extern char *error_pre_print;
@@ -290,7 +299,6 @@ static char dirbuf[1024];
 
 void (*window_hook) PARAMS ((FILE *, char *));
 
-extern int frame_file_full_name;
 extern int mapped_symbol_files;
 extern int readnow_symbol_files;
 
@@ -329,33 +337,63 @@ static void stop_sig PARAMS ((int));
 #define sigsetmask(n)
 #endif
 \f
-/* This is how `error' returns to command level.  */
+/* Where to go for return_to_top_level (RETURN_ERROR).  */
+static jmp_buf error_return;
+/* Where to go for return_to_top_level (RETURN_QUIT).  */
+static jmp_buf quit_return;
+
+/* Temporary variable for SET_TOP_LEVEL.  */
+static int top_level_val;
 
-jmp_buf to_top_level;
+/* Do a setjmp on error_return and quit_return.  catch_errors is
+   generally a cleaner way to do this, but main() would look pretty
+   ugly if it had to use catch_errors each time.  */
+
+#define SET_TOP_LEVEL() \
+  (((top_level_val = setjmp (error_return)) \
+    ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (jmp_buf))) \
+   , top_level_val)
+
+/* Return for reason REASON.  This generally gets back to the command
+   loop, but can be caught via catch_errors.  */
 
 NORETURN void
-return_to_top_level ()
+return_to_top_level (reason)
+     enum return_reason reason;
 {
   quit_flag = 0;
   immediate_quit = 0;
   bpstat_clear_actions(stop_bpstat);   /* Clear queued breakpoint commands */
   disable_current_display ();
   do_cleanups (ALL_CLEANUPS);
-  (NORETURN void) longjmp (to_top_level, 1);
+  (NORETURN void) longjmp
+    (reason == RETURN_ERROR ? error_return : quit_return, 1);
 }
 
-/* Call FUNC with arg ARGS, catching any errors.
-   If there is no error, return the value returned by FUNC.
-   If there is an error, print ERRSTRING, print the specific error message,
-                        then return zero.  */
+/* Call FUNC with arg ARGS, catching any errors.  If there is no
+   error, return the value returned by FUNC.  If there is an error,
+   print ERRSTRING, print the specific error message, then return
+   zero.
+
+   MASK specifies what to catch; it is normally set to
+   RETURN_MASK_ALL, if for no other reason than that the code which
+   calls catch_errors might not be set up to deal with a quit which
+   isn't caught.  But if the code can deal with it, it generally
+   should be RETURN_MASK_ERROR, unless for some reason it is more
+   useful to abort only the portion of the operation inside the
+   catch_errors.  Note that quit should return to the command line
+   fairly quickly, even if some further processing is being done.  */
 
 int
-catch_errors (func, args, errstring)
+catch_errors (func, args, errstring, mask)
      int (*func) PARAMS ((char *));
-     char *args;
+     PTR args;
      char *errstring;
+     return_mask mask;
 {
-  jmp_buf saved;
+  jmp_buf saved_error;
+  jmp_buf saved_quit;
+  jmp_buf tmp_jmp;
   int val;
   struct cleanup *saved_cleanup_chain;
   char *saved_error_pre_print;
@@ -363,18 +401,30 @@ catch_errors (func, args, errstring)
   saved_cleanup_chain = save_cleanups ();
   saved_error_pre_print = error_pre_print;
 
-  memcpy ((char *)saved, (char *)to_top_level, sizeof (jmp_buf));
+  if (mask & RETURN_MASK_ERROR)
+    memcpy ((char *)saved_error, (char *)error_return, sizeof (jmp_buf));
+  if (mask & RETURN_MASK_QUIT)
+    memcpy (saved_quit, quit_return, sizeof (jmp_buf));
   error_pre_print = errstring;
 
-  if (setjmp (to_top_level) == 0)
-    val = (*func) (args);
+  if (setjmp (tmp_jmp) == 0)
+    {
+      if (mask & RETURN_MASK_ERROR)
+       memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
+      if (mask & RETURN_MASK_QUIT)
+       memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
+      val = (*func) (args);
+    }
   else
     val = 0;
 
   restore_cleanups (saved_cleanup_chain);
 
   error_pre_print = saved_error_pre_print;
-  memcpy ((char *)to_top_level, (char *)saved, sizeof (jmp_buf));
+  if (mask & RETURN_MASK_ERROR)
+    memcpy (error_return, saved_error, sizeof (jmp_buf));
+  if (mask & RETURN_MASK_QUIT)
+    memcpy (quit_return, saved_quit, sizeof (jmp_buf));
   return val;
 }
 
@@ -384,7 +434,8 @@ static void
 disconnect (signo)
 int signo;
 {
-  catch_errors (quit_cover, NULL, "Could not kill inferior process");
+  catch_errors (quit_cover, NULL,
+               "Could not kill the program being debugged", RETURN_MASK_ALL);
   signal (SIGHUP, SIG_DFL);
   kill (getpid (), SIGHUP);
 }
@@ -431,7 +482,6 @@ main (argc, argv)
      char **argv;
 {
   int count;
-  static int inhibit_gdbinit = 0;
   static int quiet = 0;
   static int batch = 0;
 
@@ -471,7 +521,7 @@ main (argc, argv)
 #endif
 
   /* If error() is called from initialization code, just exit */
-  if (setjmp (to_top_level)) {
+  if (SET_TOP_LEVEL ()) {
     exit(1);
   }
 
@@ -679,9 +729,9 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
 
   /* Run the init function of each source file */
 
-  initialize_cmd_lists ();     /* This needs to be done first */
+  init_cmd_lists ();   /* This needs to be done first */
   initialize_all_files ();
-  initialize_main ();          /* But that omits this file!  Do it now */
+  init_main ();                /* But that omits this file!  Do it now */
   init_signals ();
 
   if (!quiet)
@@ -720,7 +770,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
       strcat (homeinit, gdbinit);
       if (!inhibit_gdbinit && access (homeinit, R_OK) == 0)
        {
-         if (!setjmp (to_top_level))
+         if (!SET_TOP_LEVEL ())
            source_command (homeinit, 0);
        }
       do_cleanups (ALL_CLEANUPS);
@@ -741,7 +791,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   /* Now perform all the actions indicated by the arguments.  */
   if (cdarg != NULL)
     {
-      if (!setjmp (to_top_level))
+      if (!SET_TOP_LEVEL ())
        {
          cd_command (cdarg, 0);
          init_source_path ();
@@ -750,18 +800,18 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   do_cleanups (ALL_CLEANUPS);
 
   for (i = 0; i < ndir; i++)
-    if (!setjmp (to_top_level))
+    if (!SET_TOP_LEVEL ())
       directory_command (dirarg[i], 0);
   free ((PTR)dirarg);
   do_cleanups (ALL_CLEANUPS);
 
   if (execarg != NULL
       && symarg != NULL
-      && strcmp (execarg, symarg) == 0)
+      && STREQ (execarg, symarg))
     {
       /* The exec file and the symbol-file are the same.  If we can't open
         it, better only print one error message.  */
-      if (!setjmp (to_top_level))
+      if (!SET_TOP_LEVEL ())
        {
          exec_file_command (execarg, !batch);
          symbol_file_command (symarg, 0);
@@ -770,10 +820,10 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   else
     {
       if (execarg != NULL)
-       if (!setjmp (to_top_level))
+       if (!SET_TOP_LEVEL ())
          exec_file_command (execarg, !batch);
       if (symarg != NULL)
-       if (!setjmp (to_top_level))
+       if (!SET_TOP_LEVEL ())
          symbol_file_command (symarg, 0);
     }
   do_cleanups (ALL_CLEANUPS);
@@ -787,14 +837,14 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   warning_pre_print = "\nwarning: ";
 
   if (corearg != NULL)
-    if (!setjmp (to_top_level))
+    if (!SET_TOP_LEVEL ())
       core_file_command (corearg, !batch);
-    else if (isdigit (corearg[0]) && !setjmp (to_top_level))
+    else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ())
       attach_command (corearg, !batch);
   do_cleanups (ALL_CLEANUPS);
 
   if (ttyarg != NULL)
-    if (!setjmp (to_top_level))
+    if (!SET_TOP_LEVEL ())
       tty_command (ttyarg, !batch);
   do_cleanups (ALL_CLEANUPS);
 
@@ -813,14 +863,14 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
       || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
     if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0)
       {
-       if (!setjmp (to_top_level))
+       if (!SET_TOP_LEVEL ())
          source_command (gdbinit, 0);
       }
   do_cleanups (ALL_CLEANUPS);
 
   for (i = 0; i < ncmd; i++)
     {
-      if (!setjmp (to_top_level))
+      if (!SET_TOP_LEVEL ())
        {
          if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
            read_command_file (stdin);
@@ -832,7 +882,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
   free ((PTR)cmdarg);
 
   /* Read in the old history after all the command files have been read. */
-  initialize_history();
+  init_history();
 
   if (batch)
     {
@@ -851,7 +901,7 @@ GDB manual (available as on-line info or a printed manual).\n", stderr);
 
   while (1)
     {
-      if (!setjmp (to_top_level))
+      if (!SET_TOP_LEVEL ())
        {
          do_cleanups (ALL_CLEANUPS);           /* Do complete cleanup */
          command_loop ();
@@ -898,7 +948,6 @@ execute_command (p, from_tty)
      int from_tty;
 {
   register struct cmd_list_element *c;
-  register struct command_line *cmdlines;
   register enum language flang;
   static int warned = 0;
 
@@ -1099,6 +1148,48 @@ noop_completer (text)
   return NULL;
 }
 
+/* Complete on filenames.  */
+/* FIXME: This would be a lot more useful if the word breaks got set
+   to not include '/'.  Probably best to make it up to each completer
+   to do its own word breaking.  */
+char **
+filename_completer (text)
+     char *text;
+{
+  /* From readline.  */
+  extern char *filename_completion_function ();
+  int subsequent_name;
+  char **return_val;
+  int return_val_used;
+  int return_val_alloced;
+
+  return_val_used = 0;
+  /* Small for testing.  */
+  return_val_alloced = 1;
+  return_val = (char **) xmalloc (return_val_alloced * sizeof (char *));
+
+  subsequent_name = 0;
+  while (1)
+    {
+      char *p;
+      p = filename_completion_function (text, subsequent_name);
+      if (return_val_used >= return_val_alloced)
+       {
+         return_val_alloced *= 2;
+         return_val =
+           (char **) xrealloc (return_val,
+                               return_val_alloced * sizeof (char *));
+       }
+      /* The string itself has already been stored in newly malloc'd space
+        for us by filename_completion_function.  */
+      return_val[return_val_used++] = p;
+      if (p == NULL)
+       break;
+      subsequent_name = 1;
+    }
+  return return_val;
+}
+
 /* Generate symbol names one by one for the completer.  Each time we are
    called return another potential completion to the caller.
 
@@ -1151,6 +1242,11 @@ symbol_completion_function (text, matches)
         special word break set for command strings, which leaves out the
         '-' character used in some commands. */
 
+      /* FIXME: Using rl_completer_word_break_characters is the wrong
+        approach, because "show foo-bar<TAB>" won't know to use the
+        new set until too late.  Better approach is to do the word breaking
+        ourself.  */
+
       rl_completer_word_break_characters =
          gdb_completer_word_break_characters;
 
@@ -1455,7 +1551,7 @@ command_line_input (prrompt, repeat)
   }
 
 #ifdef STOP_SIGNAL
-  signal (SIGTSTP, SIG_DFL);
+  signal (STOP_SIGNAL, SIG_DFL);
 #endif
   immediate_quit--;
 
@@ -1768,7 +1864,7 @@ define_command (comname, from_tty)
 
   /* Look it up, and verify that we got an exact match.  */
   c = lookup_cmd (&tem, cmdlist, "", -1, 1);
-  if (c && 0 != strcmp (comname, c->name))
+  if (c && !STREQ (comname, c->name))
     c = 0;
     
   if (c)
@@ -1790,7 +1886,7 @@ define_command (comname, from_tty)
       /* Look up cmd it hooks, and verify that we got an exact match.  */
       tem = comname+HOOK_LEN;
       hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
-      if (hookc && 0 != strcmp (comname+HOOK_LEN, hookc->name))
+      if (hookc && !STREQ (comname+HOOK_LEN, hookc->name))
        hookc = 0;
       if (!hookc)
        {
@@ -1894,8 +1990,14 @@ print_gdb_version (stream)
   FILE *stream;
 {
   fprintf_filtered (stream, "\
-GDB %s, Copyright 1992 Free Software Foundation, Inc.",
-         version);
+GDB %s (%s", version, host_canonical);
+
+  if (strcmp(host_canonical, target_canonical))
+    fprintf_filtered (stream, " --target %s", target_canonical);
+
+  fprintf_filtered (stream, "), ");
+  wrap_here("");
+  fprintf_filtered (stream, "Copyright 1993 Free Software Foundation, Inc.");
 }
 
 /* ARGSUSED */
@@ -1927,15 +2029,20 @@ quit_command (args, from_tty)
 {
   if (inferior_pid != 0 && target_has_execution)
     {
-      if (query ("The program is running.  Quit anyway? "))
+      if (attach_flag)
        {
-         if (attach_flag)
+         if (query ("The program is running.  Quit anyway (and detach it)? "))
            target_detach (args, from_tty);
          else
-           target_kill ();
+           error ("Not confirmed.");
        }
       else
-       error ("Not confirmed.");
+       {
+         if (query ("The program is running.  Quit anyway (and kill it)? "))
+           target_kill ();
+         else
+           error ("Not confirmed.");
+       }
     }
   /* Save the history information if it is appropriate to do so.  */
   if (write_history_p && history_filename)
@@ -1961,7 +2068,7 @@ pwd_command (args, from_tty)
   if (args) error ("The \"pwd\" command does not take an argument: %s", args);
   getcwd (dirbuf, sizeof (dirbuf));
 
-  if (strcmp (dirbuf, current_directory))
+  if (!STREQ (dirbuf, current_directory))
     printf ("Working directory %s\n (canonically %s).\n",
            current_directory, dirbuf);
   else
@@ -2044,14 +2151,15 @@ source_command (args, from_tty)
   struct cleanup *cleanups;
   char *file = args;
 
-  if (file == 0)
-    /* Let source without arguments read .gdbinit.  */
-    file = gdbinit;
+  if (file == NULL)
+    {
+      error ("source command requires pathname of file to source.");
+    }
 
   file = tilde_expand (file);
   make_cleanup (free, file);
 
-  stream = fopen (file, "r");
+  stream = fopen (file, FOPEN_RT);
   if (stream == 0)
     perror_with_name (file);
 
@@ -2072,7 +2180,7 @@ echo_command (text, from_tty)
   register int c;
 
   if (text)
-    while (c = *p++)
+    while ((c = *p++) != '\0')
       {
        if (c == '\\')
          {
@@ -2185,13 +2293,13 @@ set_history_size_command (args, from_tty, c)
      int from_tty;
      struct cmd_list_element *c;
 {
-  if (history_size == UINT_MAX)
+  if (history_size == INT_MAX)
     unstifle_history ();
   else if (history_size >= 0)
     stifle_history (history_size);
   else
     {
-      history_size = UINT_MAX;
+      history_size = INT_MAX;
       error ("History size must be non-negative");
     }
 }
@@ -2248,6 +2356,7 @@ int signo;
 {
   /* This message is based on ANSI C, section 4.7.  Note that integer
      divide by zero causes this, so "float" is a misnomer.  */
+  signal (SIGFPE, float_handler);
   error ("Erroneous arithmetic operation.");
 }
 
@@ -2260,7 +2369,7 @@ batch_mode ()
 
 \f
 static void
-initialize_cmd_lists ()
+init_cmd_lists ()
 {
   cmdlist = NULL;
   infolist = NULL;
@@ -2292,7 +2401,7 @@ initialize_cmd_lists ()
  */
 
 static void
-initialize_history()
+init_history()
 {
   char *tmpenv;
 
@@ -2317,7 +2426,7 @@ initialize_history()
 }
 
 static void
-initialize_main ()
+init_main ()
 {
   struct cmd_list_element *c;
   
@@ -2369,10 +2478,11 @@ The commands below can be used to select other frames by number or address.",
 
   add_com ("pwd", class_files, pwd_command,
           "Print working directory.  This is used for your program as well.");
-  add_com ("cd", class_files, cd_command,
+  c = add_cmd ("cd", class_files, cd_command,
           "Set working directory to DIR for debugger and program being debugged.\n\
 The change does not take effect for the program being debugged\n\
-until the next time it is started.");
+until the next time it is started.", &cmdlist);
+  c->completer = filename_completer;
 
   add_show_from_set
     (add_set_cmd ("prompt", class_support, var_string, (char *)&prompt,
@@ -2400,17 +2510,18 @@ Use the \"document\" command to give documentation for the new command.\n\
 Commands defined in this way do not take arguments.");
 
 #ifdef __STDC__
-  add_com ("source", class_support, source_command,
+  c = add_cmd ("source", class_support, source_command,
           "Read commands from a file named FILE.\n\
 Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\
-when gdb is started.");
+when gdb is started.", &cmdlist);
 #else
   /* Punt file name, we can't help it easily.  */
-  add_com ("source", class_support, source_command,
+  c = add_cmd ("source", class_support, source_command,
           "Read commands from a file named FILE.\n\
 Note that the file \".gdbinit\" is read automatically in this way\n\
-when gdb is started.");
+when gdb is started.", &cmdlist);
 #endif
+  c->completer = filename_completer;
 
   add_com ("quit", class_support, quit_command, "Exit gdb.");
   add_com ("help", class_support, help_command, "Print list of commands.");
@@ -2453,7 +2564,7 @@ Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\
 Without an argument, saving is enabled.", &sethistlist),
      &showhistlist);
 
-  c = add_set_cmd ("size", no_class, var_uinteger, (char *)&history_size,
+  c = add_set_cmd ("size", no_class, var_integer, (char *)&history_size,
                   "Set the size of the command history, \n\
 ie. the number of previous commands to keep a record of.", &sethistlist);
   add_show_from_set (c, &showhistlist);
This page took 0.030508 seconds and 4 git commands to generate.