Mercurial > hg > octave-kai > gnulib-hg
changeset 3446:849a40d65bee
Update from GNU libc.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Sun, 02 Sep 2001 13:22:25 +0000 |
parents | 771e21fddcd7 |
children | f590950998ed |
files | lib/error.c |
diffstat | 1 files changed, 167 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/error.c +++ b/lib/error.c @@ -1,23 +1,22 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000 Free Software Foundation, Inc. - + Copyright (C) 1990-1998, 2000, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ @@ -29,6 +28,10 @@ #if HAVE_LIBINTL_H # include <libintl.h> #endif +#ifdef _LIBC +# include <wchar.h> +# define mbsrtowcs __mbsrtowcs +#endif #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC # if __STDC__ @@ -83,6 +86,12 @@ /* In GNU libc we want do not want to use the common name `error' directly. Instead make it a weak alias. */ +extern void __error (int status, int errnum, const char *message, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +extern void __error_at_line (int status, int errnum, const char *file_name, + unsigned int line_number, const char *message, + ...) + __attribute__ ((__format__ (__printf__, 5, 6)));; # define error __error # define error_at_line __error_at_line @@ -121,12 +130,94 @@ # endif /* HAVE_STRERROR_R */ #endif /* not _LIBC */ + +#ifdef VA_START +static void +error_tail (int status, int errnum, const char *message, va_list args) +{ +# if HAVE_VPRINTF || _LIBC +# if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + { +# define ALLOCA_LIMIT 2000 + size_t len = strlen (message) + 1; + wchar_t *wmessage = NULL; + mbstate_t st; + size_t res; + const char *tmp; + + do + { + if (len < ALLOCA_LIMIT) + wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); + else + { + if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) + wmessage = NULL; + + wmessage = (wchar_t *) realloc (wmessage, + len * sizeof (wchar_t)); + + if (wmessage == NULL) + { + fputws_unlocked (L"out of memory\n", stderr); + return; + } + } + + memset (&st, '\0', sizeof (st)); + tmp =message; + } + while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); + + if (res == (size_t) -1) + /* The string cannot be converted. */ + wmessage = (wchar_t *) L"???"; + + __vfwprintf (stderr, wmessage, args); + } + else +# endif + vfprintf (stderr, message, args); +# else + _doprnt (message, args, stderr); +# endif + va_end (args); + + ++error_message_count; + if (errnum) + { +# if defined HAVE_STRERROR_R || _LIBC + char errbuf[1024]; + char *s = __strerror_r (errnum, errbuf, sizeof errbuf); +# if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L": %s", s); + else +# endif + fprintf (stderr, ": %s", s); +# else + fprintf (stderr, ": %s", strerror (errnum)); +# endif + } +# if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + putwc (L'\n', stderr); + else +# endif + putc ('\n', stderr); + fflush (stderr); + if (status) + exit (status); +} +#endif + + /* Print the program name and error message MESSAGE, which is a printf-style format string with optional args. If ERRNUM is nonzero, print its corresponding system error message. Exit with status STATUS if it is nonzero. */ /* VARARGS */ - void #if defined VA_START && __STDC__ error (int status, int errnum, const char *message, ...) @@ -142,47 +233,58 @@ va_list args; #endif + fflush (stdout); +#ifdef _LIBC +# ifdef USE_IN_LIBIO + _IO_flockfile (stderr); +# else + __flockfile (stderr); +# endif +#endif if (error_print_progname) (*error_print_progname) (); else { - fflush (stdout); - fprintf (stderr, "%s: ", program_name); +#if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s: ", program_name); + else +#endif + fprintf (stderr, "%s: ", program_name); } #ifdef VA_START VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); + error_tail (status, errnum, message, args); #else fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif ++error_message_count; if (errnum) { -#if defined HAVE_STRERROR_R || _LIBC +# if defined HAVE_STRERROR_R || _LIBC char errbuf[1024]; -# if HAVE_WORKING_STRERROR_R || _LIBC - fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); -# else /* Don't use __strerror_r's return value because on some systems (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ __strerror_r (errnum, errbuf, sizeof errbuf); fprintf (stderr, ": %s", errbuf); +# else + fprintf (stderr, ": %s", strerror (errnum)); # endif -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif } putc ('\n', stderr); fflush (stderr); if (status) exit (status); +#endif + +#ifdef _LIBC +# ifdef USE_IN_LIBIO + _IO_funlockfile (stderr); +# else + __funlockfile (stderr); +# endif +#endif } /* Sometimes we want to have at most one error per line. This @@ -212,8 +314,9 @@ static const char *old_file_name; static unsigned int old_line_number; - if (old_line_number == line_number && - (file_name == old_file_name || !strcmp (old_file_name, file_name))) + if (old_line_number == line_number + && (file_name == old_file_name + || strcmp (old_file_name, file_name) == 0)) /* Simply return and print nothing. */ return; @@ -221,50 +324,68 @@ old_line_number = line_number; } + fflush (stdout); +#ifdef _LIBC +# ifdef USE_IN_LIBIO + _IO_flockfile (stderr); +# else + __flockfile (stderr); +# endif +#endif if (error_print_progname) (*error_print_progname) (); else { - fflush (stdout); - fprintf (stderr, "%s:", program_name); +#if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s: ", program_name); + else +#endif + fprintf (stderr, "%s:", program_name); } if (file_name != NULL) - fprintf (stderr, "%s:%d: ", file_name, line_number); + { +#if _LIBC && USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf (stderr, L"%s:%d: ", file_name, line_number); + else +#endif + fprintf (stderr, "%s:%d: ", file_name, line_number); + } #ifdef VA_START VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); + error_tail (status, errnum, message, args); #else fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif ++error_message_count; if (errnum) { -#if defined HAVE_STRERROR_R || _LIBC +# if defined HAVE_STRERROR_R || _LIBC char errbuf[1024]; -# if HAVE_WORKING_STRERROR_R || _LIBC - fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); -# else /* Don't use __strerror_r's return value because on some systems (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ __strerror_r (errnum, errbuf, sizeof errbuf); fprintf (stderr, ": %s", errbuf); +# else + fprintf (stderr, ": %s", strerror (errnum)); # endif -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif } putc ('\n', stderr); fflush (stderr); if (status) exit (status); +#endif + +#ifdef _LIBC +# ifdef USE_IN_LIBIO + _IO_funlockfile (stderr); +# else + __funlockfile (stderr); +# endif +#endif } #ifdef _LIBC