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