OSDN Git Service

PR 11123
[pf3gnuchains/pf3gnuchains3x.git] / gdb / utils.c
index 6719ae1..4c03655 100644 (file)
@@ -2,7 +2,7 @@
 
    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
    1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009 Free Software Foundation, Inc.
+   2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include <sys/time.h>
 #include <time.h>
 
+#include "gdb_usleep.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 ();
@@ -271,6 +273,23 @@ 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)
 {
@@ -819,8 +838,7 @@ fatal (const char *string, ...)
 NORETURN 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);
 }
@@ -914,7 +932,15 @@ further debugging may prove unreliable.", file, line, problem->name, msg);
       /* Default (yes/batch case) is to quit GDB.  When in batch mode
         this lessens the likelihood of GDB going into an infinite
         loop.  */
-      quit_p = query (_("%s\nQuit this debugging session? "), reason);
+      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;
@@ -1072,6 +1098,9 @@ Show whether GDB will quit when an %s is detected"),
                        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);
@@ -1088,6 +1117,9 @@ Show whether GDB will create a core file of GDB when %s is detected"),
                        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
@@ -1184,7 +1216,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;
@@ -1194,7 +1226,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);
 
@@ -1207,8 +1239,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;
 
@@ -1218,16 +1250,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;
@@ -1240,7 +1272,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);
 
@@ -1251,7 +1283,7 @@ void
 xfree (void *ptr)
 {
   if (ptr != NULL)
-    free (ptr);                /* OK: free */
+    free (ptr);                /* ARI: free */
 }
 \f
 
@@ -1409,12 +1441,12 @@ 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 ())
@@ -1429,11 +1461,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);
@@ -1460,6 +1487,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 */
        {
@@ -1554,21 +1600,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 (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 (), host_charset (),
+                            &the_char, 1, 1, &host_data, translit_none);
 
-  error (_("There is no control character `\\%s' in the `%s' character set."),
-        copy, target_charset ());
+  if (obstack_object_size (&host_data) == 1)
+    {
+      result = 1;
+      *target_c = *(char *) obstack_base (&host_data);
+    }
+
+  do_cleanups (cleanups);
+  return result;
 }
 
 /* Parse a C escape sequence.  STRING_PTR points to a variable
@@ -1589,55 +1647,15 @@ no_control_char_error (const char *start, const char *end)
 int
 parse_escape (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':
@@ -1648,16 +1666,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
                {
@@ -1666,14 +1684,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 (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;
 }
 \f
 /* Print the character C on STREAM as part of the contents of a literal
@@ -2812,26 +2855,8 @@ get_cell (void)
   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
@@ -2842,7 +2867,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;
@@ -3119,7 +3144,6 @@ 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')
@@ -3135,17 +3159,6 @@ 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
     {
@@ -3299,7 +3312,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,
@@ -3541,6 +3554,9 @@ gdb_buildargv (const char *s)
   return argv;
 }
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_utils;
+
 void
 _initialize_utils (void)
 {