/[bison]/bison/lib/error.c
ViewVC logotype

Diff of /bison/lib/error.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by akim, Fri Mar 16 14:50:40 2001 UTC revision 1.3 by eggert, Fri Oct 26 07:26:00 2001 UTC
# Line 1  Line 1 
1  /* Error handler for noninteractive utilities  /* Error handler for noninteractive utilities
2     Copyright (C) 1990-1998, 2000 Free Software Foundation, Inc.     Copyright (C) 1990-1998, 2000, 2001 Free Software Foundation, Inc.
   
3     This file is part of the GNU C Library.  Its master source is NOT part of     This file is part of the GNU C Library.  Its master source is NOT part of
4     the C library, however.  The master source lives in /gd/gnu/lib.     the C library, however.  The master source lives in /gd/gnu/lib.
5    
6     The GNU C Library is free software; you can redistribute it and/or     The GNU C Library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public License as     modify it under the terms of the GNU Lesser General Public
8     published by the Free Software Foundation; either version 2 of the     License as published by the Free Software Foundation; either
9     License, or (at your option) any later version.     version 2.1 of the License, or (at your option) any later version.
10    
11     The GNU C Library is distributed in the hope that it will be useful,     The GNU C Library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.     Lesser General Public License for more details.
15    
16     You should have received a copy of the GNU Library General Public     You should have received a copy of the GNU Lesser General Public
17     License along with the GNU C Library; see the file COPYING.LIB.  If not,     License along with the GNU C Library; if not, write to the Free
18     write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19     Boston, MA 02111-1307, USA.  */     02111-1307 USA.  */
20    
21  /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */  /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
22    
# Line 29  Line 28 
28  #if HAVE_LIBINTL_H  #if HAVE_LIBINTL_H
29  # include <libintl.h>  # include <libintl.h>
30  #endif  #endif
31    #ifdef _LIBC
32    # include <wchar.h>
33    # define mbsrtowcs __mbsrtowcs
34    #endif
35    
36  #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC  #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
37  # if __STDC__  # if __STDC__
# Line 52  void exit (); Line 55  void exit ();
55    
56  #include "error.h"  #include "error.h"
57    
 #ifndef HAVE_DECL_STRERROR_R  
 "this configure-time declaration test was not run"  
 #endif  
 #if !HAVE_DECL_STRERROR_R  
 char *strerror_r ();  
 #endif  
   
58  #ifndef _  #ifndef _
59  # define _(String) String  # define _(String) String
60  #endif  #endif
# Line 83  unsigned int error_message_count; Line 79  unsigned int error_message_count;
79    
80  /* In GNU libc we want do not want to use the common name `error' directly.  /* In GNU libc we want do not want to use the common name `error' directly.
81     Instead make it a weak alias.  */     Instead make it a weak alias.  */
82    extern void __error (int status, int errnum, const char *message, ...)
83         __attribute__ ((__format__ (__printf__, 3, 4)));
84    extern void __error_at_line (int status, int errnum, const char *file_name,
85                                 unsigned int line_number, const char *message,
86                                 ...)
87         __attribute__ ((__format__ (__printf__, 5, 6)));;
88  # define error __error  # define error __error
89  # define error_at_line __error_at_line  # define error_at_line __error_at_line
90    
# Line 93  unsigned int error_message_count; Line 95  unsigned int error_message_count;
95    
96  #else /* not _LIBC */  #else /* not _LIBC */
97    
98    # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
99    #  ifndef HAVE_DECL_STRERROR_R
100    "this configure-time declaration test was not run"
101    #  endif
102    char *strerror_r ();
103    # endif
104    
105  /* The calling program should define program_name and set it to the  /* The calling program should define program_name and set it to the
106     name of the executing program.  */     name of the executing program.  */
107  extern char *program_name;  extern char *program_name;
108    
109  # ifdef HAVE_STRERROR_R  # if HAVE_STRERROR_R || defined strerror_r
110  #  define __strerror_r strerror_r  #  define __strerror_r strerror_r
111  # else  # else
112  #  if HAVE_STRERROR  #  if HAVE_STRERROR
113  #   ifndef strerror             /* On some systems, strerror is a macro */  #   ifndef HAVE_DECL_STRERROR
114    "this configure-time declaration test was not run"
115    #   endif
116    #   if !HAVE_DECL_STRERROR
117  char *strerror ();  char *strerror ();
118  #   endif  #   endif
119  #  else  #  else
120  static char *  static char *
121  private_strerror (errnum)  private_strerror (int errnum)
      int errnum;  
122  {  {
123    extern char *sys_errlist[];    extern char *sys_errlist[];
124    extern int sys_nerr;    extern int sys_nerr;
# Line 118  private_strerror (errnum) Line 129  private_strerror (errnum)
129  }  }
130  #   define strerror private_strerror  #   define strerror private_strerror
131  #  endif /* HAVE_STRERROR */  #  endif /* HAVE_STRERROR */
132  # endif /* HAVE_STRERROR_R */  # endif /* HAVE_STRERROR_R || defined strerror_r */
133  #endif  /* not _LIBC */  #endif  /* not _LIBC */
134    
135    static void
136    print_errno_message (int errnum)
137    {
138      char const *s;
139    
140    #if defined HAVE_STRERROR_R || _LIBC
141      char errbuf[1024];
142    # if STRERROR_R_CHAR_P || _LIBC
143      s = __strerror_r (errnum, errbuf, sizeof errbuf);
144    # else
145      if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
146        s = errbuf;
147      else
148        s = 0;
149    # endif
150    #else
151      s = strerror (errnum);
152    #endif
153    
154    #if !_LIBC
155      if (! s)
156        s = _("Unknown system error");
157    #endif
158    
159    #if _LIBC && USE_IN_LIBIO
160      if (_IO_fwide (stderr, 0) > 0)
161        {
162          __fwprintf (stderr, L": %s", s);
163          return;
164        }
165    #endif
166    
167      fprintf (stderr, ": %s", s);
168    }
169    
170    #ifdef VA_START
171    static void
172    error_tail (int status, int errnum, const char *message, va_list args)
173    {
174    # if HAVE_VPRINTF || _LIBC
175    #  if _LIBC && USE_IN_LIBIO
176      if (_IO_fwide (stderr, 0) > 0)
177        {
178    #   define ALLOCA_LIMIT 2000
179          size_t len = strlen (message) + 1;
180          wchar_t *wmessage = NULL;
181          mbstate_t st;
182          size_t res;
183          const char *tmp;
184    
185          do
186            {
187              if (len < ALLOCA_LIMIT)
188                wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
189              else
190                {
191                  if (wmessage != NULL && len / 2 < ALLOCA_LIMIT)
192                    wmessage = NULL;
193    
194                  wmessage = (wchar_t *) realloc (wmessage,
195                                                  len * sizeof (wchar_t));
196    
197                  if (wmessage == NULL)
198                    {
199                      fputws_unlocked (L"out of memory\n", stderr);
200                      return;
201                    }
202                }
203    
204              memset (&st, '\0', sizeof (st));
205              tmp =message;
206            }
207          while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len);
208    
209          if (res == (size_t) -1)
210            /* The string cannot be converted.  */
211            wmessage = (wchar_t *) L"???";
212    
213          __vfwprintf (stderr, wmessage, args);
214        }
215      else
216    #  endif
217        vfprintf (stderr, message, args);
218    # else
219      _doprnt (message, args, stderr);
220    # endif
221      va_end (args);
222    
223      ++error_message_count;
224      if (errnum)
225        print_errno_message (errnum);
226    # if _LIBC && USE_IN_LIBIO
227      if (_IO_fwide (stderr, 0) > 0)
228        putwc (L'\n', stderr);
229      else
230    # endif
231        putc ('\n', stderr);
232      fflush (stderr);
233      if (status)
234        exit (status);
235    }
236    #endif
237    
238    
239  /* Print the program name and error message MESSAGE, which is a printf-style  /* Print the program name and error message MESSAGE, which is a printf-style
240     format string with optional args.     format string with optional args.
241     If ERRNUM is nonzero, print its corresponding system error message.     If ERRNUM is nonzero, print its corresponding system error message.
242     Exit with status STATUS if it is nonzero.  */     Exit with status STATUS if it is nonzero.  */
243  /* VARARGS */  /* VARARGS */
   
244  void  void
245  #if defined VA_START && __STDC__  #if defined VA_START && __STDC__
246  error (int status, int errnum, const char *message, ...)  error (int status, int errnum, const char *message, ...)
# Line 142  error (status, errnum, message, va_alist Line 256  error (status, errnum, message, va_alist
256    va_list args;    va_list args;
257  #endif  #endif
258    
259      fflush (stdout);
260    #ifdef _LIBC
261    # ifdef USE_IN_LIBIO
262      _IO_flockfile (stderr);
263    # else
264      __flockfile (stderr);
265    # endif
266    #endif
267    if (error_print_progname)    if (error_print_progname)
268      (*error_print_progname) ();      (*error_print_progname) ();
269    else    else
270      {      {
271        fflush (stdout);  #if _LIBC && USE_IN_LIBIO
272        fprintf (stderr, "%s: ", program_name);        if (_IO_fwide (stderr, 0) > 0)
273            __fwprintf (stderr, L"%s: ", program_name);
274          else
275    #endif
276            fprintf (stderr, "%s: ", program_name);
277      }      }
278    
279  #ifdef VA_START  #ifdef VA_START
280    VA_START (args, message);    VA_START (args, message);
281  # if HAVE_VPRINTF || _LIBC    error_tail (status, errnum, message, args);
   vfprintf (stderr, message, args);  
 # else  
   _doprnt (message, args, stderr);  
 # endif  
   va_end (args);  
282  #else  #else
283    fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);    fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
 #endif  
284    
285    ++error_message_count;    ++error_message_count;
286    if (errnum)    if (errnum)
287      {      print_errno_message (errnum);
 #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);  
 # endif  
 #else  
       fprintf (stderr, ": %s", strerror (errnum));  
 #endif  
     }  
288    putc ('\n', stderr);    putc ('\n', stderr);
289    fflush (stderr);    fflush (stderr);
290    if (status)    if (status)
291      exit (status);      exit (status);
292    #endif
293    
294    #ifdef _LIBC
295    # ifdef USE_IN_LIBIO
296      _IO_funlockfile (stderr);
297    # else
298      __funlockfile (stderr);
299    # endif
300    #endif
301  }  }
302    
303  /* Sometimes we want to have at most one error per line.  This  /* Sometimes we want to have at most one error per line.  This
# Line 212  error_at_line (status, errnum, file_name Line 327  error_at_line (status, errnum, file_name
327        static const char *old_file_name;        static const char *old_file_name;
328        static unsigned int old_line_number;        static unsigned int old_line_number;
329    
330        if (old_line_number == line_number &&        if (old_line_number == line_number
331            (file_name == old_file_name || !strcmp (old_file_name, file_name)))            && (file_name == old_file_name
332                  || strcmp (old_file_name, file_name) == 0))
333          /* Simply return and print nothing.  */          /* Simply return and print nothing.  */
334          return;          return;
335    
# Line 221  error_at_line (status, errnum, file_name Line 337  error_at_line (status, errnum, file_name
337        old_line_number = line_number;        old_line_number = line_number;
338      }      }
339    
340      fflush (stdout);
341    #ifdef _LIBC
342    # ifdef USE_IN_LIBIO
343      _IO_flockfile (stderr);
344    # else
345      __flockfile (stderr);
346    # endif
347    #endif
348    if (error_print_progname)    if (error_print_progname)
349      (*error_print_progname) ();      (*error_print_progname) ();
350    else    else
351      {      {
352        fflush (stdout);  #if _LIBC && USE_IN_LIBIO
353        fprintf (stderr, "%s:", program_name);        if (_IO_fwide (stderr, 0) > 0)
354            __fwprintf (stderr, L"%s: ", program_name);
355          else
356    #endif
357            fprintf (stderr, "%s:", program_name);
358      }      }
359    
360    if (file_name != NULL)    if (file_name != NULL)
361      fprintf (stderr, "%s:%d: ", file_name, line_number);      {
362    #if _LIBC && USE_IN_LIBIO
363          if (_IO_fwide (stderr, 0) > 0)
364            __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
365          else
366    #endif
367            fprintf (stderr, "%s:%d: ", file_name, line_number);
368        }
369    
370  #ifdef VA_START  #ifdef VA_START
371    VA_START (args, message);    VA_START (args, message);
372  # if HAVE_VPRINTF || _LIBC    error_tail (status, errnum, message, args);
   vfprintf (stderr, message, args);  
 # else  
   _doprnt (message, args, stderr);  
 # endif  
   va_end (args);  
373  #else  #else
374    fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);    fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
 #endif  
375    
376    ++error_message_count;    ++error_message_count;
377    if (errnum)    if (errnum)
378      {      print_errno_message (errnum);
 #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);  
 # endif  
 #else  
       fprintf (stderr, ": %s", strerror (errnum));  
 #endif  
     }  
379    putc ('\n', stderr);    putc ('\n', stderr);
380    fflush (stderr);    fflush (stderr);
381    if (status)    if (status)
382      exit (status);      exit (status);
383    #endif
384    
385    #ifdef _LIBC
386    # ifdef USE_IN_LIBIO
387      _IO_funlockfile (stderr);
388    # else
389      __funlockfile (stderr);
390    # endif
391    #endif
392  }  }
393    
394  #ifdef _LIBC  #ifdef _LIBC

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26