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