Released version 3-2015061300
[notion.git] / libtu / output.c
blob5b6fdc356687457080e3eb93deec3300ff246d97
1 /*
2 * libtu/output.c
4 * Copyright (c) Tuomo Valkonen 1999-2002.
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 */
10 #if HAS_SYSTEM_ASPRINTF
11 #define _GNU_SOURCE
12 #endif
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <strings.h>
18 #include <string.h>
20 #include "misc.h"
21 #include "output.h"
22 #include "util.h"
23 #include "private.h"
25 #if !HAS_SYSTEM_ASPRINTF
26 #include "snprintf_2.2/snprintf.c"
27 #endif
30 static void default_warn_handler(const char *message);
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;
38 #define INDENTATOR_LENGTH 4
40 static char indentator[]={' ', ' ', ' ', ' '};
42 static void do_dispatch_message(const char *message);
45 void verbose(const char *p, ...)
47 va_list args;
49 va_start(args, p);
51 verbose_v(p, args);
53 va_end(args);
57 void verbose_v(const char *p, va_list args)
59 int i;
61 if(verbose_mode){
62 for(i=0; i<verbose_indent_lvl; i++)
63 writef(stdout, indentator, INDENTATOR_LENGTH);
65 vprintf(p, args);
66 fflush(stdout);
71 void verbose_enable(bool enable)
73 verbose_mode=enable;
77 int verbose_indent(int depth)
79 int old=verbose_indent_lvl;
81 if(depth>=0)
82 verbose_indent_lvl=depth;
84 return old;
88 void warn_progname_enable(bool enable)
90 progname_enable=enable;
94 static void put_prog_name()
96 const char*progname;
98 if(!progname_enable)
99 return;
101 progname=libtu_progname();
103 if(progname==NULL)
104 return;
106 fprintf(stderr, "%s: ", (char*)progname);
109 /* warn
113 static void fallback_warn()
115 put_prog_name();
116 fprintf(stderr, TR("Oops. Error string compilation failed: %s"),
117 strerror(errno));
121 #define CALL_V(NAME, ARGS) \
122 do { va_list args; va_start(args, p); NAME ARGS; va_end(args); } while(0)
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(); \
133 }while(0)
136 void libtu_asprintf(char **ret, const char *p, ...)
138 *ret=NULL;
139 CALL_V(vasprintf, (ret, p, args));
140 if(*ret==NULL)
141 warn_err();
145 void libtu_vasprintf(char **ret, const char *p, va_list args)
147 *ret=NULL;
148 vasprintf(ret, p, args);
149 if(*ret==NULL)
150 warn_err();
154 void warn(const char *p, ...)
156 CALL_V(warn_v, (p, args));
160 void warn_obj(const char *obj, const char *p, ...)
162 CALL_V(warn_obj_v, (obj, p, args));
166 void warn_obj_line(const char *obj, int line, const char *p, ...)
168 CALL_V(warn_obj_line_v, (obj, line, p, args));
172 void warn_obj_v(const char *obj, const char *p, va_list args)
174 warn_obj_line_v(obj, -1, p, args);
178 void warn_v(const char *p, va_list args)
180 DO_DISPATCH(errmsg_v, (p, args));
184 void warn_obj_line_v(const char *obj, int line, const char *p, va_list args)
186 DO_DISPATCH(errmsg_obj_line_v, (obj, line, p, args));
190 void warn_err()
192 DO_DISPATCH(errmsg_err, ());
196 void warn_err_obj(const char *obj)
198 DO_DISPATCH(errmsg_err_obj, (obj));
201 void warn_err_obj_line(const char *obj, int line)
203 DO_DISPATCH(errmsg_err_obj_line, (obj, line));
207 /* errmsg
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;
215 char* errmsg(const char *p, ...)
217 CALL_V_RET(errmsg_v, (p, args));
221 char *errmsg_obj(const char *obj, const char *p, ...)
223 CALL_V_RET(errmsg_obj_v, (obj, p, args));
227 char *errmsg_obj_line(const char *obj, int line, const char *p, ...)
229 CALL_V_RET(errmsg_obj_line_v, (obj, line, p, args));
233 char* errmsg_obj_v(const char *obj, const char *p, va_list args)
235 return errmsg_obj_line_v(obj, -1, p, args);
239 char *errmsg_v(const char *p, va_list args)
241 char *res;
242 libtu_vasprintf(&res, p, args);
243 return res;
247 char *errmsg_obj_line_v(const char *obj, int line, const char *p, va_list args)
249 char *res1=NULL, *res2, *res3;
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);
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;
269 return res2;
273 char *errmsg_err()
275 char *res;
276 libtu_asprintf(&res, "%s\n", strerror(errno));
277 return res;
281 char *errmsg_err_obj(const char *obj)
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;
292 char *errmsg_err_obj_line(const char *obj, int line)
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));
306 return res;
310 /* die
314 void die(const char *p, ...)
316 set_warn_handler(NULL);
317 CALL_V(die_v, (p, args));
321 void die_v(const char *p, va_list args)
323 set_warn_handler(NULL);
324 warn_v(p, args);
325 exit(EXIT_FAILURE);
329 void die_obj(const char *obj, const char *p, ...)
331 set_warn_handler(NULL);
332 CALL_V(die_obj_v, (obj, p, args));
336 void die_obj_line(const char *obj, int line, const char *p, ...)
338 set_warn_handler(NULL);
339 CALL_V(die_obj_line_v, (obj, line, p, args));
343 void die_obj_v(const char *obj, const char *p, va_list args)
345 set_warn_handler(NULL);
346 warn_obj_v(obj, p, args);
347 exit(EXIT_FAILURE);
351 void die_obj_line_v(const char *obj, int line, const char *p, va_list args)
353 set_warn_handler(NULL);
354 warn_obj_line_v(obj, line, p, args);
355 exit(EXIT_FAILURE);
359 void die_err()
361 set_warn_handler(NULL);
362 warn_err();
363 exit(EXIT_FAILURE);
367 void die_err_obj(const char *obj)
369 set_warn_handler(NULL);
370 warn_err_obj(obj);
371 exit(EXIT_FAILURE);
375 void die_err_obj_line(const char *obj, int line)
377 set_warn_handler(NULL);
378 warn_err_obj_line(obj, line);
379 exit(EXIT_FAILURE);
383 static void default_warn_handler(const char *message)
385 put_prog_name();
386 fprintf(stderr, "%s", message);
387 putc('\n', stderr);
391 static void do_dispatch_message(const char *message)
393 if(current_warn_handler!=NULL)
394 current_warn_handler(message);
395 else
396 default_warn_handler(message);
400 WarnHandler *set_warn_handler(WarnHandler *handler)
402 WarnHandler *old=current_warn_handler;
403 current_warn_handler=(handler!=NULL ? handler : default_warn_handler);
404 return old;