Mercurial > hg > octave-nkf > gnulib-hg
diff lib/error.c @ 7088:e3cb6c0685d8
* error.h: Fold in some upstream changes from glibc.
* error.c: Likewise.
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Sun, 06 Aug 2006 12:36:47 +0000 |
parents | a48fb0e98c8c |
children | 02e62250d524 |
line wrap: on
line diff
--- a/lib/error.c +++ b/lib/error.c @@ -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 @@ # 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 @@ #endif #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { - __fwprintf (stderr, L": %s", s); - return; - } + __fxprintf (NULL, ": %s", s); +#else + fprintf (stderr, ": %s", s); #endif - - fprintf (stderr, ": %s", s); } static void @@ -140,26 +140,65 @@ { # 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; + + while (1) + { + 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; + } - if (wbuf) + memset (&st, '\0', sizeof (st)); + 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) { - size_t res; - mbstate_t st; - const char *tmp = message; - memset (&st, '\0', sizeof (st)); - res = mbsrtowcs (wbuf, &tmp, len, &st); - wmessage = res == (size_t) -1 ? L"???" : wbuf; + /* 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 @@ 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 @@ 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 @@ 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);