bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: typo in error module


From: Eric Blake
Subject: Re: typo in error module
Date: Fri, 4 Aug 2006 03:51:54 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Bruno Haible <bruno <at> clisp.org> writes:

> I object. We don't want to have a semantic difference between glibc 'error'
> and gnulib 'error'.

Point taken.  So I will be opening up several glibc bugs over the next little
while, trying to see if we can get upstream to change first, starting with this:
http://sources.redhat.com/bugzilla/show_bug.cgi?id=2997

Meanwhile, is this patch acceptable, which updates the _LIBC portions of the
error module to resemble CVS glibc more closely, so that I have fewer spurious
diffs to filter through?

2006-08-03  Eric Blake  <address@hidden>

        * error.h: Fold in some upstream changes from glibc.
        * error.c: Likewise.

Index: lib/error.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/error.c,v
retrieving revision 1.43
diff -u -p -r1.43 error.c
--- lib/error.c 14 May 2005 06:03:58 -0000      1.43
+++ lib/error.c 4 Aug 2006 03:44:42 -0000
@@ -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, cons
     {
 # 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);
+      wchar_t *wmessage = NULL;
+      mbstate_t st;
+      size_t res;
+      const char *tmp;
+      bool use_malloc = false;
 
-      if (wbuf)
+      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, cons
   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 cha
   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, c
   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: lib/error.h
===================================================================
RCS file: /sources/gnulib/gnulib/lib/error.h,v
retrieving revision 1.20
diff -u -p -r1.20 error.h
--- lib/error.h 14 May 2005 06:03:58 -0000      1.20
+++ lib/error.h 4 Aug 2006 03:44:42 -0000
@@ -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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]