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