1 /* error.c -- Error reporting routines for Khepera
2 * Created: Wed Dec 21 12:55:00 1994 by faith@dict.org
3 * Copyright 1994-1997, 2002 Rickard E. Faith (faith@dict.org)
4 * Copyright 2002-2008 Aleksey Cheusov (vle@gmx.net)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * \section{Error Reporting Routines}
26 *
27 * \intro Several error reporting routines are provided. These routines
28 * are always used to print errors generated within the \khepera library,
29 * and are available for the programmer as well.
30 *
31 */
32
33 #include "maaP.h"
34 #include <errno.h>
35
36 const char *_err_programName;
37
38 /* \doc |err_set_program_name| records the value of |argv[0]| for the
39 calling program. If this value is not "NULL", then it will be used when
40 printing errors and warnings. */
41
err_set_program_name(const char * programName)42 void err_set_program_name(const char *programName)
43 {
44 if (!programName){
45 _err_programName = programName;
46 return;
47 }
48
49 const char *pt =strrchr(programName, '/');
50
51 if (pt)
52 _err_programName = pt + 1;
53 else
54 _err_programName = programName;
55 }
56
57 /* \doc |err_program_name| returns the value of |programName| that was
58 previously set with |err_set_program_name|. This value may be
59 "NULL". */
60
err_program_name(void)61 const char *err_program_name(void)
62 {
63 return _err_programName;
64 }
65
66
67 /* \doc |err_fatal| flushes "stdout", prints a fatal error report on
68 "stderr", flushes "stderr" and "stdout", and calls |exit|. |routine| is
69 the name of the routine in which the error took place. */
70
err_fatal(const char * routine,const char * format,...)71 void err_fatal(const char *routine, const char *format, ...)
72 {
73 va_list ap;
74 va_list ap_copy;
75
76 fflush(stdout);
77 if (_err_programName) {
78 if (routine)
79 fprintf(stderr, "%s (%s): ", _err_programName, routine);
80 else
81 fprintf(stderr, "%s: ", _err_programName);
82 } else {
83 if (routine) fprintf(stderr, "%s: ", routine);
84 }
85
86 va_start(ap, format);
87 va_copy(ap_copy, ap);
88
89 vfprintf(stderr, format, ap);
90 fprintf(stderr, "\n");
91 log_error_va(routine, format, ap_copy);
92
93 va_end(ap);
94
95 fflush(stderr);
96 fflush(stdout);
97 exit (1);
98 }
99
100 /* \doc |err_fatal_errno| flushes "stdout", prints a fatal error report on
101 "stderr", prints the system error corresponding to |errno|, flushes
102 "stderr" and "stdout", and calls |exit|. |routine| is the name of the
103 routine in which the error took place. */
104
err_fatal_errno(const char * routine,const char * format,...)105 void err_fatal_errno(const char *routine, const char *format, ...)
106 {
107 va_list ap;
108 va_list ap_copy;
109 int errorno = errno;
110
111 fflush(stdout);
112 if (_err_programName) {
113 if (routine)
114 fprintf(stderr, "%s (%s): ", _err_programName, routine);
115 else
116 fprintf(stderr, "%s: ", _err_programName);
117 } else {
118 if (routine) fprintf(stderr, "%s: ", routine);
119 }
120
121 va_start(ap, format);
122 va_copy(ap_copy, ap);
123
124 vfprintf(stderr, format, ap);
125 log_error_va(routine, format, ap_copy);
126
127 va_end(ap);
128
129 fprintf(stderr, " %s: %s\n", routine, strerror(errorno));
130 log_error(routine, "%s: %s", routine, strerror(errorno));
131
132 fflush(stderr);
133 fflush(stdout);
134 exit(1);
135 }
136
137 /* \doc |err_warning| flushes "stdout", prints a non-fatal warning on
138 "stderr", and returns to the caller. |routine| is the name of the
139 calling routine. */
140
err_warning(const char * routine,const char * format,...)141 void err_warning(const char *routine, const char *format, ...)
142 {
143 va_list ap;
144 va_list ap_copy;
145
146 fflush(stdout);
147 fflush(stderr);
148 if (_err_programName) {
149 if (routine)
150 fprintf(stderr, "%s (%s): ", _err_programName, routine);
151 else
152 fprintf(stderr, "%s: ", _err_programName);
153 } else {
154 if (routine) fprintf(stderr, "%s: ", routine);
155 }
156
157 va_start(ap, format);
158 va_copy(ap_copy, ap);
159
160 vfprintf(stderr, format, ap);
161 fprintf(stderr, "\n");
162 log_error_va(routine, format, ap_copy);
163
164 va_end(ap);
165 }
166
167 /* \doc |err_internal| flushes "stdout", prints the fatal error message,
168 flushes "stderr" and "stdout", and calls |abort| so that a core dump is
169 generated. */
170
err_internal(const char * routine,const char * format,...)171 void err_internal(const char *routine, const char *format, ...)
172 {
173 va_list ap;
174 va_list ap_copy;
175
176 va_start(ap, format);
177 va_copy(ap_copy, ap);
178
179 fflush(stdout);
180 if (_err_programName) {
181 if (routine)
182 fprintf(stderr, "%s (%s): Internal error\n ",
183 _err_programName, routine);
184 else
185 fprintf(stderr, "%s: Internal error\n ", _err_programName);
186 } else {
187 if (routine) fprintf(stderr, "%s: Internal error\n ", routine);
188 else fprintf(stderr, "Internal error\n ");
189 }
190
191 vfprintf(stderr, format, ap);
192 fprintf(stderr, "\n");
193 log_error_va(routine, format, ap_copy);
194
195 va_end(ap);
196
197 if (_err_programName)
198 fprintf(stderr, "Aborting %s...\n", _err_programName);
199 else
200 fprintf(stderr, "Aborting...\n");
201 fflush(stderr);
202 fflush(stdout);
203 abort();
204 }
205