PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/error.c

https://github.com/pinard/po-utils
C | 261 lines | 188 code | 30 blank | 43 comment | 32 complexity | 409209a4e3d6195f5d522fbac60d9677 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* Error handler for noninteractive utilities
  2. Copyright (C) 1990-2000 Free Software Foundation, Inc.
  3. 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.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with the GNU C Library; see the file COPYING.LIB. If not,
  15. write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. Boston, MA 02111-1307, USA. */
  17. /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
  18. #ifdef HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21. #include <stdio.h>
  22. #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
  23. # if __STDC__
  24. # include <stdarg.h>
  25. # define VA_START(args, lastarg) va_start(args, lastarg)
  26. # else
  27. # include <varargs.h>
  28. # define VA_START(args, lastarg) va_start(args)
  29. # endif
  30. #else
  31. # define va_alist a1, a2, a3, a4, a5, a6, a7, a8
  32. # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
  33. #endif
  34. #if STDC_HEADERS || _LIBC
  35. # include <stdlib.h>
  36. # include <string.h>
  37. #else
  38. void exit ();
  39. #endif
  40. #include "error.h"
  41. #ifndef _
  42. # define _(String) String
  43. #endif
  44. /* If NULL, error will flush stdout, then print on stderr the program
  45. name, a colon and a space. Otherwise, error will call this
  46. function without parameters instead. */
  47. void (*error_print_progname) (
  48. #if __STDC__ - 0
  49. void
  50. #endif
  51. );
  52. /* This variable is incremented each time `error' is called. */
  53. unsigned int error_message_count;
  54. #ifdef _LIBC
  55. /* In the GNU C library, there is a predefined variable for this. */
  56. # define program_name program_invocation_name
  57. # include <errno.h>
  58. /* In GNU libc we want do not want to use the common name `error' directly.
  59. Instead make it a weak alias. */
  60. # define error __error
  61. # define error_at_line __error_at_line
  62. #else /* not _LIBC */
  63. /* The calling program should define program_name and set it to the
  64. name of the executing program. */
  65. extern char *program_name;
  66. # ifdef HAVE_STRERROR_R
  67. # define __strerror_r strerror_r
  68. # else
  69. # if HAVE_STRERROR
  70. # ifndef strerror /* On some systems, strerror is a macro */
  71. char *strerror ();
  72. # endif
  73. # else
  74. static char *
  75. private_strerror (errnum)
  76. int errnum;
  77. {
  78. extern char *sys_errlist[];
  79. extern int sys_nerr;
  80. if (errnum > 0 && errnum <= sys_nerr)
  81. return _(sys_errlist[errnum]);
  82. return _("Unknown system error");
  83. }
  84. # define strerror private_strerror
  85. # endif /* HAVE_STRERROR */
  86. # endif /* HAVE_STRERROR_R */
  87. #endif /* not _LIBC */
  88. /* Print the program name and error message MESSAGE, which is a printf-style
  89. format string with optional args.
  90. If ERRNUM is nonzero, print its corresponding system error message.
  91. Exit with status STATUS if it is nonzero. */
  92. /* VARARGS */
  93. void
  94. #if defined VA_START && __STDC__
  95. error (int status, int errnum, const char *message, ...)
  96. #else
  97. error (status, errnum, message, va_alist)
  98. int status;
  99. int errnum;
  100. char *message;
  101. va_dcl
  102. #endif
  103. {
  104. #ifdef VA_START
  105. va_list args;
  106. #endif
  107. if (error_print_progname)
  108. (*error_print_progname) ();
  109. else
  110. {
  111. fflush (stdout);
  112. fprintf (stderr, "%s: ", program_name);
  113. }
  114. #ifdef VA_START
  115. VA_START (args, message);
  116. # if HAVE_VPRINTF || _LIBC
  117. vfprintf (stderr, message, args);
  118. # else
  119. _doprnt (message, args, stderr);
  120. # endif
  121. va_end (args);
  122. #else
  123. fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
  124. #endif
  125. ++error_message_count;
  126. if (errnum)
  127. {
  128. #if defined HAVE_STRERROR_R || _LIBC
  129. char errbuf[1024];
  130. # if HAVE_WORKING_STRERROR_R || _LIBC
  131. fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf));
  132. # else
  133. /* Don't use __strerror_r's return value because on some systems
  134. (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */
  135. __strerror_r (errnum, errbuf, sizeof errbuf);
  136. fprintf (stderr, ": %s", errbuf);
  137. # endif
  138. #else
  139. fprintf (stderr, ": %s", strerror (errnum));
  140. #endif
  141. }
  142. putc ('\n', stderr);
  143. fflush (stderr);
  144. if (status)
  145. exit (status);
  146. }
  147. /* Sometimes we want to have at most one error per line. This
  148. variable controls whether this mode is selected or not. */
  149. int error_one_per_line;
  150. void
  151. #if defined VA_START && __STDC__
  152. error_at_line (int status, int errnum, const char *file_name,
  153. unsigned int line_number, const char *message, ...)
  154. #else
  155. error_at_line (status, errnum, file_name, line_number, message, va_alist)
  156. int status;
  157. int errnum;
  158. const char *file_name;
  159. unsigned int line_number;
  160. char *message;
  161. va_dcl
  162. #endif
  163. {
  164. #ifdef VA_START
  165. va_list args;
  166. #endif
  167. if (error_one_per_line)
  168. {
  169. static const char *old_file_name;
  170. static unsigned int old_line_number;
  171. if (old_line_number == line_number &&
  172. (file_name == old_file_name || !strcmp (old_file_name, file_name)))
  173. /* Simply return and print nothing. */
  174. return;
  175. old_file_name = file_name;
  176. old_line_number = line_number;
  177. }
  178. if (error_print_progname)
  179. (*error_print_progname) ();
  180. else
  181. {
  182. fflush (stdout);
  183. fprintf (stderr, "%s:", program_name);
  184. }
  185. if (file_name != NULL)
  186. fprintf (stderr, "%s:%d: ", file_name, line_number);
  187. #ifdef VA_START
  188. VA_START (args, message);
  189. # if HAVE_VPRINTF || _LIBC
  190. vfprintf (stderr, message, args);
  191. # else
  192. _doprnt (message, args, stderr);
  193. # endif
  194. va_end (args);
  195. #else
  196. fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
  197. #endif
  198. ++error_message_count;
  199. if (errnum)
  200. {
  201. #if defined HAVE_STRERROR_R || _LIBC
  202. char errbuf[1024];
  203. # if HAVE_WORKING_STRERROR_R || _LIBC
  204. fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf));
  205. # else
  206. /* Don't use __strerror_r's return value because on some systems
  207. (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */
  208. __strerror_r (errnum, errbuf, sizeof errbuf);
  209. fprintf (stderr, ": %s", errbuf);
  210. # endif
  211. #else
  212. fprintf (stderr, ": %s", strerror (errnum));
  213. #endif
  214. }
  215. putc ('\n', stderr);
  216. fflush (stderr);
  217. if (status)
  218. exit (status);
  219. }
  220. #ifdef _LIBC
  221. /* Make the weak alias. */
  222. # undef error
  223. # undef error_at_line
  224. weak_alias (__error, error)
  225. weak_alias (__error_at_line, error_at_line)
  226. #endif