13 |
13 |
14 #include <libtu/misc.h> |
14 #include <libtu/misc.h> |
15 #include <libtu/output.h> |
15 #include <libtu/output.h> |
16 #include <libtu/util.h> |
16 #include <libtu/util.h> |
17 |
17 |
18 #if !defined(LIBTU_NO_ERRMSG) && !defined(HAS_SYSTEM_ASPRINTF) |
18 #if !defined(HAS_SYSTEM_ASPRINTF) |
19 #include "../snprintf_2.2/snprintf.h" |
19 #include "../snprintf_2.2/snprintf.h" |
20 #endif |
20 #endif |
21 |
21 |
22 |
22 |
23 /* verbose |
23 /* verbose |
24 */ |
24 */ |
25 |
25 |
26 static bool verbose_mode=FALSE; |
26 static bool verbose_mode=FALSE; |
27 static int verbose_indent_lvl=0; |
27 static int verbose_indent_lvl=0; |
28 static bool progname_enable=TRUE; |
28 static bool progname_enable=TRUE; |
|
29 static WarnHandler *current_warn_handler=NULL; |
29 |
30 |
30 #define INDENTATOR_LENGTH 4 |
31 #define INDENTATOR_LENGTH 4 |
31 |
32 |
32 static char indentator[]={' ', ' ', ' ', ' '}; |
33 static char indentator[]={' ', ' ', ' ', ' '}; |
|
34 |
|
35 static void do_dispatch_message(const char *message); |
33 |
36 |
34 |
37 |
35 void verbose(const char *p, ...) |
38 void verbose(const char *p, ...) |
36 { |
39 { |
37 va_list args; |
40 va_list args; |
97 } |
100 } |
98 |
101 |
99 /* warn |
102 /* warn |
100 */ |
103 */ |
101 |
104 |
|
105 |
|
106 static void fallback_warn() |
|
107 { |
|
108 put_prog_name(); |
|
109 fprintf(stderr, "Oops. Error string compilation failed: %s", |
|
110 strerror(errno)); |
|
111 } |
|
112 |
|
113 |
102 #define CALL_V(NAME, ARGS) \ |
114 #define CALL_V(NAME, ARGS) \ |
103 va_list args; va_start(args, p); NAME ARGS; va_end(args); |
115 do { va_list args; va_start(args, p); NAME ARGS; va_end(args); } while(0) |
104 |
116 |
105 |
117 #define DO_DISPATCH(NAME, ARGS) \ |
106 #ifndef LIBTU_NO_ERRMSG |
118 do{ \ |
|
119 char *msg; \ |
|
120 if((msg=NAME ARGS)!=NULL){ \ |
|
121 do_dispatch_message(msg); \ |
|
122 free(msg);\ |
|
123 }else{ \ |
|
124 fallback_warn(); \ |
|
125 } \ |
|
126 }while(0) |
|
127 |
107 |
128 |
108 void libtu_asprintf(char **ret, const char *p, ...) |
129 void libtu_asprintf(char **ret, const char *p, ...) |
109 { |
130 { |
110 CALL_V(vasprintf, (ret, p, args)); |
131 CALL_V(vasprintf, (ret, p, args)); |
111 } |
132 } |
142 } |
162 } |
143 |
163 |
144 |
164 |
145 void warn_v(const char *p, va_list args) |
165 void warn_v(const char *p, va_list args) |
146 { |
166 { |
147 put_prog_name(); |
167 DO_DISPATCH(errmsg_v, (p, args)); |
148 vfprintf(stderr, p, args); |
|
149 putc('\n', stderr); |
|
150 } |
168 } |
151 |
169 |
152 |
170 |
153 void warn_obj_line_v(const char *obj, int line, const char *p, va_list args) |
171 void warn_obj_line_v(const char *obj, int line, const char *p, va_list args) |
154 { |
172 { |
155 put_prog_name(); |
173 DO_DISPATCH(errmsg_obj_line_v, (obj, line, p, args)); |
156 if(obj!=NULL){ |
|
157 if(line>0) |
|
158 fprintf(stderr, TR("%s:%d: "), obj, line); |
|
159 else |
|
160 fprintf(stderr, "%s: ", obj); |
|
161 }else{ |
|
162 if(line>0) |
|
163 fprintf(stderr, TR("%d: "), line); |
|
164 } |
|
165 vfprintf(stderr, p, args); |
|
166 putc('\n', stderr); |
|
167 } |
174 } |
168 |
175 |
169 |
176 |
170 void warn_err() |
177 void warn_err() |
171 { |
178 { |
172 put_prog_name(); |
179 DO_DISPATCH(errmsg_err, ()); |
173 fprintf(stderr, "%s\n", strerror(errno)); |
|
174 } |
180 } |
175 |
181 |
176 |
182 |
177 void warn_err_obj(const char *obj) |
183 void warn_err_obj(const char *obj) |
178 { |
184 { |
179 put_prog_name(); |
185 DO_DISPATCH(errmsg_err_obj, (obj)); |
180 if(obj!=NULL) |
|
181 fprintf(stderr, "%s: %s\n", obj, strerror(errno)); |
|
182 else |
|
183 fprintf(stderr, "%s\n", strerror(errno)); |
|
184 } |
186 } |
185 |
187 |
186 void warn_err_obj_line(const char *obj, int line) |
188 void warn_err_obj_line(const char *obj, int line) |
187 { |
189 { |
188 put_prog_name(); |
190 DO_DISPATCH(errmsg_err_obj_line, (obj, line)); |
189 if(obj!=NULL){ |
|
190 if(line>0) |
|
191 fprintf(stderr, TR("%s:%d: %s\n"), obj, line, strerror(errno)); |
|
192 else |
|
193 fprintf(stderr, "%s: %s\n", obj, strerror(errno)); |
|
194 }else{ |
|
195 if(line>0) |
|
196 fprintf(stderr, TR("%d: %s\n"), line, strerror(errno)); |
|
197 else |
|
198 fprintf(stderr, TR("%s\n"), strerror(errno)); |
|
199 } |
|
200 |
|
201 } |
191 } |
202 |
192 |
203 |
193 |
204 /* errmsg |
194 /* errmsg |
205 */ |
195 */ |
206 #ifndef LIBTU_NO_ERRMSG |
|
207 |
196 |
208 #define CALL_V_RET(NAME, ARGS) \ |
197 #define CALL_V_RET(NAME, ARGS) \ |
209 char *ret; va_list args; va_start(args, p); ret=NAME ARGS; va_end(args); return ret; |
198 char *ret; va_list args; va_start(args, p); ret=NAME ARGS; \ |
|
199 va_end(args); return ret; |
210 |
200 |
211 |
201 |
212 char* errmsg(const char *p, ...) |
202 char* errmsg(const char *p, ...) |
213 { |
203 { |
214 CALL_V_RET(errmsg_v, (p, args)); |
204 CALL_V_RET(errmsg_v, (p, args)); |
242 |
232 |
243 |
233 |
244 char *errmsg_obj_line_v(const char *obj, int line, const char *p, va_list args) |
234 char *errmsg_obj_line_v(const char *obj, int line, const char *p, va_list args) |
245 { |
235 { |
246 char *res1=NULL, *res2, *res3; |
236 char *res1=NULL, *res2, *res3; |
|
237 |
247 if(obj!=NULL){ |
238 if(obj!=NULL){ |
248 if(line>0) |
239 if(line>0) |
249 asprintf(&res1, TR("%s:%d: "), obj, line); |
240 asprintf(&res1, TR("%s:%d: "), obj, line); |
250 else |
241 else |
251 asprintf(&res1, "%s: ", obj); |
242 asprintf(&res1, "%s: ", obj); |
252 }else{ |
243 }else{ |
253 if(line>0) |
244 if(line>0) |
254 asprintf(&res1, TR("%d: "), line); |
245 asprintf(&res1, TR("%d: "), line); |
255 } |
246 } |
256 asprintf(&res2, p, args); |
247 vasprintf(&res2, p, args); |
257 if(res1!=NULL){ |
248 if(res1!=NULL){ |
258 if(res2==NULL) |
249 if(res2==NULL) |
259 return NULL; |
250 return NULL; |
260 res3=scat(res1, res2); |
251 res3=scat(res1, res2); |
261 free(res1); |
252 free(res1); |
300 asprintf(&res, TR("%s\n"), strerror(errno)); |
291 asprintf(&res, TR("%s\n"), strerror(errno)); |
301 } |
292 } |
302 return res; |
293 return res; |
303 } |
294 } |
304 |
295 |
305 #endif /* LIBTU_NO_ERRMSG */ |
|
306 |
|
307 |
296 |
308 /* die |
297 /* die |
309 */ |
298 */ |
310 |
299 |
|
300 |
311 void die(const char *p, ...) |
301 void die(const char *p, ...) |
312 { |
302 { |
|
303 set_warn_handler(NULL); |
313 CALL_V(die_v, (p, args)); |
304 CALL_V(die_v, (p, args)); |
314 } |
305 } |
315 |
306 |
316 |
307 |
317 void die_v(const char *p, va_list args) |
308 void die_v(const char *p, va_list args) |
318 { |
309 { |
|
310 set_warn_handler(NULL); |
319 warn_v(p, args); |
311 warn_v(p, args); |
320 exit(EXIT_FAILURE); |
312 exit(EXIT_FAILURE); |
321 } |
313 } |
322 |
314 |
323 |
315 |
324 void die_obj(const char *obj, const char *p, ...) |
316 void die_obj(const char *obj, const char *p, ...) |
325 { |
317 { |
|
318 set_warn_handler(NULL); |
326 CALL_V(die_obj_v, (obj, p, args)); |
319 CALL_V(die_obj_v, (obj, p, args)); |
327 } |
320 } |
328 |
321 |
329 |
322 |
330 void die_obj_line(const char *obj, int line, const char *p, ...) |
323 void die_obj_line(const char *obj, int line, const char *p, ...) |
331 { |
324 { |
|
325 set_warn_handler(NULL); |
332 CALL_V(die_obj_line_v, (obj, line, p, args)); |
326 CALL_V(die_obj_line_v, (obj, line, p, args)); |
333 } |
327 } |
334 |
328 |
335 |
329 |
336 void die_obj_v(const char *obj, const char *p, va_list args) |
330 void die_obj_v(const char *obj, const char *p, va_list args) |
337 { |
331 { |
|
332 set_warn_handler(NULL); |
338 warn_obj_v(obj, p, args); |
333 warn_obj_v(obj, p, args); |
339 exit(EXIT_FAILURE); |
334 exit(EXIT_FAILURE); |
340 } |
335 } |
341 |
336 |
342 |
337 |
343 void die_obj_line_v(const char *obj, int line, const char *p, va_list args) |
338 void die_obj_line_v(const char *obj, int line, const char *p, va_list args) |
344 { |
339 { |
|
340 set_warn_handler(NULL); |
345 warn_obj_line_v(obj, line, p, args); |
341 warn_obj_line_v(obj, line, p, args); |
346 exit(EXIT_FAILURE); |
342 exit(EXIT_FAILURE); |
347 } |
343 } |
348 |
344 |
349 |
345 |
350 void die_err() |
346 void die_err() |
351 { |
347 { |
|
348 set_warn_handler(NULL); |
352 warn_err(); |
349 warn_err(); |
353 exit(EXIT_FAILURE); |
350 exit(EXIT_FAILURE); |
354 } |
351 } |
355 |
352 |
356 |
353 |
357 void die_err_obj(const char *obj) |
354 void die_err_obj(const char *obj) |
358 { |
355 { |
|
356 set_warn_handler(NULL); |
359 warn_err_obj(obj); |
357 warn_err_obj(obj); |
360 exit(EXIT_FAILURE); |
358 exit(EXIT_FAILURE); |
361 } |
359 } |
362 |
360 |
363 |
361 |
364 void die_err_obj_line(const char *obj, int line) |
362 void die_err_obj_line(const char *obj, int line) |
365 { |
363 { |
|
364 set_warn_handler(NULL); |
366 warn_err_obj_line(obj, line); |
365 warn_err_obj_line(obj, line); |
367 exit(EXIT_FAILURE); |
366 exit(EXIT_FAILURE); |
368 } |
367 } |
|
368 |
|
369 |
|
370 static void default_warn_handler(const char *message) |
|
371 { |
|
372 put_prog_name(); |
|
373 fprintf(stderr, "%s", message); |
|
374 putc('\n', stderr); |
|
375 } |
|
376 |
|
377 |
|
378 static void do_dispatch_message(const char *message) |
|
379 { |
|
380 if(current_warn_handler!=NULL) |
|
381 current_warn_handler(message); |
|
382 else |
|
383 default_warn_handler(message); |
|
384 } |
|
385 |
|
386 |
|
387 WarnHandler *set_warn_handler(WarnHandler *handler) |
|
388 { |
|
389 WarnHandler *old=current_warn_handler; |
|
390 current_warn_handler=handler; |
|
391 return old; |
|
392 } |