CACAO
logging.cpp
Go to the documentation of this file.
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 
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 void log_init(const char *fname)
76 {
77  if (fname) {
78  if (fname[0]) {
79  LOG_FILE = fopen(fname, "w");
80  }
81  }
82 }
83 
84 static inline FILE* get_log()
85 {
86  return LOG_FILE ? LOG_FILE : stdout;
87 }
88 
89 // TODO: remove
91 {
92  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 void log_start(void)
107 {
108  fprintf(get_log(), "LOG: [0x%"PRIxPTR"] ", threads_get_current_tid());
109 }
110 
111 /* log_finish ******************************************************************
112 
113  Finishes a logtext line with trailing newline and a fflush.
114 
115 *******************************************************************************/
116 
117 void log_finish(void)
118 {
119  FILE* log = get_log();
120 
121  fputs("\n", log);
122  fflush(log);
123 }
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 void log_vprint(const char *text, va_list ap)
136 {
137  FILE* log = get_log();
138 
139  os::vfprintf(log, text, ap);
140 }
141 
142 
143 /* log_print *******************************************************************
144 
145  Writes logtext to the protocol file (if opened) or to stdout.
146 
147 *******************************************************************************/
148 
149 void log_print(const char *text, ...)
150 {
151  va_list ap;
152 
153  va_start(ap, text);
154  log_vprint(text, ap);
155  va_end(ap);
156 }
157 
158 /* log_classname ***************************************************************
159 
160  Writes utf string to the protocol replacing '/' by '.'
161 
162 *******************************************************************************/
163 
165 {
166  FILE* log = get_log();
167 
168  assert(u);
169 
170  Utf8String str = u;
171  Utf8String::byte_iterator it = str.begin();
172  Utf8String::byte_iterator end = str.end();
173 
174  for (; it != end; ++it) {
175  char c = *it;
176 
177  fputc(c=='/' ? '.' : c, log);
178  }
179 }
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 void log_println(const char *text, ...)
194 {
195  va_list ap;
196 
197  log_start();
198 
199  va_start(ap, text);
200  log_vprint(text, ap);
201  va_end(ap);
202 
203  log_finish();
204 }
205 
206 /* log_message_utf *************************************************************
207 
208  Outputs log text like this:
209 
210  LOG: Creating class: java/lang/Object
211 
212 *******************************************************************************/
213 
214 void log_message_utf(const char *msg, Utf8String u)
215 {
216  log_start();
217 
218  FILE* log = get_log();
219 
220  Utf8String str = u; // TODO: remove
221 
222  fputs(msg, log);
223  fputs(str.begin(), log);
224 
225  log_finish();
226 }
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 void log_message_class(const char *msg, classinfo *c)
238 {
239  log_message_utf(msg, c->name);
240 }
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 void log_message_class_message_class(const char *msg1, classinfo *c1,
252  const char *msg2, classinfo *c2)
253 {
254  log_start();
255 
256  FILE* log = get_log();
257 
258  fputs(msg1, log);
259  fputs(Utf8String(c1->name).begin(), log);
260  fputs(msg2, log);
261  fputs(Utf8String(c2->name).begin(), log);
262 
263  log_finish();
264 }
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 void log_message_method(const char *msg, methodinfo *m)
276 {
277  log_start();
278 
279  FILE* log = get_log();
280 
281  fputs(msg, log);
282  log_classname( m->clazz->name );
283  fputc('.', log);
284  fputs(Utf8String(m->name).begin(), log);
285  fputs(Utf8String(m->descriptor).begin(), log);
286 
287  log_finish();
288 }
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  */
Utf8String name
Definition: method.hpp:71
void log_message_method(const char *msg, methodinfo *m)
Definition: logging.cpp:275
void log_message_class_message_class(const char *msg1, classinfo *c1, const char *msg2, classinfo *c2)
Definition: logging.cpp:251
byte_iterator end() const
Definition: utf8.hpp:107
FILE * log_get_logfile()
Definition: logging.cpp:90
void log_finish(void)
Definition: logging.cpp:117
void log_println(const char *text,...)
Definition: logging.cpp:193
const char * byte_iterator
Definition: utf8.hpp:104
void log_print(const char *text,...)
Definition: logging.cpp:149
Utf8String descriptor
Definition: method.hpp:72
void log_classname(Utf8String u)
Definition: logging.cpp:164
intptr_t threads_get_current_tid(void)
Definition: thread.cpp:722
classinfo * clazz
Definition: method.hpp:80
This file contains the statistics framework.
Utf8String name
Definition: class.hpp:91
Simple stream class for formatted output.
Definition: OStream.hpp:141
void log_vprint(const char *text, va_list ap)
Definition: logging.cpp:135
void log_start(void)
Definition: logging.cpp:106
void log_init(const char *fname)
Definition: logging.cpp:75
byte_iterator begin() const
Definition: utf8.hpp:106
static FILE * LOG_FILE
Definition: logging.cpp:73
void set_file(FILE *file)
Definition: OStream.hpp:209
static int vfprintf(FILE *stream, const char *format, va_list arg)
Definition: os.hpp:351
static FILE * get_log()
Definition: logging.cpp:84
#define str(x)
void log_message_utf(const char *msg, Utf8String u)
Definition: logging.cpp:214
OStream & dbg()
The default destination for logging messages.
void log_message_class(const char *msg, classinfo *c)
Definition: logging.cpp:237