summaryrefslogtreecommitdiff
path: root/misc/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/error.c')
-rw-r--r--misc/error.c207
1 files changed, 142 insertions, 65 deletions
diff --git a/misc/error.c b/misc/error.c
index 85d1cffbf9..2501583366 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -1,6 +1,7 @@
/* Error handler for noninteractive utilities
- Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+ Copyright (C) 1990-1998, 2000-2003, 2004 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 Lesser General Public
@@ -23,19 +24,33 @@
# include <config.h>
#endif
-#include <stdarg.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
+#include <libintl.h>
#ifdef _LIBC
-# include <libintl.h>
-# include <stdbool.h>
-# include <stdint.h>
# include <wchar.h>
# define mbsrtowcs __mbsrtowcs
#endif
+#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
+# if __STDC__
+# include <stdarg.h>
+# define VA_START(args, lastarg) va_start(args, lastarg)
+# else
+# include <varargs.h>
+# define VA_START(args, lastarg) va_start(args)
+# endif
+#else
+# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif
+
+#if STDC_HEADERS || _LIBC
+# include <stdlib.h>
+# include <string.h>
+#else
+void exit ();
+#endif
+
#include "error.h"
#ifndef _
@@ -45,7 +60,11 @@
/* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space. Otherwise, error will call this
function without parameters instead. */
-void (*error_print_progname) (void);
+void (*error_print_progname) (
+#if __STDC__ - 0
+ void
+#endif
+ );
/* This variable is incremented each time `error' is called. */
unsigned int error_message_count;
@@ -55,7 +74,6 @@ 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.
@@ -91,6 +109,27 @@ extern char *program_name;
# if HAVE_STRERROR_R || defined strerror_r
# define __strerror_r strerror_r
+# else
+# if HAVE_STRERROR
+# ifndef HAVE_DECL_STRERROR
+"this configure-time declaration test was not run"
+# endif
+# if !HAVE_DECL_STRERROR
+char *strerror ();
+# endif
+# else
+static char *
+private_strerror (int errnum)
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return _(sys_errlist[errnum]);
+ return _("Unknown system error");
+}
+# define strerror private_strerror
+# endif /* HAVE_STRERROR */
# endif /* HAVE_STRERROR_R || defined strerror_r */
#endif /* not _LIBC */
@@ -119,33 +158,38 @@ print_errno_message (int errnum)
#endif
#if _LIBC
- __fxprintf (NULL, ": %s", s);
-#else
- fprintf (stderr, ": %s", s);
+ if (_IO_fwide (stderr, 0) > 0)
+ {
+ __fwprintf (stderr, L": %s", s);
+ return;
+ }
#endif
+
+ fprintf (stderr, ": %s", s);
}
+#ifdef VA_START
static void
error_tail (int status, int errnum, const char *message, va_list args)
{
-#if _LIBC
+# if HAVE_VPRINTF || _LIBC
+# if _LIBC
if (_IO_fwide (stderr, 0) > 0)
{
-# define ALLOCA_LIMIT 2000
+# define ALLOCA_LIMIT 2000
size_t len = strlen (message) + 1;
wchar_t *wmessage = NULL;
mbstate_t st;
size_t res;
const char *tmp;
- bool use_malloc = false;
- while (1)
+ do
{
- if (__libc_use_alloca (len * sizeof (wchar_t)))
+ if (len < ALLOCA_LIMIT)
wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
else
{
- if (!use_malloc)
+ if (wmessage != NULL && len / 2 < ALLOCA_LIMIT)
wmessage = NULL;
wchar_t *p = (wchar_t *) realloc (wmessage,
@@ -157,69 +201,62 @@ error_tail (int status, int errnum, const char *message, va_list args)
return;
}
wmessage = p;
- use_malloc = true;
}
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;
}
+ while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len);
if (res == (size_t) -1)
- {
- /* The string cannot be converted. */
- if (use_malloc)
- {
- free (wmessage);
- use_malloc = false;
- }
- wmessage = (wchar_t *) L"???";
- }
+ /* The string cannot be converted. */
+ wmessage = (wchar_t *) L"???";
__vfwprintf (stderr, wmessage, args);
-
- if (use_malloc)
- free (wmessage);
}
else
-#endif
+# endif
vfprintf (stderr, message, args);
+# else
+ _doprnt (message, args, stderr);
+# endif
va_end (args);
++error_message_count;
if (errnum)
print_errno_message (errnum);
-#if _LIBC
- __fxprintf (NULL, "\n");
-#else
- putc ('\n', stderr);
-#endif
+# if _LIBC
+ 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, ...)
+#else
+error (status, errnum, message, va_alist)
+ int status;
+ int errnum;
+ char *message;
+ va_dcl
+#endif
{
+#ifdef VA_START
va_list args;
+#endif
#if defined _LIBC && defined __libc_ptf_call
/* We do not want this call to be cut short by a thread
@@ -238,14 +275,27 @@ error (int status, int errnum, const char *message, ...)
else
{
#if _LIBC
- __fxprintf (NULL, "%s: ", program_name);
-#else
- fprintf (stderr, "%s: ", program_name);
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s: ", program_name);
+ else
#endif
+ fprintf (stderr, "%s: ", program_name);
}
- va_start (args, message);
+#ifdef VA_START
+ VA_START (args, message);
error_tail (status, errnum, message, args);
+#else
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+
+ ++error_message_count;
+ if (errnum)
+ print_errno_message (errnum);
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+#endif
#ifdef _LIBC
_IO_funlockfile (stderr);
@@ -260,10 +310,22 @@ error (int status, int errnum, const char *message, ...)
int error_one_per_line;
void
+#if defined VA_START && __STDC__
error_at_line (int status, int errnum, const char *file_name,
unsigned int line_number, const char *message, ...)
+#else
+error_at_line (status, errnum, file_name, line_number, message, va_alist)
+ int status;
+ int errnum;
+ const char *file_name;
+ unsigned int line_number;
+ char *message;
+ va_dcl
+#endif
{
+#ifdef VA_START
va_list args;
+#endif
if (error_one_per_line)
{
@@ -297,22 +359,37 @@ error_at_line (int status, int errnum, const char *file_name,
else
{
#if _LIBC
- __fxprintf (NULL, "%s:", program_name);
-#else
- fprintf (stderr, "%s:", program_name);
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s: ", program_name);
+ else
#endif
+ fprintf (stderr, "%s:", program_name);
}
+ if (file_name != NULL)
+ {
#if _LIBC
- __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
- file_name, line_number);
-#else
- fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
- file_name, line_number);
+ 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);
+ }
- va_start (args, message);
+#ifdef VA_START
+ VA_START (args, message);
error_tail (status, errnum, message, args);
+#else
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+
+ ++error_message_count;
+ if (errnum)
+ print_errno_message (errnum);
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+#endif
#ifdef _LIBC
_IO_funlockfile (stderr);