Don't use fixed buffer length for log_message_class and log_message_method
[cacao.git] / src / toolbox / logging.c
1 /* src/toolbox/logging.c - contains logging functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Christian Thalinger
30
31    $Id: logging.c 2133 2005-03-30 09:49:41Z twisti $
32
33 */
34
35
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "config.h"
42 #include "mm/memory.h"
43 #include "toolbox/logging.h"
44 #include "vm/global.h"
45 #include "vm/tables.h"
46 #include "vm/statistics.h"
47
48
49 /***************************************************************************
50                         LOG FILE HANDLING 
51 ***************************************************************************/
52
53 FILE *logfile = NULL;
54
55
56 void log_init(const char *fname)
57 {
58         if (fname) {
59                 if (fname[0]) {
60                         logfile = fopen(fname, "w");
61                 }
62         }
63 }
64
65
66 /*********************** Function: dolog ************************************
67
68 Writes logtext to the protocol file (if opened) or to stdout.
69
70 **************************************************************************/
71
72 void dolog(const char *txt, ...)
73 {
74         char logtext[MAXLOGTEXT];
75         va_list ap;
76
77         va_start(ap, txt);
78         vsprintf(logtext, txt, ap);
79         va_end(ap);
80
81         if (logfile) {
82                 fprintf(logfile, "%s\n",logtext);
83                 fflush(logfile);
84
85         } else {
86                 fprintf(stdout,"LOG: %s\n",logtext);
87                 fflush(stdout);
88         }
89 }
90
91
92 /******************** Function: dolog_plain *******************************
93
94 Writes logtext to the protocol file (if opened) or to stdout.
95
96 **************************************************************************/
97
98 void dolog_plain(const char *txt, ...)
99 {
100         char logtext[MAXLOGTEXT];
101         va_list ap;
102
103         va_start(ap, txt);
104         vsprintf(logtext, txt, ap);
105         va_end(ap);
106
107         if (logfile) {
108                 fprintf(logfile, "%s", logtext);
109                 fflush(logfile);
110
111         } else {
112                 fprintf(stdout,"%s", logtext);
113                 fflush(stdout);
114         }
115 }
116
117
118 /********************* Function: log_text ********************************/
119
120 void log_text(const char *text)
121 {
122         dolog("%s", text);
123 }
124
125
126 /******************** Function: log_plain *******************************/
127
128 void log_plain(const char *text)
129 {
130         dolog_plain("%s", text);
131 }
132
133
134 /****************** Function: get_logfile *******************************/
135
136 FILE *get_logfile(void)
137 {
138         return (logfile) ? logfile : stdout;
139 }
140
141
142 /****************** Function: log_flush *********************************/
143
144 void log_flush(void)
145 {
146         fflush(get_logfile());
147 }
148
149
150 /********************* Function: log_nl *********************************/
151
152 void log_nl(void)
153 {
154         log_plain("\n");
155         fflush(get_logfile());
156 }
157
158
159 /* log_cputime *****************************************************************
160
161    XXX
162
163 *******************************************************************************/
164
165 #if defined(STATISTICS)
166 void log_cputime(void)
167 {
168         s8 t;
169         int sec, usec;
170         char logtext[MAXLOGTEXT];
171
172         t = getcputime();
173         sec = t / 1000000;
174         usec = t % 1000000;
175
176         sprintf(logtext, "Total CPU usage: %d seconds and %d milliseconds",
177                         sec, usec / 1000);
178         log_text(logtext);
179 }
180 #endif
181
182
183 /* log_message_method **********************************************************
184
185    outputs log text like this:
186
187    LOG: Loading class: java/lang/Object
188
189 *******************************************************************************/
190
191 void log_message_class(const char *msg, classinfo *c)
192 {
193         char *buf;
194         s4    len;
195
196         len = strlen(msg) + utf_strlen(c->name) + strlen("0");
197
198         buf = MNEW(char, len);
199
200         strcpy(buf, msg);
201         utf_strcat(buf, c->name);
202
203         log_text(buf);
204
205         MFREE(buf, char, len);
206 }
207
208
209 /* log_message_method **********************************************************
210
211    outputs log text like this:
212
213    LOG: Compiling: java.lang.Object.clone()Ljava/lang/Object;
214
215 *******************************************************************************/
216
217 void log_message_method(const char *msg, methodinfo *m)
218 {
219         char *buf;
220         s4    len;
221
222         len = strlen(msg) + utf_strlen(m->class->name) + strlen(".") +
223                 utf_strlen(m->name) + utf_strlen(m->descriptor) + strlen("0");
224
225         buf = MNEW(char, len);
226
227         strcpy(buf, msg);
228         utf_strcat_classname(buf, m->class->name);
229         strcat(buf, ".");
230         utf_strcat(buf, m->name);
231         utf_strcat(buf, m->descriptor);
232
233         log_text(buf);
234
235         MFREE(buf, char, len);
236 }
237
238
239 /* error ***********************************************************************
240
241    Like dolog(), but terminates the program immediately.
242
243 *******************************************************************************/
244
245 void error(const char *txt, ...)
246 {
247         char logtext[MAXLOGTEXT];
248         va_list ap;
249
250         va_start(ap, txt);
251         vsprintf(logtext, txt, ap);
252         va_end(ap);
253
254         if (logfile) {
255                 fprintf(logfile, "ERROR: %s\n", logtext);
256         }
257
258         fprintf(stderr, "ERROR: %s\n", logtext);
259
260         exit(1);
261 }
262
263
264 /* panic ***********************************************************************
265
266    Like error(), takes the text to output as an argument.
267
268 *******************************************************************************/
269
270 void panic(const char *txt)
271 {
272         error("%s", txt);
273 }
274
275
276 /* log_utf *********************************************************************
277
278    Log utf symbol.
279
280 *******************************************************************************/
281
282 void log_utf(utf *u)
283 {
284         char buf[MAXLOGTEXT];
285         utf_sprint(buf, u);
286         dolog("%s", buf);
287 }
288
289
290 /* log_plain_utf ***************************************************************
291
292    Log utf symbol (without printing "LOG: " and newline).
293
294 *******************************************************************************/
295
296 void log_plain_utf(utf *u)
297 {
298         char buf[MAXLOGTEXT];
299         utf_sprint(buf, u);
300         dolog_plain("%s", buf);
301 }
302
303
304 /*
305  * These are local overrides for various environment variables in Emacs.
306  * Please do not remove this and leave it at the end of the file, where
307  * Emacs will automagically detect them.
308  * ---------------------------------------------------------------------
309  * Local variables:
310  * mode: c
311  * indent-tabs-mode: t
312  * c-basic-offset: 4
313  * tab-width: 4
314  * End:
315  */