DNBLog.cpp revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
1//===-- 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
310