diff options
Diffstat (limited to 'misc/err.c')
-rw-r--r-- | misc/err.c | 101 |
1 files changed, 87 insertions, 14 deletions
diff --git a/misc/err.c b/misc/err.c index 4e1d43b2b9..dc7025c670 100644 --- a/misc/err.c +++ b/misc/err.c @@ -1,5 +1,5 @@ -/* err.c --- 4.4BSD utility functions for error messages. - Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. +/* 4.4BSD utility functions for error messages. + Copyright (C) 1995, 1996, 1998, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ #include <stdio.h> #ifdef USE_IN_LIBIO +# include <wchar.h> # define flockfile(s) _IO_flockfile (s) # define funlockfile(s) _IO_funlockfile (s) #endif @@ -39,15 +40,72 @@ extern char *__progname; va_end (ap); \ } +#ifdef USE_IN_LIBIO +static void +convert_and_print (const char *format, __gnuc_va_list ap) +{ +# define ALLOCA_LIMIT 2000 + size_t len; + wchar_t *wformat = NULL; + mbstate_t st; + size_t res; + const char *tmp; + + if (format == NULL) + return; + + len = strlen (format) + 1; + + do + { + if (len < ALLOCA_LIMIT) + wformat = (wchar_t *) alloca (len * sizeof (wchar_t)); + else + { + if (wformat != NULL && len / 2 < ALLOCA_LIMIT) + wformat = NULL; + + wformat = (wchar_t *) realloc (wformat, len * sizeof (wchar_t)); + + if (wformat == NULL) + { + fputws (L"out of memory\n", stderr); + return; + } + } + + memset (&st, '\0', sizeof (st)); + tmp =format; + } + while ((res = mbsrtowcs (wformat, &tmp, len, &st)) == len); + + if (res == (size_t) -1) + /* The string cannot be converted. */ + wformat = (wchar_t *) L"???"; + + vfwprintf (stderr, wformat, ap); +} +#endif + void vwarnx (const char *format, __gnuc_va_list ap) { flockfile (stderr); - if (__progname) - fprintf (stderr, "%s: ", __progname); - if (format) - vfprintf (stderr, format, ap); - putc_unlocked ('\n', stderr); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + { + fwprintf (stderr, L"%s: ", __progname); + convert_and_print (format, ap); + putwc_unlocked (L'\n', stderr); + } + else +#endif + { + fprintf (stderr, "%s: ", __progname); + if (format) + vfprintf (stderr, format, ap); + putc_unlocked ('\n', stderr); + } funlockfile (stderr); } @@ -57,15 +115,30 @@ vwarn (const char *format, __gnuc_va_list ap) int error = errno; flockfile (stderr); - if (__progname) - fprintf (stderr, "%s: ", __progname); - if (format) +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + { + fwprintf (stderr, L"%s: ", __progname); + if (format) + { + convert_and_print (format, ap); + fputws_unlocked (L": ", stderr); + } + __set_errno (error); + fwprintf (stderr, L"%m\n"); + } + else +#endif { - vfprintf (stderr, format, ap); - fputs_unlocked (": ", stderr); + fprintf (stderr, "%s: ", __progname); + if (format) + { + vfprintf (stderr, format, ap); + fputs_unlocked (": ", stderr); + } + __set_errno (error); + fprintf (stderr, "%m\n"); } - __set_errno (error); - fprintf (stderr, "%m\n"); funlockfile (stderr); } |