Include <stdlib.h>.
[gnulib.git] / lib / error.c
1 /* Error handler for noninteractive utilities
2    Copyright (C) 1990-1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License along
14    with this program; if not, write to the Free Software Foundation,
15    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
16
17 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include "error.h"
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef _LIBC
31 # include <libintl.h>
32 #else
33 # include "gettext.h"
34 #endif
35
36 #ifdef _LIBC
37 # include <wchar.h>
38 # define mbsrtowcs __mbsrtowcs
39 #endif
40
41 #if !_LIBC
42 # include "unlocked-io.h"
43 #endif
44
45 #ifndef _
46 # define _(String) String
47 #endif
48
49 /* If NULL, error will flush stdout, then print on stderr the program
50    name, a colon and a space.  Otherwise, error will call this
51    function without parameters instead.  */
52 void (*error_print_progname) (void);
53
54 /* This variable is incremented each time `error' is called.  */
55 unsigned int error_message_count;
56
57 #ifdef _LIBC
58 /* In the GNU C library, there is a predefined variable for this.  */
59
60 # define program_name program_invocation_name
61 # include <libio/libioP.h>
62
63 /* In GNU libc we want do not want to use the common name `error' directly.
64    Instead make it a weak alias.  */
65 extern void __error (int status, int errnum, const char *message, ...)
66      __attribute__ ((__format__ (__printf__, 3, 4)));
67 extern void __error_at_line (int status, int errnum, const char *file_name,
68                              unsigned int line_number, const char *message,
69                              ...)
70      __attribute__ ((__format__ (__printf__, 5, 6)));;
71 # define error __error
72 # define error_at_line __error_at_line
73
74 # include <libio/iolibio.h>
75 # define fflush(s) INTUSE(_IO_fflush) (s)
76 # undef putc
77 # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
78
79 #else /* not _LIBC */
80
81 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
82 #  ifndef HAVE_DECL_STRERROR_R
83 "this configure-time declaration test was not run"
84 #  endif
85 char *strerror_r ();
86 # endif
87
88 /* The calling program should define program_name and set it to the
89    name of the executing program.  */
90 extern char *program_name;
91
92 # if HAVE_STRERROR_R || defined strerror_r
93 #  define __strerror_r strerror_r
94 # endif
95 #endif  /* not _LIBC */
96
97 static void
98 print_errno_message (int errnum)
99 {
100   char const *s;
101
102 #if defined HAVE_STRERROR_R || _LIBC
103   char errbuf[1024];
104 # if STRERROR_R_CHAR_P || _LIBC
105   s = __strerror_r (errnum, errbuf, sizeof errbuf);
106 # else
107   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
108     s = errbuf;
109   else
110     s = 0;
111 # endif
112 #else
113   s = strerror (errnum);
114 #endif
115
116 #if !_LIBC
117   if (! s)
118     s = _("Unknown system error");
119 #endif
120
121 #if _LIBC
122   if (_IO_fwide (stderr, 0) > 0)
123     {
124       __fwprintf (stderr, L": %s", s);
125       return;
126     }
127 #endif
128
129   fprintf (stderr, ": %s", s);
130 }
131
132 static void
133 error_tail (int status, int errnum, const char *message, va_list args)
134 {
135 # if HAVE_VPRINTF || _LIBC
136 #  if _LIBC
137   if (_IO_fwide (stderr, 0) > 0)
138     {
139 #   define ALLOCA_LIMIT 2000
140       size_t len = strlen (message) + 1;
141       wchar_t *wmessage = NULL;
142       mbstate_t st;
143       size_t res;
144       const char *tmp;
145
146       do
147         {
148           if (len < ALLOCA_LIMIT)
149             wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
150           else
151             {
152               if (wmessage != NULL && len / 2 < ALLOCA_LIMIT)
153                 wmessage = NULL;
154
155               wmessage = (wchar_t *) realloc (wmessage,
156                                               len * sizeof (wchar_t));
157
158               if (wmessage == NULL)
159                 {
160                   fputws_unlocked (L"out of memory\n", stderr);
161                   return;
162                 }
163             }
164
165           memset (&st, '\0', sizeof (st));
166           tmp =message;
167         }
168       while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len);
169
170       if (res == (size_t) -1)
171         /* The string cannot be converted.  */
172         wmessage = (wchar_t *) L"???";
173
174       __vfwprintf (stderr, wmessage, args);
175     }
176   else
177 #  endif
178     vfprintf (stderr, message, args);
179 # else
180   _doprnt (message, args, stderr);
181 # endif
182   va_end (args);
183
184   ++error_message_count;
185   if (errnum)
186     print_errno_message (errnum);
187 # if _LIBC
188   if (_IO_fwide (stderr, 0) > 0)
189     putwc (L'\n', stderr);
190   else
191 # endif
192     putc ('\n', stderr);
193   fflush (stderr);
194   if (status)
195     exit (status);
196 }
197
198
199 /* Print the program name and error message MESSAGE, which is a printf-style
200    format string with optional args.
201    If ERRNUM is nonzero, print its corresponding system error message.
202    Exit with status STATUS if it is nonzero.  */
203 /* VARARGS */
204 void
205 error (int status, int errnum, const char *message, ...)
206 {
207   va_list args;
208
209   fflush (stdout);
210 #ifdef _LIBC
211   _IO_flockfile (stderr);
212 #endif
213   if (error_print_progname)
214     (*error_print_progname) ();
215   else
216     {
217 #if _LIBC
218       if (_IO_fwide (stderr, 0) > 0)
219         __fwprintf (stderr, L"%s: ", program_name);
220       else
221 #endif
222         fprintf (stderr, "%s: ", program_name);
223     }
224
225   va_start (args, message);
226   error_tail (status, errnum, message, args);
227
228 #ifdef _LIBC
229   _IO_funlockfile (stderr);
230 #endif
231 }
232 \f
233 /* Sometimes we want to have at most one error per line.  This
234    variable controls whether this mode is selected or not.  */
235 int error_one_per_line;
236
237 void
238 error_at_line (int status, int errnum, const char *file_name,
239                unsigned int line_number, const char *message, ...)
240 {
241   va_list args;
242
243   if (error_one_per_line)
244     {
245       static const char *old_file_name;
246       static unsigned int old_line_number;
247
248       if (old_line_number == line_number
249           && (file_name == old_file_name
250               || strcmp (old_file_name, file_name) == 0))
251         /* Simply return and print nothing.  */
252         return;
253
254       old_file_name = file_name;
255       old_line_number = line_number;
256     }
257
258   fflush (stdout);
259 #ifdef _LIBC
260   _IO_flockfile (stderr);
261 #endif
262   if (error_print_progname)
263     (*error_print_progname) ();
264   else
265     {
266 #if _LIBC
267       if (_IO_fwide (stderr, 0) > 0)
268         __fwprintf (stderr, L"%s: ", program_name);
269       else
270 #endif
271         fprintf (stderr, "%s:", program_name);
272     }
273
274   if (file_name != NULL)
275     {
276 #if _LIBC
277       if (_IO_fwide (stderr, 0) > 0)
278         __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
279       else
280 #endif
281         fprintf (stderr, "%s:%d: ", file_name, line_number);
282     }
283
284   va_start (args, message);
285   error_tail (status, errnum, message, args);
286
287 #ifdef _LIBC
288   _IO_funlockfile (stderr);
289 #endif
290 }
291
292 #ifdef _LIBC
293 /* Make the weak alias.  */
294 # undef error
295 # undef error_at_line
296 weak_alias (__error, error)
297 weak_alias (__error_at_line, error_at_line)
298 #endif