All the new audio stuff.
[jog] / err.c
CommitLineData
2ec1e693 1/* -*-c-*-
2 *
3 * $Id: err.c,v 1.1 2002/01/25 19:34:45 mdw Exp $
4 *
5 * Error reporting
6 *
7 * (c) 2001 Mark Wooding
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Jog: Programming for a jogging machine.
13 *
14 * Jog is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * Jog is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Jog; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: err.c,v $
32 * Revision 1.1 2002/01/25 19:34:45 mdw
33 * Initial revision
34 *
35 */
36
37/*----- Header files ------------------------------------------------------*/
38
39#ifdef HAVE_CONFIG_H
40# include "config.h"
41#endif
42
43#include <errno.h>
44#include <stdarg.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <time.h>
49
50#include <mLib/exc.h>
51#include <mLib/quis.h>
52
53/* #include "au.h" */
54#include "err.h"
55
56/*----- Static variables --------------------------------------------------*/
57
58static FILE *logfp = 0;
59static unsigned flags = 0;
60
61#define f_thread 1u
62
63/*----- Main code ---------------------------------------------------------*/
64
65/* --- @err_abort@ --- *
66 *
67 * Arguments: @int reason@ = abort reason code
68 * @unsigned long err@ = abort error code
69 * @const char *msg@ = error message
70 *
71 * Returns: Doesn't.
72 *
73 * Use: Reports a fatal error.
74 */
75
76void err_abortv(int reason, unsigned long err, const char *msg, va_list *ap)
77{
78 fprintf(stderr, "%s: fatal error (code %d-%lu): ", QUIS, reason, err);
79 vfprintf(stderr, msg, *ap);
80 putc('\n', stderr);
81 /* au_abort(reason, err); */
82 abort();
83}
84
85void err_abort(int reason, unsigned long err, const char *msg, ...)
86{
87 va_list ap;
88
89 va_start(ap, msg);
90 err_abortv(reason, err, msg, &ap);
91 va_end(ap);
92}
93
94/* --- @err_init@ --- *
95 *
96 * Arguments: ---
97 *
98 * Returns: ---
99 *
100 * Use: Attempts to initialize the logging system. It is a
101 * catastrophic failure if logging can't start up.
102 */
103
104static void err_exc(exc_extype ex, exc_exval v)
105{
106 switch (ex) {
107 case EXC_NOMEM:
108 err_report(ERR_EXC, 0, ex, "out of memory");
109 break;
110 default:
111 err_report(ERR_EXC, 0, ex, "uncaught mLib exception");
112 break;
113 }
114 exit(EXIT_FAILURE);
115}
116
117void err_init(void)
118{
119 const char *lf;
120
121 lf = getenv("JOG_LOGFILE");
122 if (!lf)
123 logfp = stderr;
124 else if ((logfp = fopen(lf, "w")) == 0) {
125 err_abort(ERRABORT_LOGOPEN, errno,
126 "couldn't open logfile `%s': %s", lf, strerror(errno));
127 }
128 exc_uncaught(err_exc);
129}
130
131/* --- @err_report@ --- *
132 *
133 * Arguments: @int ctx@ = context code
134 * @int reason@ = reason code
135 * @unsigned long err@ = system error code
136 * @const char *msg@ = textual message to log
137 *
138 * Returns: ---
139 *
140 * Use: Reports an error. Doesn't abort anything unless something
141 * really serious happens.
142 */
143
144void err_reportv(int ctx, int reason, unsigned long err,
145 const char *msg, va_list *ap)
146{
147 char buf[256];
148 time_t t;
149 struct tm *tm;
150
151 if (ctx && !(flags & f_thread)) {
152 unsigned f = flags;
153 flags |= f_thread;
154/* au_misc(AU_ERROR, ctx, reason, err); */
155 flags = f;
156 }
157 t = time(0);
158 tm = localtime(&t);
159 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
160 if (fputs(buf, logfp) == EOF ||
161 fprintf(stderr, " %s: ", QUIS) == EOF ||
162 vfprintf(logfp, msg, *ap) == EOF ||
163 (ctx && (fprintf(logfp, " (error %d", ctx) == EOF ||
164 (reason && fprintf(logfp, "-%d", reason) == EOF) ||
165 (err && fprintf(logfp, ":%lu", err) == EOF) ||
166 putc(')', logfp) == EOF)) ||
167 putc('\n', logfp) == EOF ||
168 fflush(logfp) == EOF) {
169 err_abort(ERRABORT_LOGWRITE, errno,
170 "error writing logfile: %s", strerror(errno));
171 }
172}
173
174void err_report(int ctx, int reason, unsigned long err, const char *msg, ...)
175{
176 va_list ap;
177
178 va_start(ap, msg);
179 err_reportv(ctx, reason, err, msg, &ap);
180 va_end(ap);
181}
182
183/* --- @err_log@ --- *
184 *
185 * Arguments: @const char *msg@ = textual message to log
186 *
187 * Returns: ---
188 *
189 * Use: Logs a message.
190 */
191
192void err_logv(const char *msg, va_list *ap)
193{
194 err_reportv(0, 0, 0, msg, ap);
195}
196
197void err_log(const char *msg, ...)
198{
199 va_list ap;
200
201 va_start(ap, msg);
202 err_reportv(0, 0, 0, msg, &ap);
203 va_end(ap);
204}
205
206/*----- That's all, folks -------------------------------------------------*/