merge from gcc
[external/binutils.git] / gdb / ui-file.c
index dd53a40..1760b4c 100644 (file)
@@ -1,12 +1,13 @@
 /* UI_FILE - a generic STDIO like output stream.
 
-   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Implement the ``struct ui_file'' object. */
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
+#include "gdb_select.h"
 
 #include <errno.h>
 
@@ -264,7 +265,7 @@ set_ui_file_data (struct ui_file *file, void *data,
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer''. */
+   a memory buffer. */
 
 struct accumulated_ui_file
 {
@@ -286,8 +287,7 @@ do_ui_file_xstrdup (void *context, const char *buffer, long length)
 }
 
 char *
-ui_file_xstrdup (struct ui_file *file,
-                 long *length)
+ui_file_xstrdup (struct ui_file *file, long *length)
 {
   struct accumulated_ui_file acc;
   acc.buffer = NULL;
@@ -295,9 +295,27 @@ ui_file_xstrdup (struct ui_file *file,
   ui_file_put (file, do_ui_file_xstrdup, &acc);
   if (acc.buffer == NULL)
     acc.buffer = xstrdup ("");
-  *length = acc.length;
+  if (length != NULL)
+    *length = acc.length;
   return acc.buffer;
 }
+
+static void
+do_ui_file_obsavestring (void *context, const char *buffer, long length)
+{
+  struct obstack *obstack = (struct obstack *) context;
+  obstack_grow (obstack, buffer, length);
+}
+
+char *
+ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
+                     long *length)
+{
+  ui_file_put (file, do_ui_file_obsavestring, obstack);
+  *length = obstack_object_size (obstack);
+  obstack_1grow (obstack, '\0');
+  return obstack_finish (obstack);
+}
 \f
 /* A pure memory based ``struct ui_file'' that can be used an output
    buffer. The buffers accumulated contents are available via
@@ -472,6 +490,19 @@ stdio_file_read (struct ui_file *file, char *buf, long length_buf)
   if (stdio->magic != &stdio_file_magic)
     internal_error (__FILE__, __LINE__,
                    _("stdio_file_read: bad magic number"));
+
+  /* For the benefit of Windows, call gdb_select before reading from
+     the file.  Wait until at least one byte of data is available.
+     Control-C can interrupt gdb_select, but not read.  */
+  {
+    int fd = fileno (stdio->file);
+    fd_set readfds;
+    FD_ZERO (&readfds);
+    FD_SET (fd, &readfds);
+    if (gdb_select (fd + 1, &readfds, NULL, NULL, NULL) == -1)
+      return -1;
+  }
+
   return read (fileno (stdio->file), buf, length_buf);
 }
 
@@ -482,7 +513,9 @@ stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
   if (stdio->magic != &stdio_file_magic)
     internal_error (__FILE__, __LINE__,
                    _("stdio_file_write: bad magic number"));
-  fwrite (buf, length_buf, 1, stdio->file);
+  /* Calling error crashes when we are called from the exception framework.  */
+  if (fwrite (buf, length_buf, 1, stdio->file))
+    ;
 }
 
 static void
@@ -492,7 +525,9 @@ stdio_file_fputs (const char *linebuffer, struct ui_file *file)
   if (stdio->magic != &stdio_file_magic)
     internal_error (__FILE__, __LINE__,
                    _("stdio_file_fputs: bad magic number"));
-  fputs (linebuffer, stdio->file);
+  /* Calling error crashes when we are called from the exception framework.  */
+  if (fputs (linebuffer, stdio->file))
+    ;
 }
 
 static int