xref: /netbsd-src/external/gpl3/gcc.old/dist/libiberty/xstrerror.c (revision 1debfc3d3fad8af6f31804271c18e67f77b4d718)
1*1debfc3dSmrg /* xstrerror.c -- jacket routine for more robust strerror() usage.
2*1debfc3dSmrg    Fri Jun 16 18:30:00 1995  Pat Rankin  <rankin@eql.caltech.edu>
3*1debfc3dSmrg    This code is in the public domain.  */
4*1debfc3dSmrg 
5*1debfc3dSmrg /*
6*1debfc3dSmrg 
7*1debfc3dSmrg @deftypefn Replacement char* xstrerror (int @var{errnum})
8*1debfc3dSmrg 
9*1debfc3dSmrg Behaves exactly like the standard @code{strerror} function, but
10*1debfc3dSmrg will never return a @code{NULL} pointer.
11*1debfc3dSmrg 
12*1debfc3dSmrg @end deftypefn
13*1debfc3dSmrg 
14*1debfc3dSmrg */
15*1debfc3dSmrg 
16*1debfc3dSmrg #include <stdio.h>
17*1debfc3dSmrg 
18*1debfc3dSmrg #include "config.h"
19*1debfc3dSmrg #include "libiberty.h"
20*1debfc3dSmrg 
21*1debfc3dSmrg #ifdef VMS
22*1debfc3dSmrg #  include <errno.h>
23*1debfc3dSmrg #  if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
24*1debfc3dSmrg #    ifdef __cplusplus
25*1debfc3dSmrg extern "C" {
26*1debfc3dSmrg #    endif /* __cplusplus */
27*1debfc3dSmrg extern char *strerror (int,...);
28*1debfc3dSmrg #    define DONT_DECLARE_STRERROR
29*1debfc3dSmrg #    ifdef __cplusplus
30*1debfc3dSmrg }
31*1debfc3dSmrg #    endif /* __cplusplus */
32*1debfc3dSmrg #  endif
33*1debfc3dSmrg #endif  /* VMS */
34*1debfc3dSmrg 
35*1debfc3dSmrg 
36*1debfc3dSmrg #ifndef DONT_DECLARE_STRERROR
37*1debfc3dSmrg #  ifdef __cplusplus
38*1debfc3dSmrg extern "C" {
39*1debfc3dSmrg #  endif /* __cplusplus */
40*1debfc3dSmrg extern char *strerror (int);
41*1debfc3dSmrg #  ifdef __cplusplus
42*1debfc3dSmrg }
43*1debfc3dSmrg #  endif /* __cplusplus */
44*1debfc3dSmrg #endif
45*1debfc3dSmrg 
46*1debfc3dSmrg /* If strerror returns NULL, we'll format the number into a static buffer.  */
47*1debfc3dSmrg 
48*1debfc3dSmrg #define ERRSTR_FMT "undocumented error #%d"
49*1debfc3dSmrg static char xstrerror_buf[sizeof ERRSTR_FMT + 20];
50*1debfc3dSmrg 
51*1debfc3dSmrg /* Like strerror, but result is never a null pointer.  */
52*1debfc3dSmrg 
53*1debfc3dSmrg char *
xstrerror(int errnum)54*1debfc3dSmrg xstrerror (int errnum)
55*1debfc3dSmrg {
56*1debfc3dSmrg   char *errstr;
57*1debfc3dSmrg #ifdef VMS
58*1debfc3dSmrg   char *(*vmslib_strerror) (int,...);
59*1debfc3dSmrg 
60*1debfc3dSmrg   /* Override any possibly-conflicting declaration from system header.  */
61*1debfc3dSmrg   vmslib_strerror = (char *(*) (int,...)) strerror;
62*1debfc3dSmrg   /* Second argument matters iff first is EVMSERR, but it's simpler to
63*1debfc3dSmrg      pass it unconditionally.  `vaxc$errno' is declared in <errno.h>
64*1debfc3dSmrg      and maintained by the run-time library in parallel to `errno'.
65*1debfc3dSmrg      We assume that `errnum' corresponds to the last value assigned to
66*1debfc3dSmrg      errno by the run-time library, hence vaxc$errno will be relevant.  */
67*1debfc3dSmrg   errstr = (*vmslib_strerror) (errnum, vaxc$errno);
68*1debfc3dSmrg #else
69*1debfc3dSmrg   errstr = strerror (errnum);
70*1debfc3dSmrg #endif
71*1debfc3dSmrg 
72*1debfc3dSmrg   /* If `errnum' is out of range, result might be NULL.  We'll fix that.  */
73*1debfc3dSmrg   if (!errstr)
74*1debfc3dSmrg     {
75*1debfc3dSmrg       sprintf (xstrerror_buf, ERRSTR_FMT, errnum);
76*1debfc3dSmrg       errstr = xstrerror_buf;
77*1debfc3dSmrg     }
78*1debfc3dSmrg   return errstr;
79*1debfc3dSmrg }
80