* error.h: Fold in some upstream changes from glibc.
authorEric Blake <ebb9@byu.net>
Sun, 6 Aug 2006 12:36:47 +0000 (12:36 +0000)
committerEric Blake <ebb9@byu.net>
Sun, 6 Aug 2006 12:36:47 +0000 (12:36 +0000)
* error.c: Likewise.

lib/ChangeLog
lib/error.c
lib/error.h

index 130a1ec..3cbbf93 100644 (file)
@@ -1,3 +1,8 @@
+2006-08-06  Eric Blake  <ebb9@byu.net>
+
+       * error.h: Fold in some upstream changes from glibc.
+       * error.c: Likewise.
+
 2006-07-29  Bruno Haible  <bruno@clisp.org>
 
        * localcharset.c: Assume <stddef.h>, <stdlib.h>, <string.h> exist.
index 45698be..34e8365 100644 (file)
@@ -1,5 +1,5 @@
 /* Error handler for noninteractive utilities
-   Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,9 @@
 #endif
 
 #ifdef _LIBC
+# include <libintl.h>
+# include <stdbool.h>
+# include <stdint.h>
 # include <wchar.h>
 # define mbsrtowcs __mbsrtowcs
 #endif
@@ -59,6 +62,7 @@ unsigned int error_message_count;
 
 # define program_name program_invocation_name
 # include <errno.h>
+# include <limits.h>
 # include <libio/libioP.h>
 
 /* In GNU libc we want do not want to use the common name `error' directly.
@@ -122,14 +126,10 @@ print_errno_message (int errnum)
 #endif
 
 #if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    {
-      __fwprintf (stderr, L": %s", s);
-      return;
-    }
-#endif
-
+  __fxprintf (NULL, ": %s", s);
+#else
   fprintf (stderr, ": %s", s);
+#endif
 }
 
 static void
@@ -140,26 +140,65 @@ error_tail (int status, int errnum, const char *message, va_list args)
     {
 # define ALLOCA_LIMIT 2000
       size_t len = strlen (message) + 1;
-      const wchar_t *wmessage = L"out of memory";
-      wchar_t *wbuf = (len < ALLOCA_LIMIT
-                      ? alloca (len * sizeof *wbuf)
-                      : len <= SIZE_MAX / sizeof *wbuf
-                      ? malloc (len * sizeof *wbuf)
-                      : NULL);
-
-      if (wbuf)
+      wchar_t *wmessage = NULL;
+      mbstate_t st;
+      size_t res;
+      const char *tmp;
+      bool use_malloc = false;
+
+      while (1)
        {
-         size_t res;
-         mbstate_t st;
-         const char *tmp = message;
+         if (__libc_use_alloca (len * sizeof (wchar_t)))
+           wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
+         else
+           {
+             if (!use_malloc)
+               wmessage = NULL;
+
+             wchar_t *p = (wchar_t *) realloc (wmessage,
+                                               len * sizeof (wchar_t));
+             if (p == NULL)
+               {
+                 free (wmessage);
+                 fputws_unlocked (L"out of memory\n", stderr);
+                 return;
+               }
+             wmessage = p;
+             use_malloc = true;
+           }
+
          memset (&st, '\0', sizeof (st));
-         res = mbsrtowcs (wbuf, &tmp, len, &st);
-         wmessage = res == (size_t) -1 ? L"???" : wbuf;
+         tmp = message;
+
+         res = mbsrtowcs (wmessage, &tmp, len, &st);
+         if (res != len)
+           break;
+
+         if (__builtin_expect (len >= SIZE_MAX / 2, 0))
+           {
+             /* This really should not happen if everything is fine.  */
+             res = (size_t) -1;
+             break;
+           }
+
+         len *= 2;
+       }
+
+      if (res == (size_t) -1)
+       {
+         /* The string cannot be converted.  */
+         if (use_malloc)
+           {
+             free (wmessage);
+             use_malloc = false;
+           }
+         wmessage = (wchar_t *) L"???";
        }
 
       __vfwprintf (stderr, wmessage, args);
-      if (! (len < ALLOCA_LIMIT))
-       free (wbuf);
+
+      if (use_malloc)
+       free (wmessage);
     }
   else
 #endif
@@ -170,11 +209,10 @@ error_tail (int status, int errnum, const char *message, va_list args)
   if (errnum)
     print_errno_message (errnum);
 #if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    putwc (L'\n', stderr);
-  else
+  __fxprintf (NULL, "\n");
+#else
+  putc ('\n', stderr);
 #endif
-    putc ('\n', stderr);
   fflush (stderr);
   if (status)
     exit (status);
@@ -207,11 +245,10 @@ error (int status, int errnum, const char *message, ...)
   else
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s: ", program_name);
-      else
+      __fxprintf (NULL, "%s: ", program_name);
+#else
+      fprintf (stderr, "%s: ", program_name);
 #endif
-       fprintf (stderr, "%s: ", program_name);
     }
 
   va_start (args, message);
@@ -267,21 +304,19 @@ error_at_line (int status, int errnum, const char *file_name,
   else
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s: ", program_name);
-      else
+      __fxprintf (NULL, "%s:", program_name);
+#else
+      fprintf (stderr, "%s:", program_name);
 #endif
-       fprintf (stderr, "%s:", program_name);
     }
 
   if (file_name != NULL)
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
-      else
+      __fxprintf (NULL, "%s:%d: ", file_name, line_number);
+#else
+      fprintf (stderr, "%s:%d: ", file_name, line_number);
 #endif
-       fprintf (stderr, "%s:%d: ", file_name, line_number);
     }
 
   va_start (args, message);
index e5220a2..5a5f247 100644 (file)
@@ -1,5 +1,5 @@
 /* Declaration for error-reporting function
-   Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@
 
 #ifndef __attribute__
 /* This feature is available in gcc versions 2.5 and later.  */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
 #  define __attribute__(Spec) /* empty */
 # endif
 /* The __-protected variants of `format' and `printf' attributes