Mon, 17 Jan 2005 22:02:09 +0100
trunk: changeset 1934
Fixed everything that requires locale stuff to check CF_NO_LOCALE.
61 | 1 | /* |
2 | * libtu/errorlog.c | |
3 | * | |
4 | * Copyright (c) Tuomo Valkonen 1999-2004. | |
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 | #include <string.h> | |
11 | #include <errno.h> | |
12 | #include <stdio.h> | |
13 | ||
14 | #include "util.h" | |
15 | #include "types.h" | |
16 | #include "output.h" | |
17 | #include "misc.h" | |
18 | #include "errorlog.h" | |
19 | ||
20 | static ErrorLog *current_log=NULL; | |
21 | ||
22 | static void add_to_log(ErrorLog *el, const char *message, int l) | |
23 | { | |
62 | 24 | if(message==NULL) |
25 | return; | |
26 | ||
27 | /* Also write to stderr */ | |
28 | fwrite(message, sizeof(char), l, stderr); | |
61 | 29 | |
62 | 30 | if(el==NULL) |
31 | return; | |
32 | ||
33 | if(el->file!=NULL){ | |
34 | el->errors=TRUE; | |
35 | fwrite(message, sizeof(char), l, el->file); | |
36 | return; | |
37 | } | |
61 | 38 | |
62 | 39 | if(el->msgs==NULL){ |
40 | el->msgs=ALLOC_N(char, ERRORLOG_MAX_SIZE); | |
41 | if(el->msgs==NULL){ | |
42 | fprintf(stderr, "%s: %s\n", prog_execname(), strerror(errno)); | |
43 | return; | |
44 | } | |
45 | el->msgs[0]=0; | |
46 | el->msgs_len=0; | |
47 | } | |
48 | ||
49 | el->errors=TRUE; | |
50 | ||
51 | if(l+el->msgs_len>ERRORLOG_MAX_SIZE-1){ | |
52 | int n=0; | |
53 | if(l<ERRORLOG_MAX_SIZE-1){ | |
54 | n=ERRORLOG_MAX_SIZE-1-l; | |
55 | memmove(el->msgs, el->msgs+el->msgs_len-n, n); | |
56 | } | |
57 | memcpy(el->msgs+n, message+l-(ERRORLOG_MAX_SIZE-1-n), | |
58 | ERRORLOG_MAX_SIZE-1-n); | |
59 | el->msgs[ERRORLOG_MAX_SIZE]='\0'; | |
60 | el->msgs_len=ERRORLOG_MAX_SIZE-1; | |
61 | }else{ | |
62 | memcpy(el->msgs+el->msgs_len, message, l); | |
63 | el->msgs[el->msgs_len+l]='\0'; | |
64 | el->msgs_len+=l; | |
65 | } | |
61 | 66 | } |
67 | ||
68 | ||
69 | static void log_warn_handler(const char *message) | |
70 | { | |
62 | 71 | const char *p=strchr(message, '\n'); |
72 | static int lineno=0; | |
73 | int alternat=0; | |
74 | ||
75 | add_to_log(current_log, lineno==0 ? ">> " : " ", 3); | |
76 | ||
77 | if(p!=NULL){ | |
78 | add_to_log(current_log, message, p-message+1); | |
79 | lineno++; | |
80 | log_warn_handler(p+1); | |
81 | lineno--; | |
82 | return; | |
83 | } | |
84 | ||
85 | add_to_log(current_log, message, strlen(message)); | |
86 | add_to_log(current_log, "\n", 1); | |
61 | 87 | } |
88 | ||
62 | 89 | |
61 | 90 | void errorlog_begin_file(ErrorLog *el, FILE *file) |
91 | { | |
62 | 92 | el->msgs=NULL; |
93 | el->msgs_len=0; | |
94 | el->file=file; | |
95 | el->prev=current_log; | |
96 | el->errors=FALSE; | |
97 | el->old_handler=set_warn_handler(log_warn_handler); | |
98 | current_log=el; | |
61 | 99 | } |
100 | ||
101 | ||
102 | void errorlog_begin(ErrorLog *el) | |
103 | { | |
62 | 104 | errorlog_begin_file(el, NULL); |
61 | 105 | } |
106 | ||
107 | ||
108 | bool errorlog_end(ErrorLog *el) | |
109 | { | |
62 | 110 | current_log=el->prev; |
111 | set_warn_handler(el->old_handler); | |
112 | el->prev=NULL; | |
113 | el->old_handler=NULL; | |
114 | return el->errors; | |
61 | 115 | } |
116 | ||
117 | ||
118 | void errorlog_deinit(ErrorLog *el) | |
119 | { | |
62 | 120 | if(el->msgs!=NULL) |
121 | free(el->msgs); | |
122 | el->msgs=NULL; | |
123 | el->msgs_len=0; | |
124 | el->file=NULL; | |
125 | el->errors=FALSE; | |
61 | 126 | } |
127 |