fprintf/vfprintf dependency fix
[cacao.git] / src / toolbox / logging.cpp
1 /* src/toolbox/logging.c - contains logging functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "vm/types.h"
33
34 #include "mm/memory.hpp"
35
36 #include "threads/thread.hpp"
37
38 #include "toolbox/logging.hpp"
39 #include "toolbox/util.h"
40
41 #include "vm/global.h"
42
43 #if defined(ENABLE_STATISTICS)
44 # include "vm/statistics.h"
45 #endif
46
47
48 /***************************************************************************
49                         LOG FILE HANDLING 
50 ***************************************************************************/
51
52 FILE *logfile = NULL;
53
54
55 void log_init(const char *fname)
56 {
57         if (fname) {
58                 if (fname[0]) {
59                         logfile = fopen(fname, "w");
60                 }
61         }
62 }
63
64
65 /* log_start *******************************************************************
66
67    Writes the preleading LOG: text to the protocol file (if opened) or
68    to stdout.
69
70 *******************************************************************************/
71
72 void log_start(void)
73 {
74 #if defined(ENABLE_THREADS)
75         ptrint tid;
76
77         tid = threads_get_current_tid();
78 #endif
79
80         if (logfile) {
81 #if defined(ENABLE_THREADS)
82 # if SIZEOF_VOID_P == 8
83                 fprintf(logfile, "[0x%016lx] ", tid );
84 # else
85                 fprintf(logfile, "[0x%08x] ", tid);
86 # endif
87 #endif
88         }
89         else {
90 #if defined(ENABLE_THREADS)
91 # if SIZEOF_VOID_P == 8
92                 fprintf(stdout, "LOG: [0x%016lx] ", tid);
93 # else
94                 fprintf(stdout, "LOG: [0x%08x] ", tid);
95 # endif
96 #else
97                 fputs("LOG: ", stdout);
98 #endif
99         }
100 }
101
102
103 /* log_vprint ******************************************************************
104
105    Writes logtext to the protocol file (if opened) or to stdout.
106
107 *******************************************************************************/
108
109 void log_vprint(const char *text, va_list ap)
110 {
111         if (logfile)
112                 os::vfprintf(logfile, text, ap);
113         else
114                 os::vfprintf(stdout, text, ap);
115 }
116
117
118 /* log_print *******************************************************************
119
120    Writes logtext to the protocol file (if opened) or to stdout.
121
122 *******************************************************************************/
123
124 void log_print(const char *text, ...)
125 {
126         va_list ap;
127
128         va_start(ap, text);
129         log_vprint(text, ap);
130         va_end(ap);
131 }
132
133
134 /* log_println *****************************************************************
135
136    Writes logtext to the protocol file (if opened) or to stdout with a
137    trailing newline.
138
139 *******************************************************************************/
140
141 void log_println(const char *text, ...)
142 {
143         va_list ap;
144
145         log_start();
146
147         va_start(ap, text);
148         log_vprint(text, ap);
149         va_end(ap);
150
151         log_finish();
152 }
153
154
155 /* log_finish ******************************************************************
156
157    Finishes a logtext line with trailing newline and a fflush.
158
159 *******************************************************************************/
160
161 void log_finish(void)
162 {
163         if (logfile) {
164                 fputs("\n", logfile);
165                 fflush(logfile);
166         }
167         else {
168                 fputs("\n", stdout);
169                 fflush(stdout);
170         }
171 }
172
173
174 /* log_message_utf *************************************************************
175
176    Outputs log text like this:
177
178    LOG: Creating class: java/lang/Object
179
180 *******************************************************************************/
181
182 void log_message_utf(const char *msg, utf *u)
183 {
184         char *buf;
185         s4    len;
186
187         len = strlen(msg) + utf_bytes(u) + strlen("0");
188
189         buf = MNEW(char, len);
190
191         strcpy(buf, msg);
192         utf_cat(buf, u);
193
194         log_text(buf);
195
196         MFREE(buf, char, len);
197 }
198
199
200 /* log_message_class ***********************************************************
201
202    Outputs log text like this:
203
204    LOG: Loading class: java/lang/Object
205
206 *******************************************************************************/
207
208 void log_message_class(const char *msg, classinfo *c)
209 {
210         log_message_utf(msg, c->name);
211 }
212
213
214 /* log_message_class_message_class *********************************************
215
216    Outputs log text like this:
217
218    LOG: Initialize super class java/lang/Object from java/lang/VMThread
219
220 *******************************************************************************/
221
222 void log_message_class_message_class(const char *msg1, classinfo *c1,
223                                                                          const char *msg2, classinfo *c2)
224 {
225         char *buf;
226         s4    len;
227
228         len =
229                 strlen(msg1) + utf_bytes(c1->name) +
230                 strlen(msg2) + utf_bytes(c2->name) + strlen("0");
231
232         buf = MNEW(char, len);
233
234         strcpy(buf, msg1);
235         utf_cat_classname(buf, c1->name);
236         strcat(buf, msg2);
237         utf_cat_classname(buf, c2->name);
238
239         log_text(buf);
240
241         MFREE(buf, char, len);
242 }
243
244
245 /* log_message_method **********************************************************
246
247    Outputs log text like this:
248
249    LOG: Compiling: java.lang.Object.clone()Ljava/lang/Object;
250
251 *******************************************************************************/
252
253 void log_message_method(const char *msg, methodinfo *m)
254 {
255         char *buf;
256         s4    len;
257
258         len = strlen(msg) + utf_bytes(m->clazz->name) + strlen(".") +
259                 utf_bytes(m->name) + utf_bytes(m->descriptor) + strlen("0");
260
261         buf = MNEW(char, len);
262
263         strcpy(buf, msg);
264         utf_cat_classname(buf, m->clazz->name);
265         strcat(buf, ".");
266         utf_cat(buf, m->name);
267         utf_cat(buf, m->descriptor);
268
269         log_text(buf);
270
271         MFREE(buf, char, len);
272 }
273
274
275 /*
276  * These are local overrides for various environment variables in Emacs.
277  * Please do not remove this and leave it at the end of the file, where
278  * Emacs will automagically detect them.
279  * ---------------------------------------------------------------------
280  * Local variables:
281  * mode: c++
282  * indent-tabs-mode: t
283  * c-basic-offset: 4
284  * tab-width: 4
285  * End:
286  * vim:noexpandtab:sw=4:ts=4:
287  */