Line data Source code
1 : /* src/toolbox/logging.cpp - contains logging functions
2 :
3 : Copyright (C) 1996-2013
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 : #include "config.h"
26 :
27 : #include <cstdio>
28 : #include <cstdlib>
29 : #include <cstring>
30 : #include <cassert>
31 : #include <inttypes.h>
32 :
33 : #include "vm/method.hpp"
34 : #include "vm/types.hpp"
35 :
36 : #include "threads/thread.hpp"
37 :
38 : #include "toolbox/logging.hpp"
39 : #include "toolbox/util.hpp"
40 :
41 : #include "vm/statistics.hpp"
42 :
43 : #ifdef ENABLE_LOGGING
44 :
45 : using namespace cacao;
46 :
47 : static Color current_log_color = BoldWhite;
48 :
49 : OStream& cacao::dbg() {
50 : static OStream stream(stdout);
51 :
52 : return stream;
53 : }
54 :
55 : void cacao::set_log_file(FILE *file) {
56 : dbg().set_file(file);
57 : }
58 :
59 : void cacao::set_log_color(Color color) {
60 : current_log_color = color;
61 : }
62 :
63 : Color cacao::log_color() {
64 : return current_log_color;
65 : }
66 :
67 : #endif
68 :
69 : /***************************************************************************
70 : LOG FILE HANDLING
71 : ***************************************************************************/
72 :
73 : static FILE *LOG_FILE = NULL;
74 :
75 0 : void log_init(const char *fname)
76 : {
77 0 : if (fname) {
78 0 : if (fname[0]) {
79 0 : LOG_FILE = fopen(fname, "w");
80 : }
81 : }
82 0 : }
83 :
84 0 : static inline FILE* get_log()
85 : {
86 0 : return LOG_FILE ? LOG_FILE : stdout;
87 : }
88 :
89 : // TODO: remove
90 0 : FILE* log_get_logfile()
91 : {
92 0 : return get_log();
93 : }
94 :
95 : /***************************************************************************
96 : LOG ENTRY HEADER/FOOTER
97 : ***************************************************************************/
98 :
99 : /* log_start *******************************************************************
100 :
101 : Writes the preleading LOG: text to the protocol file (if opened) or
102 : to stdout.
103 :
104 : *******************************************************************************/
105 :
106 0 : void log_start(void)
107 : {
108 0 : fprintf(get_log(), "LOG: [0x%"PRIxPTR"] ", threads_get_current_tid());
109 0 : }
110 :
111 : /* log_finish ******************************************************************
112 :
113 : Finishes a logtext line with trailing newline and a fflush.
114 :
115 : *******************************************************************************/
116 :
117 0 : void log_finish(void)
118 : {
119 0 : FILE* log = get_log();
120 :
121 0 : fputs("\n", log);
122 0 : fflush(log);
123 0 : }
124 :
125 : /***************************************************************************
126 : PRINT TO CURRENT LOG ENTRY
127 : ***************************************************************************/
128 :
129 : /* log_vprint ******************************************************************
130 :
131 : Writes logtext to the protocol file (if opened) or to stdout.
132 :
133 : *******************************************************************************/
134 :
135 0 : void log_vprint(const char *text, va_list ap)
136 : {
137 0 : FILE* log = get_log();
138 :
139 0 : os::vfprintf(log, text, ap);
140 0 : }
141 :
142 :
143 : /* log_print *******************************************************************
144 :
145 : Writes logtext to the protocol file (if opened) or to stdout.
146 :
147 : *******************************************************************************/
148 :
149 0 : void log_print(const char *text, ...)
150 : {
151 : va_list ap;
152 :
153 0 : va_start(ap, text);
154 0 : log_vprint(text, ap);
155 0 : va_end(ap);
156 0 : }
157 :
158 : /* log_classname ***************************************************************
159 :
160 : Writes utf string to the protocol replacing '/' by '.'
161 :
162 : *******************************************************************************/
163 :
164 0 : void log_classname(Utf8String u)
165 : {
166 0 : FILE* log = get_log();
167 :
168 0 : assert(u);
169 :
170 0 : Utf8String str = u;
171 0 : Utf8String::byte_iterator it = str.begin();
172 0 : Utf8String::byte_iterator end = str.end();
173 :
174 0 : for (; it != end; ++it) {
175 0 : char c = *it;
176 :
177 0 : fputc(c=='/' ? '.' : c, log);
178 : }
179 0 : }
180 :
181 :
182 : /***************************************************************************
183 : PRINT WHOLE LOG ENTRY
184 : ***************************************************************************/
185 :
186 : /* log_println *****************************************************************
187 :
188 : Writes logtext to the protocol file (if opened) or to stdout with a
189 : trailing newline.
190 :
191 : *******************************************************************************/
192 :
193 0 : void log_println(const char *text, ...)
194 : {
195 : va_list ap;
196 :
197 0 : log_start();
198 :
199 0 : va_start(ap, text);
200 0 : log_vprint(text, ap);
201 0 : va_end(ap);
202 :
203 0 : log_finish();
204 0 : }
205 :
206 : /* log_message_utf *************************************************************
207 :
208 : Outputs log text like this:
209 :
210 : LOG: Creating class: java/lang/Object
211 :
212 : *******************************************************************************/
213 :
214 0 : void log_message_utf(const char *msg, Utf8String u)
215 : {
216 0 : log_start();
217 :
218 0 : FILE* log = get_log();
219 :
220 0 : Utf8String str = u; // TODO: remove
221 :
222 0 : fputs(msg, log);
223 0 : fputs(str.begin(), log);
224 :
225 0 : log_finish();
226 0 : }
227 :
228 :
229 : /* log_message_class ***********************************************************
230 :
231 : Outputs log text like this:
232 :
233 : LOG: Loading class: java/lang/Object
234 :
235 : *******************************************************************************/
236 :
237 0 : void log_message_class(const char *msg, classinfo *c)
238 : {
239 0 : log_message_utf(msg, c->name);
240 0 : }
241 :
242 :
243 : /* log_message_class_message_class *********************************************
244 :
245 : Outputs log text like this:
246 :
247 : LOG: Initialize super class java/lang/Object from java/lang/VMThread
248 :
249 : *******************************************************************************/
250 :
251 0 : void log_message_class_message_class(const char *msg1, classinfo *c1,
252 : const char *msg2, classinfo *c2)
253 : {
254 0 : log_start();
255 :
256 0 : FILE* log = get_log();
257 :
258 0 : fputs(msg1, log);
259 0 : fputs(Utf8String(c1->name).begin(), log);
260 0 : fputs(msg2, log);
261 0 : fputs(Utf8String(c2->name).begin(), log);
262 :
263 0 : log_finish();
264 0 : }
265 :
266 :
267 : /* log_message_method **********************************************************
268 :
269 : Outputs log text like this:
270 :
271 : LOG: Compiling: java.lang.Object.clone()Ljava/lang/Object;
272 :
273 : *******************************************************************************/
274 :
275 0 : void log_message_method(const char *msg, methodinfo *m)
276 : {
277 0 : log_start();
278 :
279 0 : FILE* log = get_log();
280 :
281 0 : fputs(msg, log);
282 0 : log_classname( m->clazz->name );
283 0 : fputc('.', log);
284 0 : fputs(Utf8String(m->name).begin(), log);
285 0 : fputs(Utf8String(m->descriptor).begin(), log);
286 :
287 0 : log_finish();
288 0 : }
289 :
290 :
291 : /*
292 : * These are local overrides for various environment variables in Emacs.
293 : * Please do not remove this and leave it at the end of the file, where
294 : * Emacs will automagically detect them.
295 : * ---------------------------------------------------------------------
296 : * Local variables:
297 : * mode: c++
298 : * indent-tabs-mode: t
299 : * c-basic-offset: 4
300 : * tab-width: 4
301 : * End:
302 : * vim:noexpandtab:sw=4:ts=4:
303 : */
|