blob: d99e415f37eefb4142b4388e1ef7abe55488b3c4 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- DNBLog.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Created by Greg Clayton on 6/18/07.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DNBLog.h"
15
16static int g_debug = 0;
17static int g_verbose = 0;
18
19#if defined (DNBLOG_ENABLED)
20
21#include <stdio.h>
22#include <stdarg.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <mach/mach.h>
26#include <pthread.h>
27#include "PThreadMutex.h"
28
29uint32_t g_log_bits = 0;
30static DNBCallbackLog g_log_callback = NULL;
31static void *g_log_baton = NULL;
32
33
34int
35DNBLogGetDebug ()
36{
37 return g_debug;
38}
39
40
41void
42DNBLogSetDebug (int g)
43{
44 g_debug = g;
45}
46
47int
48DNBLogGetVerbose ()
49{
50 return g_verbose;
51}
52
53void
54DNBLogSetVerbose (int v)
55{
56 g_verbose = v;
57}
58
59bool
60DNBLogCheckLogBit (uint32_t bit)
61{
62 return (g_log_bits & bit) != 0;
63}
64
65uint32_t
66DNBLogSetLogMask (uint32_t mask)
67{
68 uint32_t old = g_log_bits;
69 g_log_bits = mask;
70 return old;
71}
72
73uint32_t
74DNBLogGetLogMask ()
75{
76 return g_log_bits;
77}
78
79void
80DNBLogSetLogCallback (DNBCallbackLog callback, void *baton)
81{
82 g_log_callback = callback;
83 g_log_baton = baton;
84}
85
86bool
87DNBLogEnabled ()
88{
89 return g_log_callback != NULL;
90}
91
92static inline void
93_DNBLogVAPrintf(uint32_t flags, const char *format, va_list args)
94{
95 if (g_log_callback)
96 g_log_callback(g_log_baton, flags, format, args);
97}
98
99void
100_DNBLog(uint32_t flags, const char *format, ...)
101{
102 va_list args;
103 va_start (args, format);
104 _DNBLogVAPrintf(flags, format, args);
105 va_end (args);
106}
107
108//----------------------------------------------------------------------
109// Print debug strings if and only if the global g_debug is set to
110// a non-zero value.
111//----------------------------------------------------------------------
112void
113_DNBLogDebug (const char *format, ...)
114{
115 if (DNBLogEnabled () && g_debug)
116 {
117 va_list args;
118 va_start (args, format);
119 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args);
120 va_end (args);
121 }
122}
123
124
125//----------------------------------------------------------------------
126// Print debug strings if and only if the global g_debug is set to
127// a non-zero value.
128//----------------------------------------------------------------------
129void
130_DNBLogDebugVerbose (const char *format, ...)
131{
132 if (DNBLogEnabled () && g_debug && g_verbose)
133 {
134 va_list args;
135 va_start (args, format);
136 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args);
137 va_end (args);
138 }
139}
140
141
142static pthread_mutex_t *
143GetLogThreadedMutex()
144{
145 static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
146 return g_LogThreadedMutex.Mutex();
147}
148static uint32_t g_message_id = 0;
149
150//----------------------------------------------------------------------
151// Prefix the formatted log string with process and thread IDs and
152// suffix it with a newline.
153//----------------------------------------------------------------------
154void
155_DNBLogThreaded (const char *format, ...)
156{
157 if (DNBLogEnabled ())
158 {
159 PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
160
161 char *arg_msg = NULL;
162 va_list args;
163 va_start (args, format);
164 ::vasprintf (&arg_msg, format, args);
165 va_end (args);
166
167 if (arg_msg != NULL)
168 {
169 _DNBLog (DNBLOG_FLAG_THREADED, "%u [%4.4x/%4.4x]: %s", ++g_message_id, getpid(), mach_thread_self(), arg_msg);
170 free (arg_msg);
171 }
172 }
173}
174
175//----------------------------------------------------------------------
176// Prefix the formatted log string with process and thread IDs and
177// suffix it with a newline.
178//----------------------------------------------------------------------
179void
180_DNBLogThreadedIf (uint32_t log_bit, const char *format, ...)
181{
182 if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit)
183 {
184 PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
185
186 char *arg_msg = NULL;
187 va_list args;
188 va_start (args, format);
189 ::vasprintf (&arg_msg, format, args);
190 va_end (args);
191
192 if (arg_msg != NULL)
193 {
194 _DNBLog (DNBLOG_FLAG_THREADED, "%u [%4.4x/%4.4x]: %s", ++g_message_id, getpid(), mach_thread_self(), arg_msg);
195 free (arg_msg);
196 }
197 }
198}
199
200
201
202//----------------------------------------------------------------------
203// Printing of errors that are not fatal.
204//----------------------------------------------------------------------
205void
206_DNBLogError (const char *format, ...)
207{
208 if (DNBLogEnabled ())
209 {
210 char *arg_msg = NULL;
211 va_list args;
212 va_start (args, format);
213 ::vasprintf (&arg_msg, format, args);
214 va_end (args);
215
216 if (arg_msg != NULL)
217 {
218 _DNBLog (DNBLOG_FLAG_ERROR, "error: %s", arg_msg);
219 free (arg_msg);
220 }
221 }
222}
223
224//----------------------------------------------------------------------
225// Printing of errors that ARE fatal. Exit with ERR exit code
226// immediately.
227//----------------------------------------------------------------------
228void
229_DNBLogFatalError (int err, const char *format, ...)
230{
231 if (DNBLogEnabled ())
232 {
233 char *arg_msg = NULL;
234 va_list args;
235 va_start (args, format);
236 ::vasprintf (&arg_msg, format, args);
237 va_end (args);
238
239 if (arg_msg != NULL)
240 {
241 _DNBLog (DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg);
242 free (arg_msg);
243 }
244 ::exit (err);
245 }
246}
247
248
249//----------------------------------------------------------------------
250// Printing of warnings that are not fatal only if verbose mode is
251// enabled.
252//----------------------------------------------------------------------
253void
254_DNBLogVerbose (const char *format, ...)
255{
256 if (DNBLogEnabled () && g_verbose)
257 {
258 va_list args;
259 va_start (args, format);
260 _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args);
261 va_end (args);
262 }
263}
264
265//----------------------------------------------------------------------
266// Printing of warnings that are not fatal only if verbose mode is
267// enabled.
268//----------------------------------------------------------------------
269void
270_DNBLogWarningVerbose (const char *format, ...)
271{
272 if (DNBLogEnabled () && g_verbose)
273 {
274 char *arg_msg = NULL;
275 va_list args;
276 va_start (args, format);
277 ::vasprintf (&arg_msg, format, args);
278 va_end (args);
279
280 if (arg_msg != NULL)
281 {
282 _DNBLog (DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s", arg_msg);
283 free (arg_msg);
284 }
285 }
286}
287//----------------------------------------------------------------------
288// Printing of warnings that are not fatal.
289//----------------------------------------------------------------------
290void
291_DNBLogWarning (const char *format, ...)
292{
293 if (DNBLogEnabled ())
294 {
295 char *arg_msg = NULL;
296 va_list args;
297 va_start (args, format);
298 ::vasprintf (&arg_msg, format, args);
299 va_end (args);
300
301 if (arg_msg != NULL)
302 {
303 _DNBLog (DNBLOG_FLAG_WARNING, "warning: %s", arg_msg);
304 free (arg_msg);
305 }
306 }
307}
308
309#endif