| 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 } |