]> git.decadent.org.uk Git - ion3.git/blob - libtu/errorlog.c
[svn-inject] Installing original source of ion3
[ion3.git] / libtu / errorlog.c
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 {
24     if(message==NULL)
25         return;
26     
27     /* Also write to stderr */
28     fwrite(message, sizeof(char), l, stderr);
29
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     }
38
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     }
66 }
67
68
69 static void log_warn_handler(const char *message)
70 {
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);
87 }
88
89            
90 void errorlog_begin_file(ErrorLog *el, FILE *file)
91 {
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;
99 }
100
101
102 void errorlog_begin(ErrorLog *el)
103 {
104     errorlog_begin_file(el, NULL);
105 }
106
107
108 bool errorlog_end(ErrorLog *el)
109 {
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;
115 }
116
117
118 void errorlog_deinit(ErrorLog *el)
119 {
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;
126 }
127