Perform all tests in callfuncs.exp with and without C function prototypes
[deliverable/binutils-gdb.git] / gdb / utils.c
index 86df1c7f6a4db6366e644ed667894866b71d0cb9..3915b58c047499ada2bbdf8ede3174a06316e5ac 100644 (file)
 
 #include "defs.h"
 #include "dyn-string.h"
-#include "gdb_assert.h"
 #include <ctype.h>
-#include <string.h>
 #include "gdb_wait.h"
 #include "event-top.h"
-#include "exceptions.h"
 #include "gdbthread.h"
 #include "fnmatch.h"
 #include "gdb_bfd.h"
@@ -522,33 +519,18 @@ vwarning (const char *string, va_list args)
     (*deprecated_warning_hook) (string, args);
   else
     {
-      target_terminal_ours ();
-      wrap_here ("");          /* Force out any buffered output.  */
+      if (target_supports_terminal_ours ())
+       target_terminal_ours ();
+      if (filtered_printing_initialized ())
+       wrap_here ("");         /* Force out any buffered output.  */
       gdb_flush (gdb_stdout);
       if (warning_pre_print)
        fputs_unfiltered (warning_pre_print, gdb_stderr);
       vfprintf_unfiltered (gdb_stderr, string, args);
       fprintf_unfiltered (gdb_stderr, "\n");
-      va_end (args);
     }
 }
 
-/* Print a warning message.
-   The first argument STRING is the warning message, used as a fprintf string,
-   and the remaining args are passed as arguments to it.
-   The primary difference between warnings and errors is that a warning
-   does not force the return to command level.  */
-
-void
-warning (const char *string, ...)
-{
-  va_list args;
-
-  va_start (args, string);
-  vwarning (string, args);
-  va_end (args);
-}
-
 /* Print an error message and return to command level.
    The first argument STRING is the error message, used as a fprintf string,
    and the remaining args are passed as arguments to it.  */
@@ -560,47 +542,30 @@ verror (const char *string, va_list args)
 }
 
 void
-error (const char *string, ...)
+error_stream (struct ui_file *stream)
 {
-  va_list args;
-
-  va_start (args, string);
-  throw_verror (GENERIC_ERROR, string, args);
-  va_end (args);
-}
-
-/* Print an error message and quit.
-   The first argument STRING is the error message, used as a fprintf string,
-   and the remaining args are passed as arguments to it.  */
+  char *message = ui_file_xstrdup (stream, NULL);
 
-void
-vfatal (const char *string, va_list args)
-{
-  throw_vfatal (string, args);
+  make_cleanup (xfree, message);
+  error (("%s"), message);
 }
 
-void
-fatal (const char *string, ...)
-{
-  va_list args;
-
-  va_start (args, string);
-  throw_vfatal (string, args);
-  va_end (args);
-}
+/* Emit a message and abort.  */
 
-void
-error_stream (struct ui_file *stream)
+static void ATTRIBUTE_NORETURN
+abort_with_message (const char *msg)
 {
-  char *message = ui_file_xstrdup (stream, NULL);
+  if (gdb_stderr == NULL)
+    fputs (msg, stderr);
+  else
+    fputs_unfiltered (msg, gdb_stderr);
 
-  make_cleanup (xfree, message);
-  error (("%s"), message);
+  abort ();            /* NOTE: GDB has only three calls to abort().  */
 }
 
 /* Dump core trying to increase the core soft limit to hard limit first.  */
 
-static void
+void
 dump_core (void)
 {
 #ifdef HAVE_SETRLIMIT
@@ -613,10 +578,12 @@ dump_core (void)
 }
 
 /* Check whether GDB will be able to dump core using the dump_core
-   function.  */
+   function.  Returns zero if GDB cannot or should not dump core.
+   If LIMIT_KIND is LIMIT_CUR the user's soft limit will be respected.
+   If LIMIT_KIND is LIMIT_MAX only the hard limit will be respected.  */
 
-static int
-can_dump_core (const char *reason)
+int
+can_dump_core (enum resource_limit_kind limit_kind)
 {
 #ifdef HAVE_GETRLIMIT
   struct rlimit rlim;
@@ -625,19 +592,47 @@ can_dump_core (const char *reason)
   if (getrlimit (RLIMIT_CORE, &rlim) != 0)
     return 1;
 
-  if (rlim.rlim_max == 0)
+  switch (limit_kind)
     {
-      fprintf_unfiltered (gdb_stderr,
-                         _("%s\nUnable to dump core, use `ulimit -c"
-                           " unlimited' before executing GDB next time.\n"),
-                         reason);
-      return 0;
+    case LIMIT_CUR:
+      if (rlim.rlim_cur == 0)
+       return 0;
+
+    case LIMIT_MAX:
+      if (rlim.rlim_max == 0)
+       return 0;
     }
 #endif /* HAVE_GETRLIMIT */
 
   return 1;
 }
 
+/* Print a warning that we cannot dump core.  */
+
+void
+warn_cant_dump_core (const char *reason)
+{
+  fprintf_unfiltered (gdb_stderr,
+                     _("%s\nUnable to dump core, use `ulimit -c"
+                       " unlimited' before executing GDB next time.\n"),
+                     reason);
+}
+
+/* Check whether GDB will be able to dump core using the dump_core
+   function, and print a warning if we cannot.  */
+
+static int
+can_dump_core_warn (enum resource_limit_kind limit_kind,
+                   const char *reason)
+{
+  int core_dump_allowed = can_dump_core (limit_kind);
+
+  if (!core_dump_allowed)
+    warn_cant_dump_core (reason);
+
+  return core_dump_allowed;
+}
+
 /* Allow the user to configure the debugger behavior with respect to
    what to do when an internal problem is detected.  */
 
@@ -659,7 +654,9 @@ static const char *const internal_problem_modes[] =
 struct internal_problem
 {
   const char *name;
+  int user_settable_should_quit;
   const char *should_quit;
+  int user_settable_should_dump_core;
   const char *should_dump_core;
 };
 
@@ -688,8 +685,7 @@ internal_vproblem (struct internal_problem *problem,
        break;
       case 1:
        dejavu = 2;
-       fputs_unfiltered (msg, gdb_stderr);
-       abort ();       /* NOTE: GDB has only three calls to abort().  */
+       abort_with_message (msg);
       default:
        dejavu = 3;
         /* Newer GLIBC versions put the warn_unused_result attribute
@@ -703,10 +699,6 @@ internal_vproblem (struct internal_problem *problem,
       }
   }
 
-  /* Try to get the message out and at the start of a new line.  */
-  target_terminal_ours ();
-  begin_line ();
-
   /* Create a string containing the full error/warning message.  Need
      to call query with this full string, as otherwize the reason
      (error/warning) and question become separated.  Format using a
@@ -724,18 +716,32 @@ internal_vproblem (struct internal_problem *problem,
     make_cleanup (xfree, reason);
   }
 
+  /* Fall back to abort_with_message if gdb_stderr is not set up.  */
+  if (gdb_stderr == NULL)
+    {
+      fputs (reason, stderr);
+      abort_with_message ("\n");
+    }
+
+  /* Try to get the message out and at the start of a new line.  */
+  if (target_supports_terminal_ours ())
+    target_terminal_ours ();
+  if (filtered_printing_initialized ())
+    begin_line ();
+
+  /* Emit the message unless query will emit it below.  */
+  if (problem->should_quit != internal_problem_ask
+      || !confirm
+      || !filtered_printing_initialized ())
+    fprintf_unfiltered (gdb_stderr, "%s\n", reason);
+
   if (problem->should_quit == internal_problem_ask)
     {
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
         this lessens the likelihood of GDB going into an infinite
         loop.  */
-      if (!confirm)
-        {
-          /* Emit the message and quit.  */
-          fputs_unfiltered (reason, gdb_stderr);
-          fputs_unfiltered ("\n", gdb_stderr);
-          quit_p = 1;
-        }
+      if (!confirm || !filtered_printing_initialized ())
+       quit_p = 1;
       else
         quit_p = query (_("%s\nQuit this debugging session? "), reason);
     }
@@ -754,8 +760,10 @@ internal_vproblem (struct internal_problem *problem,
 
   if (problem->should_dump_core == internal_problem_ask)
     {
-      if (!can_dump_core (reason))
+      if (!can_dump_core_warn (LIMIT_MAX, reason))
        dump_core_p = 0;
+      else if (!filtered_printing_initialized ())
+       dump_core_p = 1;
       else
        {
          /* Default (yes/batch case) is to dump core.  This leaves a GDB
@@ -765,7 +773,7 @@ internal_vproblem (struct internal_problem *problem,
        }
     }
   else if (problem->should_dump_core == internal_problem_yes)
-    dump_core_p = can_dump_core (reason);
+    dump_core_p = can_dump_core_warn (LIMIT_MAX, reason);
   else if (problem->should_dump_core == internal_problem_no)
     dump_core_p = 0;
   else
@@ -794,43 +802,43 @@ internal_vproblem (struct internal_problem *problem,
 }
 
 static struct internal_problem internal_error_problem = {
-  "internal-error", internal_problem_ask, internal_problem_ask
+  "internal-error", 1, internal_problem_ask, 1, internal_problem_ask
 };
 
 void
 internal_verror (const char *file, int line, const char *fmt, va_list ap)
 {
   internal_vproblem (&internal_error_problem, file, line, fmt, ap);
-  fatal (_("Command aborted."));
+  throw_quit (_("Command aborted."));
 }
 
+static struct internal_problem internal_warning_problem = {
+  "internal-warning", 1, internal_problem_ask, 1, internal_problem_ask
+};
+
 void
-internal_error (const char *file, int line, const char *string, ...)
+internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
 {
-  va_list ap;
-
-  va_start (ap, string);
-  internal_verror (file, line, string, ap);
-  va_end (ap);
+  internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
 }
 
-static struct internal_problem internal_warning_problem = {
-  "internal-warning", internal_problem_ask, internal_problem_ask
+static struct internal_problem demangler_warning_problem = {
+  "demangler-warning", 1, internal_problem_ask, 0, internal_problem_no
 };
 
 void
-internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
+demangler_vwarning (const char *file, int line, const char *fmt, va_list ap)
 {
-  internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
+  internal_vproblem (&demangler_warning_problem, file, line, fmt, ap);
 }
 
 void
-internal_warning (const char *file, int line, const char *string, ...)
+demangler_warning (const char *file, int line, const char *string, ...)
 {
   va_list ap;
 
   va_start (ap, string);
-  internal_vwarning (file, line, string, ap);
+  demangler_vwarning (file, line, string, ap);
   va_end (ap);
 }
 
@@ -894,45 +902,51 @@ add_internal_problem_command (struct internal_problem *problem)
                          (char *) NULL),
                  0/*allow-unknown*/, &maintenance_show_cmdlist);
 
-  set_doc = xstrprintf (_("Set whether GDB should quit "
-                         "when an %s is detected"),
-                       problem->name);
-  show_doc = xstrprintf (_("Show whether GDB will quit "
-                          "when an %s is detected"),
-                        problem->name);
-  add_setshow_enum_cmd ("quit", class_maintenance,
-                       internal_problem_modes,
-                       &problem->should_quit,
-                       set_doc,
-                       show_doc,
-                       NULL, /* help_doc */
-                       NULL, /* setfunc */
-                       NULL, /* showfunc */
-                       set_cmd_list,
-                       show_cmd_list);
-
-  xfree (set_doc);
-  xfree (show_doc);
-
-  set_doc = xstrprintf (_("Set whether GDB should create a core "
-                         "file of GDB when %s is detected"),
-                       problem->name);
-  show_doc = xstrprintf (_("Show whether GDB will create a core "
-                          "file of GDB when %s is detected"),
-                        problem->name);
-  add_setshow_enum_cmd ("corefile", class_maintenance,
-                       internal_problem_modes,
-                       &problem->should_dump_core,
-                       set_doc,
-                       show_doc,
-                       NULL, /* help_doc */
-                       NULL, /* setfunc */
-                       NULL, /* showfunc */
-                       set_cmd_list,
-                       show_cmd_list);
+  if (problem->user_settable_should_quit)
+    {
+      set_doc = xstrprintf (_("Set whether GDB should quit "
+                             "when an %s is detected"),
+                           problem->name);
+      show_doc = xstrprintf (_("Show whether GDB will quit "
+                              "when an %s is detected"),
+                            problem->name);
+      add_setshow_enum_cmd ("quit", class_maintenance,
+                           internal_problem_modes,
+                           &problem->should_quit,
+                           set_doc,
+                           show_doc,
+                           NULL, /* help_doc */
+                           NULL, /* setfunc */
+                           NULL, /* showfunc */
+                           set_cmd_list,
+                           show_cmd_list);
+
+      xfree (set_doc);
+      xfree (show_doc);
+    }
 
-  xfree (set_doc);
-  xfree (show_doc);
+  if (problem->user_settable_should_dump_core)
+    {
+      set_doc = xstrprintf (_("Set whether GDB should create a core "
+                             "file of GDB when %s is detected"),
+                           problem->name);
+      show_doc = xstrprintf (_("Show whether GDB will create a core "
+                              "file of GDB when %s is detected"),
+                            problem->name);
+      add_setshow_enum_cmd ("corefile", class_maintenance,
+                           internal_problem_modes,
+                           &problem->should_dump_core,
+                           set_doc,
+                           show_doc,
+                           NULL, /* help_doc */
+                           NULL, /* setfunc */
+                           NULL, /* showfunc */
+                           set_cmd_list,
+                           show_cmd_list);
+
+      xfree (set_doc);
+      xfree (show_doc);
+    }
 }
 
 /* Return a newly allocated string, containing the PREFIX followed
@@ -1032,15 +1046,15 @@ quit (void)
 #ifdef __MSDOS__
   /* No steenking SIGINT will ever be coming our way when the
      program is resumed.  Don't lie.  */
-  fatal ("Quit");
+  throw_quit ("Quit");
 #else
   if (job_control
       /* If there is no terminal switching for this target, then we can't
          possibly get screwed by the lack of job control.  */
-      || current_target.to_terminal_ours == NULL)
-    fatal ("Quit");
+      || !target_supports_terminal_ours ())
+    throw_quit ("Quit");
   else
-    fatal ("Quit (expect signal SIGINT when the program is resumed)");
+    throw_quit ("Quit (expect signal SIGINT when the program is resumed)");
 #endif
 }
 
@@ -1502,7 +1516,13 @@ parse_escape (struct gdbarch *gdbarch, const char **string_ptr)
 /* Print the character C on STREAM as part of the contents of a literal
    string whose delimiter is QUOTER.  Note that this routine should only
    be call for printing things which are independent of the language
-   of the program being debugged.  */
+   of the program being debugged.
+
+   printchar will normally escape backslashes and instances of QUOTER. If
+   QUOTER is 0, printchar won't escape backslashes or any quoting character.
+   As a side effect, if you pass the backslash character as the QUOTER,
+   printchar will escape backslashes as usual, but not any other quoting
+   character. */
 
 static void
 printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
@@ -1545,7 +1565,7 @@ printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
     }
   else
     {
-      if (c == '\\' || c == quoter)
+      if (quoter != 0 && (c == '\\' || c == quoter))
        do_fputs ("\\", stream);
       do_fprintf (stream, "%c", c);
     }
@@ -1696,6 +1716,13 @@ init_page_info (void)
   set_width ();
 }
 
+/* Return nonzero if filtered printing is initialized.  */
+int
+filtered_printing_initialized (void)
+{
+  return wrap_buffer != NULL;
+}
+
 /* Helper for make_cleanup_restore_page_info.  */
 
 static void
@@ -1813,6 +1840,10 @@ prompt_for_continue (void)
 
   immediate_quit++;
   QUIT;
+
+  /* We'll need to handle input.  */
+  target_terminal_ours ();
+
   /* On a real operating system, the user can quit with SIGINT.
      But not on GO32.
 
@@ -3032,7 +3063,7 @@ gdb_sign_extend (LONGEST value, int bit)
 void *
 hashtab_obstack_allocate (void *data, size_t size, size_t count)
 {
-  unsigned int total = size * count;
+  size_t total = size * count;
   void *ptr = obstack_alloc ((struct obstack *) data, total);
 
   memset (ptr, 0, total);
@@ -3255,7 +3286,7 @@ gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
 /* Return ARGS parsed as a valid pid, or throw an error.  */
 
 int
-parse_pid_to_attach (char *args)
+parse_pid_to_attach (const char *args)
 {
   unsigned long pid;
   char *dummy;
@@ -3263,7 +3294,7 @@ parse_pid_to_attach (char *args)
   if (!args)
     error_no_arg (_("process-id to attach"));
 
-  dummy = args;
+  dummy = (char *) args;
   pid = strtoul (args, &dummy, 0);
   /* Some targets don't set errno on errors, grrr!  */
   if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
@@ -3523,4 +3554,5 @@ _initialize_utils (void)
 {
   add_internal_problem_command (&internal_error_problem);
   add_internal_problem_command (&internal_warning_problem);
+  add_internal_problem_command (&demangler_warning_problem);
 }
This page took 0.059072 seconds and 4 git commands to generate.