]> git.decadent.org.uk Git - ion3.git/blob - libtu/output.c
[svn-inject] Installing original source of ion3
[ion3.git] / libtu / output.c
1 /*
2  * libtu/output.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2002. 
5  *
6  * You may distribute and modify this library under the terms of either
7  * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
8  */
9
10 #if defined(HAS_SYSTEM_ASPRINTF)
11 #define _GNU_SOURCE
12 #endif
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <strings.h>
18 #include <string.h>
19
20 #include "misc.h"
21 #include "output.h"
22 #include "util.h"
23 #include "private.h"
24
25 #if !defined(HAS_SYSTEM_ASPRINTF)
26 #include "snprintf_2.2/snprintf.h"
27 #endif
28
29
30 static void default_warn_handler(const char *message);
31
32
33 static bool verbose_mode=FALSE;
34 static int verbose_indent_lvl=0;
35 static bool progname_enable=TRUE;
36 static WarnHandler *current_warn_handler=default_warn_handler;
37
38 #define INDENTATOR_LENGTH 4
39
40 static char indentator[]={' ', ' ', ' ', ' '};
41
42 static void do_dispatch_message(const char *message);
43
44
45 void verbose(const char *p, ...)
46 {
47     va_list args;
48     
49     va_start(args, p);
50     
51     verbose_v(p, args);
52     
53     va_end(args);
54 }
55            
56
57 void verbose_v(const char *p, va_list args)
58 {
59     int i;
60     
61     if(verbose_mode){
62         for(i=0; i<verbose_indent_lvl; i++)
63             writef(stdout, indentator, INDENTATOR_LENGTH);
64         
65         vprintf(p, args);
66         fflush(stdout);
67     }
68 }
69
70
71 void verbose_enable(bool enable)
72 {
73     verbose_mode=enable;
74 }
75
76
77 int verbose_indent(int depth)
78 {
79     int old=verbose_indent_lvl;
80     
81     if(depth>=0)
82         verbose_indent_lvl=depth;
83     
84     return old;
85 }
86         
87
88 void warn_progname_enable(bool enable)
89 {
90     progname_enable=enable;
91 }
92
93
94 static void put_prog_name()
95 {
96     const char*progname;
97     
98     if(!progname_enable)
99         return;
100     
101     progname=prog_execname();
102     
103     if(progname==NULL)
104         return;
105     
106     fprintf(stderr, "%s: ", (char*)progname);
107 }
108
109 /* warn
110  */
111
112
113 static void fallback_warn()
114 {
115     put_prog_name();
116     fprintf(stderr, TR("Oops. Error string compilation failed: %s"),
117             strerror(errno));
118 }
119     
120     
121 #define CALL_V(NAME, ARGS) \
122     do { va_list args; va_start(args, p); NAME ARGS; va_end(args); } while(0)
123
124 #define DO_DISPATCH(NAME, ARGS) \
125     do{ \
126         char *msg; \
127         if((msg=NAME ARGS)!=NULL){ \
128             do_dispatch_message(msg); \
129             free(msg);\
130         }else{ \
131             fallback_warn(); \
132         } \
133     }while(0)
134
135
136 void libtu_asprintf(char **ret, const char *p, ...)
137 {
138     *ret=NULL;
139     CALL_V(vasprintf, (ret, p, args));
140     if(*ret==NULL)
141         warn_err();
142 }
143
144
145 void libtu_vasprintf(char **ret, const char *p, va_list args)
146 {
147     *ret=NULL;
148     vasprintf(ret, p, args);
149     if(*ret==NULL)
150         warn_err();
151 }
152
153
154 void warn(const char *p, ...)
155 {
156     CALL_V(warn_v, (p, args));
157 }
158
159
160 void warn_obj(const char *obj, const char *p, ...)
161 {
162     CALL_V(warn_obj_v, (obj, p, args));
163 }
164
165
166 void warn_obj_line(const char *obj, int line, const char *p, ...)
167 {
168     CALL_V(warn_obj_line_v, (obj, line, p, args));
169 }
170
171
172 void warn_obj_v(const char *obj, const char *p, va_list args)
173 {
174     warn_obj_line_v(obj, -1, p, args);
175 }
176
177
178 void warn_v(const char *p, va_list args)
179 {
180     DO_DISPATCH(errmsg_v, (p, args));
181 }
182
183
184 void warn_obj_line_v(const char *obj, int line, const char *p, va_list args)
185 {
186     DO_DISPATCH(errmsg_obj_line_v, (obj, line, p, args));
187 }
188
189
190 void warn_err()
191 {
192     DO_DISPATCH(errmsg_err, ());
193 }
194
195
196 void warn_err_obj(const char *obj)
197 {
198     DO_DISPATCH(errmsg_err_obj, (obj));
199 }
200
201 void warn_err_obj_line(const char *obj, int line)
202 {
203     DO_DISPATCH(errmsg_err_obj_line, (obj, line));
204 }
205
206
207 /* errmsg
208  */
209
210 #define CALL_V_RET(NAME, ARGS) \
211     char *ret; va_list args; va_start(args, p); ret=NAME ARGS; \
212     va_end(args); return ret;
213
214
215 char* errmsg(const char *p, ...)
216 {
217     CALL_V_RET(errmsg_v, (p, args));
218 }
219
220
221 char *errmsg_obj(const char *obj, const char *p, ...)
222 {
223     CALL_V_RET(errmsg_obj_v, (obj, p, args));
224 }
225
226
227 char *errmsg_obj_line(const char *obj, int line, const char *p, ...)
228 {
229     CALL_V_RET(errmsg_obj_line_v, (obj, line, p, args));
230 }
231
232
233 char* errmsg_obj_v(const char *obj, const char *p, va_list args)
234 {
235     return errmsg_obj_line_v(obj, -1, p, args);
236 }
237
238
239 char *errmsg_v(const char *p, va_list args)
240 {
241     char *res;
242     libtu_vasprintf(&res, p, args);
243     return res;
244 }
245
246
247 char *errmsg_obj_line_v(const char *obj, int line, const char *p, va_list args)
248 {
249     char *res1=NULL, *res2, *res3;
250     
251     if(obj!=NULL){
252         if(line>0)
253             libtu_asprintf(&res1, "%s:%d: ", obj, line);
254         else        
255             libtu_asprintf(&res1, "%s: ", obj);
256     }else{
257         if(line>0)
258             libtu_asprintf(&res1, "%d: ", line);
259     }
260     libtu_vasprintf(&res2, p, args);
261     if(res1!=NULL){
262         if(res2==NULL)
263             return NULL;
264         res3=scat(res1, res2);
265         free(res1);
266         free(res2);
267         return res3;
268     }
269     return res2;
270 }
271
272
273 char *errmsg_err()
274 {
275     char *res;
276     libtu_asprintf(&res, "%s\n", strerror(errno));
277     return res;
278 }
279
280
281 char *errmsg_err_obj(const char *obj)
282 {
283     char *res;
284     if(obj!=NULL)
285         libtu_asprintf(&res, "%s: %s\n", obj, strerror(errno));
286     else
287         libtu_asprintf(&res, "%s\n", strerror(errno));
288     return res;
289 }
290
291
292 char *errmsg_err_obj_line(const char *obj, int line)
293 {
294     char *res;
295     if(obj!=NULL){
296         if(line>0)
297             libtu_asprintf(&res, "%s:%d: %s\n", obj, line, strerror(errno));
298         else
299             libtu_asprintf(&res, "%s: %s\n", obj, strerror(errno));
300     }else{
301         if(line>0)
302             libtu_asprintf(&res, "%d: %s\n", line, strerror(errno));
303         else
304             libtu_asprintf(&res, "%s\n", strerror(errno));
305     }
306     return res;
307 }
308
309
310 /* die
311  */
312
313
314 void die(const char *p, ...)
315 {
316     set_warn_handler(NULL);
317     CALL_V(die_v, (p, args));
318 }
319
320
321 void die_v(const char *p, va_list args)
322 {
323     set_warn_handler(NULL);
324     warn_v(p, args);
325     exit(EXIT_FAILURE);
326 }
327
328
329 void die_obj(const char *obj, const char *p, ...)
330 {
331     set_warn_handler(NULL);
332     CALL_V(die_obj_v, (obj, p, args));
333 }
334
335
336 void die_obj_line(const char *obj, int line, const char *p, ...)
337 {
338     set_warn_handler(NULL);
339     CALL_V(die_obj_line_v, (obj, line, p, args));
340 }
341
342
343 void die_obj_v(const char *obj, const char *p, va_list args)
344 {
345     set_warn_handler(NULL);
346     warn_obj_v(obj, p, args);
347     exit(EXIT_FAILURE);
348 }
349
350
351 void die_obj_line_v(const char *obj, int line, const char *p, va_list args)
352 {
353     set_warn_handler(NULL);
354     warn_obj_line_v(obj, line, p, args);
355     exit(EXIT_FAILURE);
356 }
357
358
359 void die_err()
360 {
361     set_warn_handler(NULL);
362     warn_err();
363     exit(EXIT_FAILURE);
364 }
365
366
367 void die_err_obj(const char *obj)
368 {
369     set_warn_handler(NULL);
370     warn_err_obj(obj);
371     exit(EXIT_FAILURE);
372 }
373
374
375 void die_err_obj_line(const char *obj, int line)
376 {
377     set_warn_handler(NULL);
378     warn_err_obj_line(obj, line);
379     exit(EXIT_FAILURE);
380 }
381
382
383 static void default_warn_handler(const char *message)
384 {
385     put_prog_name();
386     fprintf(stderr, "%s", message);
387     putc('\n', stderr);
388 }
389
390
391 static void do_dispatch_message(const char *message)
392 {
393     if(current_warn_handler!=NULL)
394         current_warn_handler(message);
395     else
396         default_warn_handler(message);
397 }
398
399
400 WarnHandler *set_warn_handler(WarnHandler *handler)
401 {
402     WarnHandler *old=current_warn_handler;
403     current_warn_handler=(handler!=NULL ? handler : default_warn_handler);
404     return old;
405 }