2010-05-16 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / utils.c
index 26d79334696133415e0ad3fe41896f406beca9db..472cf471da77276bc66e2d6321cddb3183ec98bf 100644 (file)
@@ -1,8 +1,8 @@
 /* General utility routines for GDB, the GNU debugger.
 
    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-   Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -26,6 +26,9 @@
 #include "event-top.h"
 #include "exceptions.h"
 #include "gdbthread.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
 
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_get_command_dimension.   */
@@ -55,6 +58,7 @@
 #include "gdb_obstack.h"
 #include "gdbcore.h"
 #include "top.h"
+#include "main.h"
 
 #include "inferior.h"          /* for signed_pointer_to_address */
 
 #include <sys/time.h>
 #include <time.h>
 
+#include "gdb_usleep.h"
+#include "interps.h"
+
 #if !HAVE_DECL_MALLOC
-extern PTR malloc ();          /* OK: PTR */
+extern PTR malloc ();          /* ARI: PTR */
 #endif
 #if !HAVE_DECL_REALLOC
-extern PTR realloc ();         /* OK: PTR */
+extern PTR realloc ();         /* ARI: PTR */
 #endif
 #if !HAVE_DECL_FREE
 extern void free ();
@@ -85,7 +92,7 @@ void (*deprecated_error_begin_hook) (void);
 /* Prototypes for local functions */
 
 static void vfprintf_maybe_filtered (struct ui_file *, const char *,
-                                    va_list, int) ATTR_FORMAT (printf, 2, 0);
+                                    va_list, int) ATTRIBUTE_PRINTF (2, 0);
 
 static void fputs_maybe_filtered (const char *, struct ui_file *, int);
 
@@ -243,6 +250,7 @@ static void
 do_close_cleanup (void *arg)
 {
   int *fd = arg;
+
   close (*fd);
 }
 
@@ -250,6 +258,7 @@ struct cleanup *
 make_cleanup_close (int fd)
 {
   int *saved_fd = xmalloc (sizeof (fd));
+
   *saved_fd = fd;
   return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
 }
@@ -260,7 +269,8 @@ static void
 do_fclose_cleanup (void *arg)
 {
   FILE *file = arg;
-  fclose (arg);
+
+  fclose (file);
 }
 
 /* Return a new cleanup that closes FILE.  */
@@ -271,6 +281,24 @@ make_cleanup_fclose (FILE *file)
   return make_cleanup (do_fclose_cleanup, file);
 }
 
+/* Helper function which does the work for make_cleanup_obstack_free.  */
+
+static void
+do_obstack_free (void *arg)
+{
+  struct obstack *ob = arg;
+
+  obstack_free (ob, NULL);
+}
+
+/* Return a new cleanup that frees OBSTACK.  */
+
+struct cleanup *
+make_cleanup_obstack_free (struct obstack *obstack)
+{
+  return make_cleanup (do_obstack_free, obstack);
+}
+
 static void
 do_ui_file_delete (void *arg)
 {
@@ -305,6 +333,7 @@ static void
 restore_integer (void *p)
 {
   struct restore_integer_closure *closure = p;
+
   *(closure->variable) = closure->value;
 }
 
@@ -315,6 +344,7 @@ make_cleanup_restore_integer (int *variable)
 {
   struct restore_integer_closure *c =
     xmalloc (sizeof (struct restore_integer_closure));
+
   c->variable = variable;
   c->value = *variable;
 
@@ -366,6 +396,7 @@ do_my_cleanups (struct cleanup **pmy_chain,
                struct cleanup *old_chain)
 {
   struct cleanup *ptr;
+
   while ((ptr = *pmy_chain) != old_chain)
     {
       *pmy_chain = ptr->next;  /* Do this first incase recursion */
@@ -396,6 +427,7 @@ discard_my_cleanups (struct cleanup **pmy_chain,
                     struct cleanup *old_chain)
 {
   struct cleanup *ptr;
+
   while ((ptr = *pmy_chain) != old_chain)
     {
       *pmy_chain = ptr->next;
@@ -458,6 +490,7 @@ void
 free_current_contents (void *ptr)
 {
   void **location = ptr;
+
   if (location == NULL)
     internal_error (__FILE__, __LINE__,
                    _("free_current_contents: NULL pointer"));
@@ -505,10 +538,64 @@ add_continuation (struct thread_info *thread,
   thread->continuations = (struct continuation *) as_cleanup;
 }
 
+/* Add a continuation to the continuation list of INFERIOR.  The new
+   continuation will be added at the front.  */
+
+void
+add_inferior_continuation (void (*continuation_hook) (void *), void *args,
+                          void (*continuation_free_args) (void *))
+{
+  struct inferior *inf = current_inferior ();
+  struct cleanup *as_cleanup = &inf->continuations->base;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
+
+  make_my_cleanup2 (&as_cleanup,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
+
+  inf->continuations = (struct continuation *) as_cleanup;
+}
+
+/* Do all continuations of the current inferior.  */
+
+void
+do_all_inferior_continuations (void)
+{
+  struct cleanup *as_cleanup;
+  struct inferior *inf = current_inferior ();
+
+  if (inf->continuations == NULL)
+    return;
+
+  /* Copy the list header into another pointer, and set the global
+     list header to null, so that the global list can change as a side
+     effect of invoking the continuations and the processing of the
+     preexisting continuations will not be affected.  */
+
+  as_cleanup = &inf->continuations->base;
+  inf->continuations = NULL;
+
+  /* Work now on the list we have set aside.  */
+  do_my_cleanups (&as_cleanup, NULL);
+}
+
+/* Get rid of all the inferior-wide continuations of INF.  */
+
+void
+discard_all_inferior_continuations (struct inferior *inf)
+{
+  struct cleanup *continuation_ptr = &inf->continuations->base;
+
+  discard_my_cleanups (&continuation_ptr, NULL);
+  inf->continuations = NULL;
+}
+
 static void
 restore_thread_cleanup (void *arg)
 {
   ptid_t *ptid_p = arg;
+
   switch_to_thread (*ptid_p);
 }
 
@@ -589,6 +676,7 @@ discard_all_continuations_thread_callback (struct thread_info *thread,
                                           void *data)
 {
   struct cleanup *continuation_ptr = &thread->continuations->base;
+
   discard_my_cleanups (&continuation_ptr, NULL);
   thread->continuations = NULL;
   return 0;
@@ -665,6 +753,7 @@ discard_all_intermediate_continuations_thread_callback (struct thread_info *thre
                                                        void *data)
 {
   struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
+
   discard_my_cleanups (&continuation_ptr, NULL);
   thread->intermediate_continuations = NULL;
   return 0;
@@ -720,6 +809,7 @@ void
 warning (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   vwarning (string, args);
   va_end (args);
@@ -729,16 +819,17 @@ warning (const char *string, ...)
    The first argument STRING is the error message, used as a fprintf string,
    and the remaining args are passed as arguments to it.  */
 
-NORETURN void
+void
 verror (const char *string, va_list args)
 {
   throw_verror (GENERIC_ERROR, string, args);
 }
 
-NORETURN void
+void
 error (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_verror (GENERIC_ERROR, string, args);
   va_end (args);
@@ -748,30 +839,83 @@ error (const char *string, ...)
    The first argument STRING is the error message, used as a fprintf string,
    and the remaining args are passed as arguments to it.  */
 
-NORETURN void
+void
 vfatal (const char *string, va_list args)
 {
   throw_vfatal (string, args);
 }
 
-NORETURN void
+void
 fatal (const char *string, ...)
 {
   va_list args;
+
   va_start (args, string);
   throw_vfatal (string, args);
   va_end (args);
 }
 
-NORETURN void
+void
 error_stream (struct ui_file *stream)
 {
-  long len;
-  char *message = ui_file_xstrdup (stream, &len);
+  char *message = ui_file_xstrdup (stream, NULL);
+
   make_cleanup (xfree, message);
   error (("%s"), message);
 }
 
+/* Dump core trying to increase the core soft limit to hard limit first.  */
+
+static void
+dump_core (void)
+{
+#ifdef HAVE_SETRLIMIT
+  struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
+
+  setrlimit (RLIMIT_CORE, &rlim);
+#endif /* HAVE_SETRLIMIT */
+
+  abort ();            /* NOTE: GDB has only three calls to abort().  */
+}
+
+/* Check whether GDB will be able to dump core using the dump_core function.  */
+
+static int
+can_dump_core (const char *reason)
+{
+#ifdef HAVE_GETRLIMIT
+  struct rlimit rlim;
+
+  /* Be quiet and assume we can dump if an error is returned.  */
+  if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+    return 1;
+
+  if (rlim.rlim_max == 0)
+    {
+      fprintf_unfiltered (gdb_stderr,
+                         _("%s\nUnable to dump core, use `ulimit -c unlimited'"
+                           " before executing GDB next time.\n"), reason);
+      return 0;
+    }
+#endif /* HAVE_GETRLIMIT */
+
+  return 1;
+}
+
+/* Allow the user to configure the debugger behavior with respect to
+   what to do when an internal problem is detected.  */
+
+const char internal_problem_ask[] = "ask";
+const char internal_problem_yes[] = "yes";
+const char internal_problem_no[] = "no";
+static const char *internal_problem_modes[] =
+{
+  internal_problem_ask,
+  internal_problem_yes,
+  internal_problem_no,
+  NULL
+};
+
 /* Print a message reporting an internal error/warning. Ask the user
    if they want to continue, dump core, or just exit.  Return
    something to indicate a quit.  */
@@ -779,17 +923,15 @@ error_stream (struct ui_file *stream)
 struct internal_problem
 {
   const char *name;
-  /* FIXME: cagney/2002-08-15: There should be ``maint set/show''
-     commands available for controlling these variables.  */
-  enum auto_boolean should_quit;
-  enum auto_boolean should_dump_core;
+  const char *should_quit;
+  const char *should_dump_core;
 };
 
 /* Report a problem, internal to GDB, to the user.  Once the problem
    has been reported, and assuming GDB didn't quit, the caller can
    either allow execution to resume or throw an error.  */
 
-static void ATTR_FORMAT (printf, 4, 0)
+static void ATTRIBUTE_PRINTF (4, 0)
 internal_vproblem (struct internal_problem *problem,
                   const char *file, int line, const char *fmt, va_list ap)
 {
@@ -801,6 +943,7 @@ internal_vproblem (struct internal_problem *problem,
   /* Don't allow infinite error/warning recursion.  */
   {
     static char msg[] = "Recursive internal problem.\n";
+
     switch (dejavu)
       {
       case 0:
@@ -812,7 +955,13 @@ internal_vproblem (struct internal_problem *problem,
        abort ();       /* NOTE: GDB has only three calls to abort().  */
       default:
        dejavu = 3;
-       write (STDERR_FILENO, msg, sizeof (msg));
+        /* Newer GLIBC versions put the warn_unused_result attribute
+           on write, but this is one of those rare cases where
+           ignoring the return value is correct.  Casting to (void)
+           does not fix this problem.  This is the solution suggested
+           at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509.  */
+       if (write (STDERR_FILENO, msg, sizeof (msg)) != sizeof (msg))
+          abort (); /* NOTE: GDB has only three calls to abort().  */
        exit (1);
       }
   }
@@ -828,6 +977,7 @@ internal_vproblem (struct internal_problem *problem,
      so that the user knows that they are living on the edge.  */
   {
     char *msg;
+
     msg = xstrvprintf (fmt, ap);
     reason = xstrprintf ("\
 %s:%d: %s: %s\n\
@@ -837,47 +987,51 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
     make_cleanup (xfree, reason);
   }
 
-  switch (problem->should_quit)
+  if (problem->should_quit == internal_problem_ask)
     {
-    case AUTO_BOOLEAN_AUTO:
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
-         this lessens the likelhood of GDB going into an infinate
-         loop.  */
-      quit_p = query (_("%s\nQuit this debugging session? "), reason);
-      break;
-    case AUTO_BOOLEAN_TRUE:
-      quit_p = 1;
-      break;
-    case AUTO_BOOLEAN_FALSE:
-      quit_p = 0;
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
+        this lessens the likelihood of GDB going into an infinite
+        loop.  */
+      if (caution == 0)
+        {
+          /* Emit the message and quit.  */
+          fputs_unfiltered (reason, gdb_stderr);
+          fputs_unfiltered ("\n", gdb_stderr);
+          quit_p = 1;
+        }
+      else
+        quit_p = query (_("%s\nQuit this debugging session? "), reason);
     }
+  else if (problem->should_quit == internal_problem_yes)
+    quit_p = 1;
+  else if (problem->should_quit == internal_problem_no)
+    quit_p = 0;
+  else
+    internal_error (__FILE__, __LINE__, _("bad switch"));
 
-  switch (problem->should_dump_core)
+  if (problem->should_dump_core == internal_problem_ask)
     {
-    case AUTO_BOOLEAN_AUTO:
-      /* Default (yes/batch case) is to dump core.  This leaves a GDB
-         `dropping' so that it is easier to see that something went
-         wrong in GDB.  */
-      dump_core_p = query (_("%s\nCreate a core file of GDB? "), reason);
-      break;
-      break;
-    case AUTO_BOOLEAN_TRUE:
-      dump_core_p = 1;
-      break;
-    case AUTO_BOOLEAN_FALSE:
-      dump_core_p = 0;
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
+      if (!can_dump_core (reason))
+       dump_core_p = 0;
+      else
+       {
+         /* Default (yes/batch case) is to dump core.  This leaves a GDB
+            `dropping' so that it is easier to see that something went
+            wrong in GDB.  */
+         dump_core_p = query (_("%s\nCreate a core file of GDB? "), reason);
+       }
     }
+  else if (problem->should_dump_core == internal_problem_yes)
+    dump_core_p = can_dump_core (reason);
+  else if (problem->should_dump_core == internal_problem_no)
+    dump_core_p = 0;
+  else
+    internal_error (__FILE__, __LINE__, _("bad switch"));
 
   if (quit_p)
     {
       if (dump_core_p)
-       abort ();               /* NOTE: GDB has only three calls to abort().  */
+       dump_core ();
       else
        exit (1);
     }
@@ -887,7 +1041,7 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
        {
 #ifdef HAVE_WORKING_FORK
          if (fork () == 0)
-           abort ();           /* NOTE: GDB has only three calls to abort().  */
+           dump_core ();
 #endif
        }
     }
@@ -896,27 +1050,28 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
 }
 
 static struct internal_problem internal_error_problem = {
-  "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+  "internal-error", internal_problem_ask, internal_problem_ask
 };
 
-NORETURN void
+void
 internal_verror (const char *file, int line, const char *fmt, va_list ap)
 {
   internal_vproblem (&internal_error_problem, file, line, fmt, ap);
   deprecated_throw_reason (RETURN_ERROR);
 }
 
-NORETURN void
+void
 internal_error (const char *file, int line, const char *string, ...)
 {
   va_list ap;
+
   va_start (ap, string);
   internal_verror (file, line, string, ap);
   va_end (ap);
 }
 
 static struct internal_problem internal_warning_problem = {
-  "internal-warning", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+  "internal-warning", internal_problem_ask, internal_problem_ask
 };
 
 void
@@ -929,16 +1084,118 @@ void
 internal_warning (const char *file, int line, const char *string, ...)
 {
   va_list ap;
+
   va_start (ap, string);
   internal_vwarning (file, line, string, ap);
   va_end (ap);
 }
 
+/* Dummy functions to keep add_prefix_cmd happy.  */
+
+static void
+set_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+/* When GDB reports an internal problem (error or warning) it gives
+   the user the opportunity to quit GDB and/or create a core file of
+   the current debug session.  This function registers a few commands
+   that make it possible to specify that GDB should always or never
+   quit or create a core file, without asking.  The commands look
+   like:
+
+   maint set PROBLEM-NAME quit ask|yes|no
+   maint show PROBLEM-NAME quit
+   maint set PROBLEM-NAME corefile ask|yes|no
+   maint show PROBLEM-NAME corefile
+
+   Where PROBLEM-NAME is currently "internal-error" or
+   "internal-warning".  */
+
+static void
+add_internal_problem_command (struct internal_problem *problem)
+{
+  struct cmd_list_element **set_cmd_list;
+  struct cmd_list_element **show_cmd_list;
+  char *set_doc;
+  char *show_doc;
+
+  set_cmd_list = xmalloc (sizeof (*set_cmd_list));
+  show_cmd_list = xmalloc (sizeof (*set_cmd_list));
+  *set_cmd_list = NULL;
+  *show_cmd_list = NULL;
+
+  set_doc = xstrprintf (_("Configure what GDB does when %s is detected."),
+                       problem->name);
+
+  show_doc = xstrprintf (_("Show what GDB does when %s is detected."),
+                        problem->name);
+
+  add_prefix_cmd ((char*) problem->name,
+                 class_maintenance, set_internal_problem_cmd, set_doc,
+                 set_cmd_list,
+                 concat ("maintenance set ", problem->name, " ",
+                         (char *) NULL),
+                 0/*allow-unknown*/, &maintenance_set_cmdlist);
+
+  add_prefix_cmd ((char*) problem->name,
+                 class_maintenance, show_internal_problem_cmd, show_doc,
+                 show_cmd_list,
+                 concat ("maintenance show ", problem->name, " ",
+                         (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);
+
+  xfree (set_doc);
+  xfree (show_doc);
+}
+
 /* Print the system error message for errno, and also mention STRING
    as the file name for which the error was encountered.
    Then return to command level.  */
 
-NORETURN void
+void
 perror_with_name (const char *string)
 {
   char *err;
@@ -1004,7 +1261,7 @@ quit (void)
 /* Called when a memory allocation fails, with the number of bytes of
    memory requested in SIZE. */
 
-NORETURN void
+void
 nomem (long size)
 {
   if (size > 0)
@@ -1028,7 +1285,7 @@ nomem (long size)
 /* NOTE: These are declared using PTR to ensure consistency with
    "libiberty.h".  xfree() is GDB local.  */
 
-PTR                            /* OK: PTR */
+PTR                            /* ARI: PTR */
 xmalloc (size_t size)
 {
   void *val;
@@ -1038,7 +1295,7 @@ xmalloc (size_t size)
   if (size == 0)
     size = 1;
 
-  val = malloc (size);         /* OK: malloc */
+  val = malloc (size);         /* ARI: malloc */
   if (val == NULL)
     nomem (size);
 
@@ -1051,8 +1308,8 @@ xzalloc (size_t size)
   return xcalloc (1, size);
 }
 
-PTR                            /* OK: PTR */
-xrealloc (PTR ptr, size_t size)        /* OK: PTR */
+PTR                            /* ARI: PTR */
+xrealloc (PTR ptr, size_t size)        /* ARI: PTR */
 {
   void *val;
 
@@ -1062,16 +1319,16 @@ xrealloc (PTR ptr, size_t size) /* OK: PTR */
     size = 1;
 
   if (ptr != NULL)
-    val = realloc (ptr, size); /* OK: realloc */
+    val = realloc (ptr, size); /* ARI: realloc */
   else
-    val = malloc (size);               /* OK: malloc */
+    val = malloc (size);               /* ARI: malloc */
   if (val == NULL)
     nomem (size);
 
   return (val);
 }
 
-PTR                            /* OK: PTR */
+PTR                            /* ARI: PTR */
 xcalloc (size_t number, size_t size)
 {
   void *mem;
@@ -1084,7 +1341,7 @@ xcalloc (size_t number, size_t size)
       size = 1;
     }
 
-  mem = calloc (number, size);         /* OK: xcalloc */
+  mem = calloc (number, size);         /* ARI: xcalloc */
   if (mem == NULL)
     nomem (number * size);
 
@@ -1095,7 +1352,7 @@ void
 xfree (void *ptr)
 {
   if (ptr != NULL)
-    free (ptr);                /* OK: free */
+    free (ptr);                /* ARI: free */
 }
 \f
 
@@ -1107,6 +1364,7 @@ xstrprintf (const char *format, ...)
 {
   char *ret;
   va_list args;
+
   va_start (args, format);
   ret = xstrvprintf (format, args);
   va_end (args);
@@ -1117,6 +1375,7 @@ void
 xasprintf (char **ret, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   (*ret) = xstrvprintf (format, args);
   va_end (args);
@@ -1133,6 +1392,7 @@ xstrvprintf (const char *format, va_list ap)
 {
   char *ret = NULL;
   int status = vasprintf (&ret, format, ap);
+
   /* NULL is returned when there was a memory allocation problem, or
      any other error (for instance, a bad format string).  A negative
      status (the printed length) with a non-NULL buffer should never
@@ -1186,6 +1446,7 @@ char *
 savestring (const char *ptr, size_t size)
 {
   char *p = (char *) xmalloc (size + 1);
+
   memcpy (p, ptr, size);
   p[size] = 0;
   return p;
@@ -1202,12 +1463,7 @@ print_spaces (int n, struct ui_file *file)
 void
 gdb_print_host_address (const void *addr, struct ui_file *stream)
 {
-
-  /* We could use the %p conversion specifier to fprintf if we had any
-     way of knowing whether this host supports it.  But the following
-     should work on the Alpha and on 32 bit machines.  */
-
-  fprintf_filtered (stream, "0x%lx", (unsigned long) addr);
+  fprintf_filtered (stream, "%s", host_address_to_string (addr));
 }
 \f
 
@@ -1221,7 +1477,7 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
    ARGS are the arguments passed along with the CTLSTR argument to
    printf.  */
 
-static int ATTR_FORMAT (printf, 1, 0)
+static int ATTRIBUTE_PRINTF (1, 0)
 defaulted_query (const char *ctlstr, const char defchar, va_list args)
 {
   int answer;
@@ -1258,15 +1514,15 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
     }
 
   /* Automatically answer the default value if the user did not want
-     prompts.  */
-  if (! caution)
+     prompts or the command was issued with the server prefix.  */
+  if (! caution || server_command)
     return def_value;
 
   /* If input isn't coming from the user directly, just say what
-     question we're asking, and then answer "yes" automatically.  This
+     question we're asking, and then answer the default automatically.  This
      way, important error messages don't get lost when talking to GDB
      over a pipe.  */
-  if (! input_from_terminal_p ())
+  if (batch_flag || ! input_from_terminal_p ())
     {
       wrap_here ("");
       vfprintf_filtered (gdb_stdout, ctlstr, args);
@@ -1278,11 +1534,6 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
       return def_value;
     }
 
-  /* Automatically answer the default value if input is not from the user
-     directly, or if the user did not want prompts.  */
-  if (!input_from_terminal_p () || !caution)
-    return def_value;
-
   if (deprecated_query_hook)
     {
       return deprecated_query_hook (ctlstr, args);
@@ -1309,6 +1560,25 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
       gdb_flush (gdb_stdout);
 
       answer = fgetc (stdin);
+
+      /* We expect fgetc to block until a character is read.  But
+         this may not be the case if the terminal was opened with
+         the NONBLOCK flag.  In that case, if there is nothing to
+         read on stdin, fgetc returns EOF, but also sets the error
+         condition flag on stdin and errno to EAGAIN.  With a true
+         EOF, stdin's error condition flag is not set.
+
+         A situation where this behavior was observed is a pseudo
+         terminal on AIX.  */
+      while (answer == EOF && ferror (stdin) && errno == EAGAIN)
+        {
+          /* Not a real EOF.  Wait a little while and try again until
+             we read something.  */
+          clearerr (stdin);
+          gdb_usleep (10000);
+          answer = fgetc (stdin);
+        }
+
       clearerr (stdin);                /* in case of C-d */
       if (answer == EOF)       /* C-d */
        {
@@ -1403,21 +1673,33 @@ query (const char *ctlstr, ...)
   va_end (args);
 }
 
-/* Print an error message saying that we couldn't make sense of a
-   \^mumble sequence in a string or character constant.  START and END
-   indicate a substring of some larger string that contains the
-   erroneous backslash sequence, missing the initial backslash.  */
-static NORETURN int
-no_control_char_error (const char *start, const char *end)
+/* A helper for parse_escape that converts a host character to a
+   target character.  C is the host character.  If conversion is
+   possible, then the target character is stored in *TARGET_C and the
+   function returns 1.  Otherwise, the function returns 0.  */
+
+static int
+host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
 {
-  int len = end - start;
-  char *copy = alloca (end - start + 1);
+  struct obstack host_data;
+  char the_char = c;
+  struct cleanup *cleanups;
+  int result = 0;
+
+  obstack_init (&host_data);
+  cleanups = make_cleanup_obstack_free (&host_data);
 
-  memcpy (copy, start, len);
-  copy[len] = '\0';
+  convert_between_encodings (target_charset (gdbarch), host_charset (),
+                            &the_char, 1, 1, &host_data, translit_none);
+
+  if (obstack_object_size (&host_data) == 1)
+    {
+      result = 1;
+      *target_c = *(char *) obstack_base (&host_data);
+    }
 
-  error (_("There is no control character `\\%s' in the `%s' character set."),
-        copy, target_charset ());
+  do_cleanups (cleanups);
+  return result;
 }
 
 /* Parse a C escape sequence.  STRING_PTR points to a variable
@@ -1436,57 +1718,18 @@ no_control_char_error (const char *start, const char *end)
    after the zeros.  A value of 0 does not mean end of string.  */
 
 int
-parse_escape (char **string_ptr)
+parse_escape (struct gdbarch *gdbarch, char **string_ptr)
 {
-  int target_char;
+  int target_char = -2;        /* initialize to avoid GCC warnings */
   int c = *(*string_ptr)++;
-  if (c_parse_backslash (c, &target_char))
-    return target_char;
-  else
-    switch (c)
-      {
+
+  switch (c)
+    {
       case '\n':
        return -2;
       case 0:
        (*string_ptr)--;
        return 0;
-      case '^':
-       {
-         /* Remember where this escape sequence started, for reporting
-            errors.  */
-         char *sequence_start_pos = *string_ptr - 1;
-
-         c = *(*string_ptr)++;
-
-         if (c == '?')
-           {
-             /* XXXCHARSET: What is `delete' in the host character set?  */
-             c = 0177;
-
-             if (!host_char_to_target (c, &target_char))
-               error (_("There is no character corresponding to `Delete' "
-                      "in the target character set `%s'."), host_charset ());
-
-             return target_char;
-           }
-         else if (c == '\\')
-           target_char = parse_escape (string_ptr);
-         else
-           {
-             if (!host_char_to_target (c, &target_char))
-               no_control_char_error (sequence_start_pos, *string_ptr);
-           }
-
-         /* Now target_char is something like `c', and we want to find
-            its control-character equivalent.  */
-         if (!target_char_to_control_char (target_char, &target_char))
-           no_control_char_error (sequence_start_pos, *string_ptr);
-
-         return target_char;
-       }
-
-       /* XXXCHARSET: we need to use isdigit and value-of-digit
-          methods of the host character set here.  */
 
       case '0':
       case '1':
@@ -1497,16 +1740,16 @@ parse_escape (char **string_ptr)
       case '6':
       case '7':
        {
-         int i = c - '0';
+         int i = host_hex_value (c);
          int count = 0;
          while (++count < 3)
            {
              c = (**string_ptr);
-             if (c >= '0' && c <= '7')
+             if (isdigit (c) && c != '8' && c != '9')
                {
                  (*string_ptr)++;
                  i *= 8;
-                 i += c - '0';
+                 i += host_hex_value (c);
                }
              else
                {
@@ -1515,14 +1758,39 @@ parse_escape (char **string_ptr)
            }
          return i;
        }
-      default:
-       if (!host_char_to_target (c, &target_char))
-         error
-           ("The escape sequence `\%c' is equivalent to plain `%c', which"
-            " has no equivalent\n" "in the `%s' character set.", c, c,
-            target_charset ());
-       return target_char;
-      }
+
+    case 'a':
+      c = '\a';
+      break;
+    case 'b':
+      c = '\b';
+      break;
+    case 'f':
+      c = '\f';
+      break;
+    case 'n':
+      c = '\n';
+      break;
+    case 'r':
+      c = '\r';
+      break;
+    case 't':
+      c = '\t';
+      break;
+    case 'v':
+      c = '\v';
+      break;
+
+    default:
+      break;
+    }
+
+  if (!host_char_to_target (gdbarch, c, &target_char))
+    error
+      ("The escape sequence `\%c' is equivalent to plain `%c', which"
+       " has no equivalent\n" "in the `%s' character set.", c, c,
+       target_charset (gdbarch));
+  return target_char;
 }
 \f
 /* Print the character C on STREAM as part of the contents of a literal
@@ -1535,7 +1803,6 @@ printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
           void (*do_fprintf) (struct ui_file *, const char *, ...)
           ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter)
 {
-
   c &= 0xFF;                   /* Avoid sign bit follies */
 
   if (c < 0x20 ||              /* Low control chars */
@@ -1602,6 +1869,7 @@ fputstrn_filtered (const char *str, int n, int quoter,
                   struct ui_file *stream)
 {
   int i;
+
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
 }
@@ -1611,6 +1879,7 @@ fputstrn_unfiltered (const char *str, int n, int quoter,
                     struct ui_file *stream)
 {
   int i;
+
   for (i = 0; i < n; i++)
     printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
 }
@@ -1806,6 +2075,7 @@ prompt_for_continue (void)
   if (ignore)
     {
       char *p = ignore;
+
       while (*p == ' ' || *p == '\t')
        ++p;
       if (p[0] == 'q')
@@ -1969,8 +2239,11 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
     return;
 
   /* Don't do any filtering if it is disabled.  */
-  if ((stream != gdb_stdout) || !pagination_enabled
-      || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
+  if (stream != gdb_stdout
+      || !pagination_enabled
+      || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
+      || top_level_interpreter () == NULL
+      || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
     {
       fputs_unfiltered (linebuffer, stream);
       return;
@@ -2070,6 +2343,7 @@ int
 putchar_unfiltered (int c)
 {
   char buf = c;
+
   ui_file_write (gdb_stdout, &buf, 1);
   return c;
 }
@@ -2087,6 +2361,7 @@ int
 fputc_unfiltered (int c, struct ui_file *stream)
 {
   char buf = c;
+
   ui_file_write (stream, &buf, 1);
   return c;
 }
@@ -2233,13 +2508,22 @@ vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
     {
       struct timeval tm;
       char *timestamp;
+      int len, need_nl;
 
       gettimeofday (&tm, NULL);
-      timestamp = xstrprintf ("%ld:%ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+
+      len = strlen (linebuffer);
+      need_nl = (len > 0 && linebuffer[len - 1] != '\n');
+
+      timestamp = xstrprintf ("%ld:%ld %s%s",
+                             (long) tm.tv_sec, (long) tm.tv_usec,
+                             linebuffer,
+                             need_nl ? "\n": "");
       make_cleanup (xfree, timestamp);
       fputs_unfiltered (timestamp, stream);
     }
-  fputs_unfiltered (linebuffer, stream);
+  else
+    fputs_unfiltered (linebuffer, stream);
   do_cleanups (old_cleanups);
 }
 
@@ -2259,6 +2543,7 @@ void
 fprintf_filtered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (stream, format, args);
   va_end (args);
@@ -2268,6 +2553,7 @@ void
 fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (stream, format, args);
   va_end (args);
@@ -2281,6 +2567,7 @@ fprintfi_filtered (int spaces, struct ui_file *stream, const char *format,
                   ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, stream);
 
@@ -2293,6 +2580,7 @@ void
 printf_filtered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_filtered (gdb_stdout, format, args);
   va_end (args);
@@ -2303,6 +2591,7 @@ void
 printf_unfiltered (const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   vfprintf_unfiltered (gdb_stdout, format, args);
   va_end (args);
@@ -2315,6 +2604,7 @@ void
 printfi_filtered (int spaces, const char *format, ...)
 {
   va_list args;
+
   va_start (args, format);
   print_spaces_filtered (spaces, gdb_stdout);
   vfprintf_filtered (gdb_stdout, format, args);
@@ -2534,6 +2824,7 @@ int
 subset_compare (char *string_to_compare, char *template_string)
 {
   int match;
+
   if (template_string != (char *) NULL && string_to_compare != (char *) NULL
       && strlen (string_to_compare) <= strlen (template_string))
     match =
@@ -2567,8 +2858,6 @@ show_debug_timestamp (struct ui_file *file, int from_tty,
 void
 initialize_utils (void)
 {
-  struct cmd_list_element *c;
-
   add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
 Set number of characters gdb thinks are in a line."), _("\
 Show number of characters gdb thinks are in a line."), NULL,
@@ -2647,31 +2936,14 @@ get_cell (void)
 {
   static char buf[NUMCELLS][CELLSIZE];
   static int cell = 0;
+
   if (++cell >= NUMCELLS)
     cell = 0;
   return buf[cell];
 }
 
-int
-strlen_paddr (void)
-{
-  return (gdbarch_addr_bit (current_gdbarch) / 8 * 2);
-}
-
-char *
-paddr (CORE_ADDR addr)
-{
-  return phex (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
-char *
-paddr_nz (CORE_ADDR addr)
-{
-  return phex_nz (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
 const char *
-paddress (CORE_ADDR addr)
+paddress (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   /* Truncate address to the size of a target address, avoiding shifts
      larger or equal than the width of a CORE_ADDR.  The local
@@ -2682,7 +2954,7 @@ paddress (CORE_ADDR addr)
      either zero or sign extended.  Should gdbarch_address_to_pointer or
      some ADDRESS_TO_PRINTABLE() be used to do the conversion?  */
 
-  int addr_bit = gdbarch_addr_bit (current_gdbarch);
+  int addr_bit = gdbarch_addr_bit (gdbarch);
 
   if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
     addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
@@ -2696,8 +2968,8 @@ decimal2str (char *sign, ULONGEST addr, int width)
      about the real size of addr as the above does? */
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (1000 * 1000 * 1000);
@@ -2737,8 +3009,8 @@ octal2str (ULONGEST addr, int width)
 {
   unsigned long temp[3];
   char *str = get_cell ();
-
   int i = 0;
+
   do
     {
       temp[i] = addr % (0100000 * 0100000);
@@ -2832,6 +3104,7 @@ phex_nz (ULONGEST l, int sizeof_l)
     case 8:
       {
        unsigned long high = (unsigned long) (l >> thirty_two);
+
        str = get_cell ();
        if (high == 0)
          xsnprintf (str, CELLSIZE, "%lx",
@@ -2863,6 +3136,7 @@ char *
 hex_string (LONGEST num)
 {
   char *result = get_cell ();
+
   xsnprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
   return result;
 }
@@ -2907,6 +3181,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 16:
       {
        char *result;
+
        if (width == 0)
          result = hex_string (val);
        else
@@ -2925,6 +3200,7 @@ int_string (LONGEST val, int radix, int is_signed, int width,
     case 8:
       {
        char *result = octal2str (val, width);
+
        if (use_c_format || val == 0)
          return result;
        else
@@ -2941,6 +3217,7 @@ const char *
 core_addr_to_string (const CORE_ADDR addr)
 {
   char *str = get_cell ();
+
   strcpy (str, "0x");
   strcat (str, phex (addr, sizeof (addr)));
   return str;
@@ -2950,6 +3227,7 @@ const char *
 core_addr_to_string_nz (const CORE_ADDR addr)
 {
   char *str = get_cell ();
+
   strcpy (str, "0x");
   strcat (str, phex_nz (addr, sizeof (addr)));
   return str;
@@ -2959,13 +3237,13 @@ core_addr_to_string_nz (const CORE_ADDR addr)
 CORE_ADDR
 string_to_core_addr (const char *my_string)
 {
-  int addr_bit = gdbarch_addr_bit (current_gdbarch);
   CORE_ADDR addr = 0;
 
   if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
     {
       /* Assume that it is in hex.  */
       int i;
+
       for (i = 2; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -2975,22 +3253,12 @@ string_to_core_addr (const char *my_string)
          else
            error (_("invalid hex \"%s\""), my_string);
        }
-
-      /* Not very modular, but if the executable format expects
-         addresses to be sign-extended, then do so if the address was
-         specified with only 32 significant bits.  Really this should
-         be determined by the target architecture, not by the object
-         file.  */
-      if (i - 2 == addr_bit / 4
-         && exec_bfd
-         && bfd_get_sign_extend_vma (exec_bfd))
-       addr = (addr ^ ((CORE_ADDR) 1 << (addr_bit - 1)))
-              - ((CORE_ADDR) 1 << (addr_bit - 1));
     }
   else
     {
       /* Assume that it is in decimal.  */
       int i;
+
       for (i = 0; my_string[i] != '\0'; i++)
        {
          if (isdigit (my_string[i]))
@@ -3007,7 +3275,8 @@ const char *
 host_address_to_string (const void *addr)
 {
   char *str = get_cell ();
-  sprintf (str, "0x%lx", (unsigned long) addr);
+
+  xsnprintf (str, CELLSIZE, "0x%s", phex_nz ((uintptr_t) addr, sizeof (addr)));
   return str;
 }
 
@@ -3029,6 +3298,7 @@ gdb_realpath (const char *filename)
 # endif
 # if defined (USE_REALPATH)
     const char *rp = realpath (filename, buf);
+
     if (rp == NULL)
       rp = filename;
     return xstrdup (rp);
@@ -3042,6 +3312,7 @@ gdb_realpath (const char *filename)
 #if defined(HAVE_CANONICALIZE_FILE_NAME)
   {
     char *rp = canonicalize_file_name (filename);
+
     if (rp == NULL)
       return xstrdup (filename);
     else
@@ -3069,11 +3340,13 @@ gdb_realpath (const char *filename)
   {
     /* Find out the max path size.  */
     long path_max = pathconf ("/", _PC_PATH_MAX);
+
     if (path_max > 0)
       {
        /* PATH_MAX is bounded.  */
        char *buf = alloca (path_max);
        char *rp = realpath (filename, buf);
+
        return xstrdup (rp ? rp : filename);
       }
   }
@@ -3121,9 +3394,9 @@ xfullpath (const char *filename)
      directory separator, avoid doubling it.  */
   real_path = gdb_realpath (dir_name);
   if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
-    result = concat (real_path, base_name, (char *)NULL);
+    result = concat (real_path, base_name, (char *) NULL);
   else
-    result = concat (real_path, SLASH_STRING, base_name, (char *)NULL);
+    result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
 
   xfree (real_path);
   return result;
@@ -3138,7 +3411,7 @@ xfullpath (const char *filename)
 unsigned long
 gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
 {
-  static const unsigned long crc32_table[256] = {
+  static const unsigned int crc32_table[256] = {
     0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
     0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
     0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
@@ -3224,6 +3497,7 @@ hashtab_obstack_allocate (void *data, size_t size, size_t count)
 {
   unsigned int total = size * count;
   void *ptr = obstack_alloc ((struct obstack *) data, total);
+
   memset (ptr, 0, total);
   return ptr;
 }
@@ -3375,7 +3649,86 @@ char **
 gdb_buildargv (const char *s)
 {
   char **argv = buildargv (s);
+
   if (s != NULL && argv == NULL)
     nomem (0);
   return argv;
 }
+
+int
+compare_positive_ints (const void *ap, const void *bp)
+{
+  /* Because we know we're comparing two ints which are positive,
+     there's no danger of overflow here.  */
+  return * (int *) ap - * (int *) bp;
+}
+
+#define AMBIGUOUS_MESS1        ".\nMatching formats:"
+#define AMBIGUOUS_MESS2        ".\nUse \"set gnutarget format-name\" to specify the format."
+
+const char *
+gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
+{
+  char *ret, *retp;
+  int ret_len;
+  char **p;
+
+  /* Check if errmsg just need simple return.  */
+  if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
+    return bfd_errmsg (error_tag);
+
+  ret_len = strlen (bfd_errmsg (error_tag)) + strlen (AMBIGUOUS_MESS1)
+            + strlen (AMBIGUOUS_MESS2);
+  for (p = matching; *p; p++)
+    ret_len += strlen (*p) + 1;
+  ret = xmalloc (ret_len + 1);
+  retp = ret;
+  make_cleanup (xfree, ret);
+
+  strcpy (retp, bfd_errmsg (error_tag));
+  retp += strlen (retp);
+
+  strcpy (retp, AMBIGUOUS_MESS1);
+  retp += strlen (retp);
+
+  for (p = matching; *p; p++)
+    {
+      sprintf (retp, " %s", *p);
+      retp += strlen (retp);
+    }
+  xfree (matching);
+
+  strcpy (retp, AMBIGUOUS_MESS2);
+
+  return ret;
+}
+
+/* Return ARGS parsed as a valid pid, or throw an error.  */
+
+int
+parse_pid_to_attach (char *args)
+{
+  unsigned long pid;
+  char *dummy;
+
+  if (!args)
+    error_no_arg (_("process-id to attach"));
+
+  dummy = args;
+  pid = strtoul (args, &dummy, 0);
+  /* Some targets don't set errno on errors, grrr!  */
+  if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
+    error (_("Illegal process-id: %s."), args);
+
+  return pid;
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_utils;
+
+void
+_initialize_utils (void)
+{
+  add_internal_problem_command (&internal_error_problem);
+  add_internal_problem_command (&internal_warning_problem);
+}
This page took 0.043283 seconds and 4 git commands to generate.