19 |
19 |
20 static ErrorLog *current_log=NULL; |
20 static ErrorLog *current_log=NULL; |
21 |
21 |
22 static void add_to_log(ErrorLog *el, const char *message, int l) |
22 static void add_to_log(ErrorLog *el, const char *message, int l) |
23 { |
23 { |
24 if(message==NULL) |
24 if(message==NULL) |
25 return; |
25 return; |
26 |
26 |
27 /* Also write to stderr */ |
27 /* Also write to stderr */ |
28 fwrite(message, sizeof(char), l, stderr); |
28 fwrite(message, sizeof(char), l, stderr); |
29 |
29 |
30 if(el==NULL) |
30 if(el==NULL) |
31 return; |
31 return; |
32 |
32 |
33 if(el->file!=NULL){ |
33 if(el->file!=NULL){ |
34 el->errors=TRUE; |
34 el->errors=TRUE; |
35 fwrite(message, sizeof(char), l, el->file); |
35 fwrite(message, sizeof(char), l, el->file); |
36 return; |
36 return; |
37 } |
37 } |
38 |
38 |
39 if(el->msgs==NULL){ |
39 if(el->msgs==NULL){ |
40 el->msgs=ALLOC_N(char, ERRORLOG_MAX_SIZE); |
40 el->msgs=ALLOC_N(char, ERRORLOG_MAX_SIZE); |
41 if(el->msgs==NULL){ |
41 if(el->msgs==NULL){ |
42 fprintf(stderr, "%s: %s\n", prog_execname(), strerror(errno)); |
42 fprintf(stderr, "%s: %s\n", prog_execname(), strerror(errno)); |
43 return; |
43 return; |
44 } |
44 } |
45 el->msgs[0]=0; |
45 el->msgs[0]=0; |
46 el->msgs_len=0; |
46 el->msgs_len=0; |
47 } |
47 } |
48 |
48 |
49 el->errors=TRUE; |
49 el->errors=TRUE; |
50 |
50 |
51 if(l+el->msgs_len>ERRORLOG_MAX_SIZE-1){ |
51 if(l+el->msgs_len>ERRORLOG_MAX_SIZE-1){ |
52 int n=0; |
52 int n=0; |
53 if(l<ERRORLOG_MAX_SIZE-1){ |
53 if(l<ERRORLOG_MAX_SIZE-1){ |
54 n=ERRORLOG_MAX_SIZE-1-l; |
54 n=ERRORLOG_MAX_SIZE-1-l; |
55 memmove(el->msgs, el->msgs+el->msgs_len-n, n); |
55 memmove(el->msgs, el->msgs+el->msgs_len-n, n); |
56 } |
56 } |
57 memcpy(el->msgs+n, message+l-(ERRORLOG_MAX_SIZE-1-n), |
57 memcpy(el->msgs+n, message+l-(ERRORLOG_MAX_SIZE-1-n), |
58 ERRORLOG_MAX_SIZE-1-n); |
58 ERRORLOG_MAX_SIZE-1-n); |
59 el->msgs[ERRORLOG_MAX_SIZE]='\0'; |
59 el->msgs[ERRORLOG_MAX_SIZE]='\0'; |
60 el->msgs_len=ERRORLOG_MAX_SIZE-1; |
60 el->msgs_len=ERRORLOG_MAX_SIZE-1; |
61 }else{ |
61 }else{ |
62 memcpy(el->msgs+el->msgs_len, message, l); |
62 memcpy(el->msgs+el->msgs_len, message, l); |
63 el->msgs[el->msgs_len+l]='\0'; |
63 el->msgs[el->msgs_len+l]='\0'; |
64 el->msgs_len+=l; |
64 el->msgs_len+=l; |
65 } |
65 } |
66 } |
66 } |
67 |
67 |
68 |
68 |
69 static void log_warn_handler(const char *message) |
69 static void log_warn_handler(const char *message) |
70 { |
70 { |
71 const char *p=strchr(message, '\n'); |
71 const char *p=strchr(message, '\n'); |
72 static int lineno=0; |
72 static int lineno=0; |
73 int alternat=0; |
73 int alternat=0; |
74 |
74 |
75 add_to_log(current_log, lineno==0 ? ">> " : " ", 3); |
75 add_to_log(current_log, lineno==0 ? ">> " : " ", 3); |
76 |
76 |
77 if(p!=NULL){ |
77 if(p!=NULL){ |
78 add_to_log(current_log, message, p-message+1); |
78 add_to_log(current_log, message, p-message+1); |
79 lineno++; |
79 lineno++; |
80 log_warn_handler(p+1); |
80 log_warn_handler(p+1); |
81 lineno--; |
81 lineno--; |
82 return; |
82 return; |
83 } |
83 } |
84 |
84 |
85 add_to_log(current_log, message, strlen(message)); |
85 add_to_log(current_log, message, strlen(message)); |
86 add_to_log(current_log, "\n", 1); |
86 add_to_log(current_log, "\n", 1); |
87 } |
87 } |
88 |
88 |
89 |
89 |
90 void errorlog_begin_file(ErrorLog *el, FILE *file) |
90 void errorlog_begin_file(ErrorLog *el, FILE *file) |
91 { |
91 { |
92 el->msgs=NULL; |
92 el->msgs=NULL; |
93 el->msgs_len=0; |
93 el->msgs_len=0; |
94 el->file=file; |
94 el->file=file; |
95 el->prev=current_log; |
95 el->prev=current_log; |
96 el->errors=FALSE; |
96 el->errors=FALSE; |
97 el->old_handler=set_warn_handler(log_warn_handler); |
97 el->old_handler=set_warn_handler(log_warn_handler); |
98 current_log=el; |
98 current_log=el; |
99 } |
99 } |
100 |
100 |
101 |
101 |
102 void errorlog_begin(ErrorLog *el) |
102 void errorlog_begin(ErrorLog *el) |
103 { |
103 { |
104 errorlog_begin_file(el, NULL); |
104 errorlog_begin_file(el, NULL); |
105 } |
105 } |
106 |
106 |
107 |
107 |
108 bool errorlog_end(ErrorLog *el) |
108 bool errorlog_end(ErrorLog *el) |
109 { |
109 { |
110 current_log=el->prev; |
110 current_log=el->prev; |
111 set_warn_handler(el->old_handler); |
111 set_warn_handler(el->old_handler); |
112 el->prev=NULL; |
112 el->prev=NULL; |
113 el->old_handler=NULL; |
113 el->old_handler=NULL; |
114 return el->errors; |
114 return el->errors; |
115 } |
115 } |
116 |
116 |
117 |
117 |
118 void errorlog_deinit(ErrorLog *el) |
118 void errorlog_deinit(ErrorLog *el) |
119 { |
119 { |
120 if(el->msgs!=NULL) |
120 if(el->msgs!=NULL) |
121 free(el->msgs); |
121 free(el->msgs); |
122 el->msgs=NULL; |
122 el->msgs=NULL; |
123 el->msgs_len=0; |
123 el->msgs_len=0; |
124 el->file=NULL; |
124 el->file=NULL; |
125 el->errors=FALSE; |
125 el->errors=FALSE; |
126 } |
126 } |
127 |
127 |